passbolt/passbolt_api · error · BadRequestException
The SSO authentication token is invalid. Settings id is…
Error message
The SSO authentication token is invalid. Settings id is missing.
What it means
A BadRequestException from assert() when the token's data payload lacks the required 'sso_setting_id' data property. SSO tokens carry metadata (settings id, IP, user agent) in their data JSON; getDataProperty() throws AuthenticationTokenDataPropertyException if the key is absent.
Solutions
- Ensure the token is created via the SSO token creation service which populates the sso_setting_id data property
- Delete/expire stale tokens from before the SSO settings migration and restart the flow
- Confirm the row's data JSON actually contains the settings id (inspect sso_authentication_tokens.data)
- Verify you are handling an SsoAuthenticationToken entity, not a base AuthenticationToken
Example fix
// before
$token->getDataProperty(SsoAuthenticationToken::DATA_SSO_SETTING_ID); // throws if missing
// after
if (!$token->hasDataProperty(SsoAuthenticationToken::DATA_SSO_SETTING_ID)) {
throw new BadRequestException(__('The SSO authentication token is invalid. Settings id is missing.'));
}
$sid = $token->getDataProperty(SsoAuthenticationToken::DATA_SSO_SETTING_ID); Defensive patterns
Strategy: validation
Validate before calling
$hasSettings = $token->hasDataProperty(\Passbolt\Sso\Model\Entity\SsoAuthenticationToken::DATA_SSO_SETTING_ID);
Type guard
function hasSsoSettingsId(SsoAuthenticationToken $t): bool {
return $t->hasDataProperty(SsoAuthenticationToken::DATA_SSO_SETTING_ID);
} Try / catch
try {
$service->assertAndConsume($token, $uac, $settingsId);
} catch (\Cake\Http\Exception\BadRequestException $e) {
if (str_contains($e->getMessage(), 'Settings id is missing')) {
// recreate token via the SSO token creation service
}
} Prevention
- Only create SSO tokens via the dedicated creation service that populates data properties
- Purge pre-migration tokens lacking data payloads
- Inspect the data JSON column when debugging
When it happens
Trigger: assert()/assertAndConsume() is called on a token whose data property DATA_SSO_SETTING_ID is missing — e.g. the token was created without SSO settings data, the data JSON was truncated, or a plain authentication token is mistakenly processed by the SSO assert path.
Common situations: Migrating data from pre-SSO-settings token format; manually seeded test tokens without a data payload; version skew where old tokens (created before a migration added the property) are still in circulation; passing a generic AuthenticationToken instead of an SsoAuthenticationToken.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- The SSO authentication token is invalid. Token IP is…
- The SSO authentication token is invalid. User agent is…
- The SSO authentication token is invalid. User id mismatch.
- The token is required in URL parameters.
- Access to this service requires an invitation. Please…
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/0c0e908251d32471.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Service/SsoAuthenticationTokens/SsoAuthenticationTokenGetService.php:180
* @param \App\Utility\ExtendedUserAccessControl $uac user access control
* @param string $settingsId uuid
* @throws \Cake\Http\Exception\BadRequestException if the authentication is expired
* @throws \Cake\Http\Exception\BadRequestException if the user agent or IP are missing or not matching
* @throws \Cake\Http\Exception\BadRequestException if the SSO settings is not valid or not matching
* @return void
*/
public function assert(SsoAuthenticationToken $token, ExtendedUserAccessControl $uac, string $settingsId): void
{
$errorMsg = __('The SSO authentication token is invalid.') . ' ';
if ($token->isExpired()) {
throw new BadRequestException($errorMsg . __('The authentication token is expired.'));
}
try {
$sid = $token->getDataProperty(SsoAuthenticationToken::DATA_SSO_SETTING_ID);
} catch (AuthenticationTokenDataPropertyException $exception) {
throw new BadRequestException($errorMsg . __('Settings id is missing.'), 400, $exception);
}
if ($token->user_id !== $uac->getId() || !Validation::uuid($token->user_id)) {
throw new BadRequestException($errorMsg . __('User id mismatch.'));
}
if (Configure::read('passbolt.security.userIp')) {
try {
$ip = $token->getDataProperty(SsoAuthenticationToken::DATA_IP);
} catch (AuthenticationTokenDataPropertyException $exception) {
throw new BadRequestException($errorMsg . __('Token IP is missing.'), 400, $exception);
}
if ($ip !== $uac->getUserIp()) {
throw new BadRequestException($errorMsg . __('User IP mismatch.'));
}
}
View on GitHub (pinned to 31c1bbc10f)