{"record":{"id":"2aeeba863a044a0a","repo":"passbolt/passbolt_api","slug":"the-authentication-token-does-not-exist-ssokeysgetservice","errorCode":null,"errorMessage":"The authentication token does not exist.","messagePattern":"The authentication token does not exist\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Service/SsoKeys/SsoKeysGetService.php","lineNumber":50,"sourceCode":"     *\n     * @param \\App\\Utility\\ExtendedUserAccessControl $uac extended user access control\n     * @param string $token SsoAuthenticationToken.token\n     * @param string $keyId uuid\n     * @return \\Passbolt\\Sso\\Model\\Entity\\SsoKey\n     */\n    public function get(ExtendedUserAccessControl $uac, string $token, string $keyId): SsoKey\n    {\n        try {\n            $ssoSettingEntity = (new SsoSettingsGetService())->getActiveOrFail();\n            // Token must be provided and matching the settings, user id, ip, user agent, etc.\n            $ssoAuthTokenGetService = new SsoAuthenticationTokenGetService();\n            $ssoAuthToken = $ssoAuthTokenGetService->getOrFail(\n                $token,\n                SsoState::TYPE_SSO_GET_KEY\n            );\n            $ssoAuthTokenGetService->assertAndConsume($ssoAuthToken, $uac, $ssoSettingEntity->id);\n        } catch (RecordNotFoundException $exception) {\n            throw new BadRequestException($exception->getMessage(), 400, $exception);\n        }\n\n        try {\n            $SsoKeys = TableRegistry::getTableLocator()->get('Passbolt/Sso.SsoKeys');\n            /** @var \\Passbolt\\Sso\\Model\\Entity\\SsoKey $key entity */\n            $key = $SsoKeys->find()->where(['id' => $keyId, 'user_id' => $uac->getId()])->firstOrFail();\n        } catch (RecordNotFoundException $exception) {\n            throw new RecordNotFoundException(__('The SSO key does not exist.'), 404, $exception);\n        }\n\n        return $key;\n    }\n}\n","sourceCodeStart":32,"sourceCodeEnd":64,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Service/SsoKeys/SsoKeysGetService.php#L32-L64","documentation":"In SsoKeysGetService::get(), the SSO authentication token is fetched via SsoAuthenticationTokenGetService::getOrFail(); if the token record does not exist, RecordNotFoundException('The authentication token does not exist.') is re-thrown as BadRequestException. The token is the secret handed to the browser during the SSO key exchange and must exist (and later pass assertAndConsume) before the SSO key is returned.","triggerScenarios":"Calling the SSO keys get endpoint with a token id that was never created, was already consumed by a prior call (assertAndConsume consumes it), or expired/was deleted.","commonSituations":"Replaying an SSO key-exchange token after it was already used in a previous request; browser refresh re-submitting a used token; clocks/expiry cleanup removing the token; copy-pasting a token from another session.","solutions":["Restart the SSO login/key-exchange flow from the beginning so a fresh token is generated","Do not reuse a token once the SSO key was fetched — each token is single-use","Check the sso_authentication_tokens table to confirm the token id exists","Ensure the client is not double-submitting the request (e.g. retries after a timeout)"],"exampleFix":"// before: reuse consumed token on page refresh\nawait getSsoKey(oldTokenId);\n// after: restart flow to obtain a new token\nconst {token} = await startSsoKeyExchange();\nawait getSsoKey(token);","handlingStrategy":"try-catch","validationCode":"// check token exists and is unconsumed before calling\n$token = $SsoAuthTokens->find()->where(['id' => $tokenId, 'active' => true])->first();\nif (!$token) {\n    restartSsoFlow();\n}","typeGuard":null,"tryCatchPattern":"try {\n    $key = $ssoKeysGetService->get($uac, $token, $keyId);\n} catch (BadRequestException $e) {\n    if (str_contains($e->getMessage(), 'authentication token does not exist')) {\n        return $this->restartSsoFlow(); // token used/expired\n    }\n    throw $e;\n}","preventionTips":["Treat SSO tokens as single-use; never reuse after a successful fetch","Avoid re-submitting the same request on page refresh or network retry","Restart the whole SSO flow when a token is rejected"],"tags":["sso","authentication-token","not-found","single-use-token"],"backgroundTag":"record-not-found","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"}