{"record":{"id":"c39805799e30a139","repo":"passbolt/passbolt_api","slug":"the-scim-secret-token-expiry-configuration-is-invalid","errorCode":null,"errorMessage":"The SCIM secret token expiry configuration is invalid.","messagePattern":"The SCIM secret token expiry configuration is invalid\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\InternalErrorException","httpStatus":500,"severity":"critical","filePath":"plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php","lineNumber":189,"sourceCode":"        if ($storedHash === null) {\n            return true;\n        }\n\n        return !ScimTokenVerifier::verify($rawToken, $storedHash);\n    }\n\n    /**\n     * Compute the expiration date for the SCIM secret token based on the configured expiry duration.\n     *\n     * @return string Date in Y-m-d format.\n     * @throws \\Cake\\Http\\Exception\\InternalErrorException If the expiry configuration is invalid.\n     */\n    private function computeExpiredDate(): string\n    {\n        /** @var string|null $expiry */\n        $expiry = Configure::read('passbolt.plugins.scim.security.secretToken.expiry');\n        if ($expiry === null) {\n            throw new InternalErrorException(__('The SCIM secret token expiry configuration is invalid.'));\n        }\n\n        return Date::now()->modify('+' . $expiry)->format('Y-m-d');\n    }\n\n    /**\n     * Generate crypto-secure token for authentication\n     *\n     * @return string\n     * @throws \\Exception\n     */\n    public static function generateToken(): string\n    {\n        // Generate 256-bit entropy token\n        $bin = random_bytes(32);\n        // Base64 gives exact 43 characters (cutting \"==\" from last)\n        $token = rtrim(strtr(base64_encode($bin), '+/', '-_'), '=');\n","sourceCodeStart":171,"sourceCodeEnd":207,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php#L171-L207","documentation":"computeExpiredDate() reads the token expiry duration from Configure at 'passbolt.plugins.scim.security.secretToken.expiry' and throws InternalErrorException if the key is not set, since it cannot compute when a newly generated SCIM secret token expires. This is a server misconfiguration (or missing default config), surfaced as a 500 during settings save.","triggerScenarios":"Creating SCIM settings (POST) or rotating the secret token (PUT with a new token) on a server where passbolt.plugins.scim.security.secretToken.expiry is absent from config/passbolt.php or the loaded configure files.","commonSituations":"Hand-written passbolt.php missing the newer scim security block; config file not re-deployed after a passbolt upgrade that introduced the expiry setting; typo in the config key path.","solutions":["Add the expiry to config/passbolt.php: 'passbolt' => ['plugins' => ['scim' => ['security' => ['secretToken' => ['expiry' => '1 year']]]]] (value must be a string parseable by Date::modify, e.g. '6 months', '90 days').","Compare with the plugin's default config file (plugins/PassboltEe/Scim/config/config.php) and copy any missing scim keys.","Clear the config cache (rm tmp/cache/* or `cake cache clear_all`) after editing config files."],"exampleFix":"// before (config/passbolt.php)\n'scim' => ['enabled' => true],\n// after\n'scim' => [\n  'enabled' => true,\n  'security' => ['secretToken' => ['expiry' => '1 year']],\n],","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  $date = $service->computeExpiry();\n} catch (InternalErrorException $e) {\n  Log::alert('Missing passbolt.plugins.scim.security.secretToken.expiry; check config/passbolt.php');\n  throw $e; // server config issue, do not swallow\n}","preventionTips":["Include the full scim config block (security.secretToken.expiry) in config/passbolt.php on every environment.","Re-diff config/passbolt.php against the plugin's default config after each passbolt upgrade.","Smoke-test saving SCIM settings in staging after config changes.","Clear config caches after editing configure files."],"tags":["scim","php","cakephp","configuration","internal-error"],"backgroundTag":"missing-config-key","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"}