{"record":{"id":"e60ce71ec9e937b1","repo":"passbolt/passbolt_api","slug":"the-openpgp-server-key-defined-in-the-config-cannot-be-used-e60ce7","errorCode":null,"errorMessage":"The OpenPGP server key defined in the config cannot be used to verify signature. ","messagePattern":"The OpenPGP server key defined in the config cannot be used to verify signature\\. ","errorType":"http","errorClass":"InternalErrorException","httpStatus":500,"severity":"critical","filePath":"src/Service/OpenPGP/OpenPGPCommonServerOperationsTrait.php","lineNumber":115,"sourceCode":"        // Check if config contains fingerprint\n        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');\n        $this->assertServerFingerprint($fingerprint);\n\n        // Check if config contains valid passphrase\n        $passphrase = Configure::read('passbolt.gpg.serverKey.passphrase');\n        $this->assertServerPassphrase($passphrase);\n\n        // Set verify key as the one from the server\n        try {\n            $gpg->setVerifyKeyFromFingerprint($fingerprint);\n        } catch (Exception $exception) {\n            try {\n                $gpg->importServerKeyInKeyring();\n                $gpg->setVerifyKeyFromFingerprint($fingerprint);\n            } catch (Exception $exception) {\n                $msg = __('The OpenPGP server key defined in the config cannot be used to verify signature.') . ' ';\n                $msg .= $exception->getMessage();\n                throw new InternalErrorException($msg, 500, $exception);\n            }\n        }\n\n        return $gpg;\n    }\n\n    /**\n     * @param \\App\\Utility\\OpenPGP\\OpenPGPBackend $gpg for example OpenPGPBackendFactory::get()\n     * @return \\App\\Utility\\OpenPGP\\OpenPGPBackend backend configured to use server key to sign\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException if the server key cannot be loaded\n     */\n    public function setSignKeyWithServerKey(OpenPGPBackend $gpg): OpenPGPBackend\n    {\n        // Check if config contains fingerprint\n        $fingerprint = Configure::read('passbolt.gpg.serverKey.fingerprint');\n        $this->assertServerFingerprint($fingerprint);\n\n        // Check if config contains valid passphrase","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/src/Service/OpenPGP/OpenPGPCommonServerOperationsTrait.php#L97-L133","documentation":"Thrown by setVerifyKeyWithServerKey when the GnuPG backend cannot set the configured server key as signature-verification key, even after importing it into the keyring. The wrapped gnupg message is appended. Typically means the key used to verify server-signed tokens/responses cannot be resolved from the keyring by the configured fingerprint.","triggerScenarios":"Calling setVerifyKeyWithServerKey when the keyring has no key for passbolt.gpg.serverKey.fingerprint and importServerKeyInKeyring fails (missing/unreadable key file, invalid ASCII armor), or the gnupg context cannot be initialized with that fingerprint (malformed fingerprint string in config).","commonSituations":"serverkey.asc path misconfigured or file deleted during a cleanup; fingerprint copy/pasted with extra whitespace or wrong length; Docker image rebuilt without re-importing the key; keyring owned by a different system user than the one PHP runs as.","solutions":["Compare `passbolt.gpg.serverKey.fingerprint` against `gpg --show-keys <serverKey.path>` — fix any mismatch or whitespace.","Ensure passbolt.gpg.serverKey.path points to an existing, readable public key file and that `public` config is true if serving it.","Import manually as the web server user: `sudo -H -u www-data gpg --home <gnupghome> --import /etc/passbolt/serverkey.asc`, then retry the request.","Fix GNUPGHOME permissions (owned by web user, mode 700) so the import into the keyring can succeed.","Check the appended exception message for the precise gnupg error (e.g. 'import failed – invalid key')."],"exampleFix":"// before\n'serverKey' => ['fingerprint' => trim(file_get_contents('/etc/passbolt/fingerprint'))], // trailing newline\n// after\n'serverKey' => ['fingerprint' => strtoupper(preg_replace('/\\s+/', '', $rawFingerprint))],","handlingStrategy":"validation","validationCode":"$fp = preg_replace('/\\s+/', '', (string)Configure::read('passbolt.gpg.serverKey.fingerprint'));\nif (!PublicKeyValidationService::isValidFingerprint($fp)) {\n    throw new Exception('passbolt.gpg.serverKey.fingerprint missing or malformed');\n}\n$path = Configure::read('passbolt.gpg.serverKey.path');\nif (!is_readable($path)) {\n    throw new Exception(\"Server key file not readable: {$path}\");\n}\nexec('gpg --show-keys ' . escapeshellarg($path) . ' 2>/dev/null', $out, $code);\nif ($code !== 0 || strpos(implode('\\n', $out), strtoupper($fp)) === false) {\n    throw new Exception('Fingerprint does not match the key file');\n}","typeGuard":"function isValidFingerprintString(mixed $fp): bool\n{\n    return is_string($fp) && (bool)preg_match('/^[A-F0-9]{40}$/', strtoupper(preg_replace('/\\s+/', '', $fp)));\n}","tryCatchPattern":"try {\n    $gpg = $this->setVerifyKeyWithServerKey($gpg);\n} catch (InternalErrorException $e) {\n    Log::error('Verify key setup failed: ' . $e->getMessage());\n    throw new InternalErrorException('Server signature verification unavailable; check key config.');\n}","preventionTips":["Normalize fingerprints (strip whitespace, uppercase) when injecting them from env/config.","Verify the key file exists and fingerprint matches at deploy time with gpg --show-keys.","Set passbolt.gpg.serverKey.public correctly if the key is served to clients.","Mount the keyring persistently in containerized deployments.","Run the OpenPGP healthcheck after every image rebuild."],"tags":["openpgp","gnupg","server-key","signature","verification"],"backgroundTag":"invalid-config-value","analyzedSha":"31c1bbc10f32808a607fa9bd81891e898779c0bc","analyzedAt":"2026-09-17T00:04:38.960Z","contentChangedAt":"2026-09-17T00:04:38.960Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}