passbolt/passbolt_api · error · BadRequestException
The aud (client id) parameter is invalid.
Error message
The aud (client id) parameter is invalid.
What it means
assertAudClaim verifies the `aud` claim contains this provider's configured client id (using strict in_array). If aud is missing, not a string/array, or does not include the expected client id, it throws BadRequestException('The aud (client id) parameter is invalid.'). This prevents tokens minted for another application from being accepted.
Solutions
- Decode the token (jwt.io or debugEnabled) and compare its `aud` value with the client id configured in passbolt's SSO provider settings.
- Update passbolt's SSO client ID setting to match the application the token was actually issued for.
- Ensure the client code exchanges the code and passes the id_token from the same client id that initiated login.
- Verify you are not confusing environments (staging client id used against production provider or vice versa).
Example fix
// before 'sso' => ['google' => ['clientId' => 'old-app-id.apps.googleusercontent.com']] // token aud is new-app-id // after 'sso' => ['google' => ['clientId' => 'new-app-id.apps.googleusercontent.com']] // matches token aud
Defensive patterns
Strategy: validation
Validate before calling
$auds = (array)($claims['aud'] ?? []);
if (!in_array($expectedClientId, $auds, true)) {
throw new RuntimeException('id_token aud does not include configured client id');
} Type guard
function audienceIncludes(array $claims, string $clientId): bool {
$aud = $claims['aud'] ?? null;
$auds = is_array($aud) ? $aud : (is_string($aud) ? [$aud] : []);
return in_array($clientId, $auds, true);
} Try / catch
try {
$token->assertTokenClaims($claims);
} catch (BadRequestException $e) {
if (str_contains($e->getMessage(), 'aud (client id)')) { /* compare token aud vs configured clientId */ }
} Prevention
- Update passbolt's SSO client id immediately when rotating OAuth credentials in the provider console
- Separate staging/production client ids and verify env at startup
- Always validate the id_token's aud, never an access token, in the SSO flow
When it happens
Trigger: assertTokenClaims runs assertAudClaim and the id_token's `aud` claim (string or array) does not contain $this->provider->getClientId() — typically the token was issued for a different client/application.
Common situations: Rotating or creating new OAuth client credentials without updating passbolt's SSO settings; mixing staging and production client ids across environments; passing an access token (whose aud differs) where an id_token is expected; multi-audience tokens with strict comparison edge cases.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- No claims
- The email claim is not found or invalid.
- The iss (issuer) parameter does not match.
- The iss (issuer) parameter is invalid.
- JWT token is missing.
AI-assisted analysis of passbolt/passbolt_api@31c1bbc10f (2026-09-17).
Data as JSON: /api/errors/830bf64c54b95324.
Report an issue: GitHub.
Appendix: source
Thrown at plugins/PassboltEe/Sso/src/Utility/OpenId/BaseIdToken.php:178
* @throws \Cake\Http\Exception\BadRequestException if the claim does not validate
*/
public function assertAudClaim(array $tokenClaims): void
{
if (isset($tokenClaims['aud'])) {
if (is_string($tokenClaims['aud'])) {
$auds[] = $tokenClaims['aud'];
} else {
$auds = $tokenClaims['aud'];
}
if (is_array($auds)) {
if (in_array($this->provider->getClientId(), $auds, true)) {
return;
}
}
}
throw new BadRequestException('The aud (client id) parameter is invalid.');
}
/**
* @return string id_token
*/
public function getIdToken(): string
{
return $this->idToken;
}
/**
* @return array claims from JWT::decode(id_token)
*/
public function getIdTokenClaims(): array
{
return $this->idTokenClaims;
}
View on GitHub (pinned to 31c1bbc10f)