{"record":{"id":"7d9356ac56d04126","repo":"passbolt/passbolt_api","slug":"the-sso-authentication-token-is-invalid-user-agent-is","errorCode":null,"errorMessage":"The SSO authentication token is invalid. User agent is missing.","messagePattern":"The SSO authentication token is invalid\\. User agent is missing\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltEe/Sso/src/Service/SsoAuthenticationTokens/SsoAuthenticationTokenGetService.php","lineNumber":203,"sourceCode":"        }\n\n        if (Configure::read('passbolt.security.userIp')) {\n            try {\n                $ip = $token->getDataProperty(SsoAuthenticationToken::DATA_IP);\n            } catch (AuthenticationTokenDataPropertyException $exception) {\n                throw new BadRequestException($errorMsg . __('Token IP is missing.'), 400, $exception);\n            }\n\n            if ($ip !== $uac->getUserIp()) {\n                throw new BadRequestException($errorMsg . __('User IP mismatch.'));\n            }\n        }\n\n        if (Configure::read('passbolt.security.userAgent')) {\n            try {\n                $ua = $token->getDataProperty(SsoAuthenticationToken::DATA_USER_AGENT);\n            } catch (AuthenticationTokenDataPropertyException $exception) {\n                throw new BadRequestException($errorMsg . __('User agent is missing.'), 400, $exception);\n            }\n            if ($ua !== $uac->getUserAgent()) {\n                throw new BadRequestException($errorMsg . __('User agent mismatch.'));\n            }\n        }\n\n        if ($sid !== $settingsId || !Validation::uuid($sid)) {\n            throw new BadRequestException($errorMsg . __('Settings mismatch.'));\n        }\n    }\n}\n","sourceCodeStart":185,"sourceCodeEnd":215,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Sso/src/Service/SsoAuthenticationTokens/SsoAuthenticationTokenGetService.php#L185-L215","documentation":"A BadRequestException from assert() raised when the 'passbolt.security.userAgent' check is enabled but the token's data payload lacks the user agent property. getDataProperty(DATA_USER_AGENT) throws AuthenticationTokenDataPropertyException, converted into this BadRequestException.","triggerScenarios":"assert()/assertAndConsume() runs with Configure 'passbolt.security.userAgent' = true and the token data has no DATA_USER_AGENT entry — typically tokens created under different security config than the one used during assertion, or missing/corrupted token data.","commonSituations":"Config toggled between token creation and consumption; tokens seeded manually without user agent data; headless/API clients creating tokens without recording a user agent; data JSON lost on restore.","solutions":["Restart the SSO flow to create a fresh token that includes the user agent data","Ensure the same passbolt.security.userAgent setting applies at creation and assertion time","Verify the client sends a User-Agent header when initiating the flow (headless clients may omit it)","Set passbolt.security.userAgent = false if UA pinning is not needed in your environment"],"exampleFix":"// before\ncurl -X POST https://passbolt.example.com/sso/... # no User-Agent header -> token lacks UA data\n// after\ncurl -A \"my-client/1.0\" -X POST https://passbolt.example.com/sso/...","handlingStrategy":"validation","validationCode":"$uaEnabled = \\Cake\\Core\\Configure::read('passbolt.security.userAgent');\n$hasUa = !$uaEnabled || $token->hasDataProperty(\\Passbolt\\Sso\\Model\\Entity\\SsoAuthenticationToken::DATA_USER_AGENT);","typeGuard":null,"tryCatchPattern":"try {\n    $service->assertAndConsume($token, $uac, $settingsId);\n} catch (\\Cake\\Http\\Exception\\BadRequestException $e) {\n    if (str_contains($e->getMessage(), 'User agent is missing')) {\n        // ensure client sends User-Agent and recreate the token\n    }\n}","preventionTips":["Ensure HTTP clients always send a User-Agent header","Keep passbolt.security.userAgent consistent between token creation and assertion","Create tokens through the SSO service so UA data is recorded"],"tags":["sso","missing-data","user-agent","security-config"],"backgroundTag":"missing-required-config-field","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"}