{"record":{"id":"830bf64c54b95324","repo":"passbolt/passbolt_api","slug":"the-aud-client-id-parameter-is-invalid","errorCode":null,"errorMessage":"The aud (client id) parameter is invalid.","messagePattern":"The aud \\(client id\\) parameter is invalid\\.","errorType":"validation","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Utility/OpenId/BaseIdToken.php","lineNumber":178,"sourceCode":"     * @throws \\Cake\\Http\\Exception\\BadRequestException if the claim does not validate\n     */\n    public function assertAudClaim(array $tokenClaims): void\n    {\n        if (isset($tokenClaims['aud'])) {\n            if (is_string($tokenClaims['aud'])) {\n                $auds[] = $tokenClaims['aud'];\n            } else {\n                $auds = $tokenClaims['aud'];\n            }\n\n            if (is_array($auds)) {\n                if (in_array($this->provider->getClientId(), $auds, true)) {\n                    return;\n                }\n            }\n        }\n\n        throw new BadRequestException('The aud (client id) parameter is invalid.');\n    }\n\n    /**\n     * @return string id_token\n     */\n    public function getIdToken(): string\n    {\n        return $this->idToken;\n    }\n\n    /**\n     * @return array claims from JWT::decode(id_token)\n     */\n    public function getIdTokenClaims(): array\n    {\n        return $this->idTokenClaims;\n    }\n","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Utility/OpenId/BaseIdToken.php#L160-L196","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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)."],"exampleFix":"// before\n'sso' => ['google' => ['clientId' => 'old-app-id.apps.googleusercontent.com']] // token aud is new-app-id\n// after\n'sso' => ['google' => ['clientId' => 'new-app-id.apps.googleusercontent.com']] // matches token aud","handlingStrategy":"validation","validationCode":"$auds = (array)($claims['aud'] ?? []);\nif (!in_array($expectedClientId, $auds, true)) {\n    throw new RuntimeException('id_token aud does not include configured client id');\n}","typeGuard":"function audienceIncludes(array $claims, string $clientId): bool {\n    $aud = $claims['aud'] ?? null;\n    $auds = is_array($aud) ? $aud : (is_string($aud) ? [$aud] : []);\n    return in_array($clientId, $auds, true);\n}","tryCatchPattern":"try {\n    $token->assertTokenClaims($claims);\n} catch (BadRequestException $e) {\n    if (str_contains($e->getMessage(), 'aud (client id)')) { /* compare token aud vs configured clientId */ }\n}","preventionTips":["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"],"tags":["jwt","claims","audience","openid","sso"],"backgroundTag":"schema-validation-failed","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"}