passbolt/passbolt_api · critical · Cake\Http\Exception\InternalErrorException

The SCIM secret token expiry configuration is invalid.

Error message

The SCIM secret token expiry configuration is invalid.

What it means

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.

Solutions

  1. 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').
  2. Compare with the plugin's default config file (plugins/PassboltEe/Scim/config/config.php) and copy any missing scim keys.
  3. Clear the config cache (rm tmp/cache/* or `cake cache clear_all`) after editing config files.

Example fix

// before (config/passbolt.php)
'scim' => ['enabled' => true],
// after
'scim' => [
  'enabled' => true,
  'security' => ['secretToken' => ['expiry' => '1 year']],
],
Defensive patterns

Strategy: validation

Try / catch

try {
  $date = $service->computeExpiry();
} catch (InternalErrorException $e) {
  Log::alert('Missing passbolt.plugins.scim.security.secretToken.expiry; check config/passbolt.php');
  throw $e; // server config issue, do not swallow
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17). Data as JSON: /api/errors/c39805799e30a139. Report an issue: GitHub.

Appendix: source

Thrown at plugins/PassboltEe/Scim/src/Service/ScimSetSettingsService.php:189

        if ($storedHash === null) {
            return true;
        }

        return !ScimTokenVerifier::verify($rawToken, $storedHash);
    }

    /**
     * Compute the expiration date for the SCIM secret token based on the configured expiry duration.
     *
     * @return string Date in Y-m-d format.
     * @throws \Cake\Http\Exception\InternalErrorException If the expiry configuration is invalid.
     */
    private function computeExpiredDate(): string
    {
        /** @var string|null $expiry */
        $expiry = Configure::read('passbolt.plugins.scim.security.secretToken.expiry');
        if ($expiry === null) {
            throw new InternalErrorException(__('The SCIM secret token expiry configuration is invalid.'));
        }

        return Date::now()->modify('+' . $expiry)->format('Y-m-d');
    }

    /**
     * Generate crypto-secure token for authentication
     *
     * @return string
     * @throws \Exception
     */
    public static function generateToken(): string
    {
        // Generate 256-bit entropy token
        $bin = random_bytes(32);
        // Base64 gives exact 43 characters (cutting "==" from last)
        $token = rtrim(strtr(base64_encode($bin), '+/', '-_'), '=');

View on GitHub (pinned to 31c1bbc10f)