{"record":{"id":"7461ff76ae2f690c","repo":"passbolt/passbolt_api","slug":"simultaneous-scim-and-session-authentication-is-not","errorCode":null,"errorMessage":"Simultaneous SCIM and session authentication is not permitted.","messagePattern":"Simultaneous SCIM and session authentication is not permitted\\.","errorType":"exception","errorClass":"Cake\\Http\\Exception\\ForbiddenException","httpStatus":403,"severity":"error","filePath":"plugins/PassboltEe/Scim/src/Middleware/ScimAuthMiddleware.php","lineNumber":93,"sourceCode":"\n    /**\n     * @param \\Cake\\Http\\ServerRequest $request server request\n     * @param \\Cake\\Core\\ContainerInterface $container container\n     * @return void\n     * @throws \\Psr\\Container\\ContainerExceptionInterface\n     * @throws \\Psr\\Container\\NotFoundExceptionInterface\n     * @throws \\Cake\\Http\\Exception\\ForbiddenException if the user is logged in via session\n     */\n    private function assertNotSessionAuthenticated(ServerRequest $request, ContainerInterface $container): void\n    {\n        /** @var \\Authentication\\AuthenticationServiceInterface $authenticationService */\n        $authenticationService = $container->get(AuthenticationServiceInterface::class);\n        if (!($authenticationService instanceof SessionAuthenticationService)) {\n            return;\n        }\n        $isUserSessionAuthenticated = $authenticationService->authenticate($request)->isValid();\n        if ($isUserSessionAuthenticated) {\n            throw new ForbiddenException(__('Simultaneous SCIM and session authentication is not permitted.'));\n        }\n    }\n}\n","sourceCodeStart":75,"sourceCodeEnd":97,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltEe/Scim/src/Middleware/ScimAuthMiddleware.php#L75-L97","documentation":"This ForbiddenException is thrown by the SCIM auth middleware when an HTTP request reaches a SCIM endpoint while already carrying a valid session authentication (browser cookie). Passbolt's SCIM API is designed exclusively for bearer-token (SCIM authentication service) access, so the middleware deliberately swaps the container's AuthenticationService for ScimAuthenticationService and rejects any request where a server-side session is already valid. This prevents ambiguous identity resolution where a request could be simultaneously treated as a logged-in user session and a SCIM client.","triggerScenarios":"Any request to /scim/v2/... routes that includes both a SCIM bearer token header and a valid PHP session cookie. The middleware's assertNotSessionAuthenticated() fetches the SessionAuthenticationService from the DI container, calls authenticate($request), and throws when isValid() is true. The most common concrete case: an admin who is logged into the passbolt web UI in the same browser (same domain) calls SCIM endpoints from scripts or a REST client using that browser's cookies.","commonSituations":"Calling SCIM API endpoints directly from the browser (e.g. testing /scim/v2/settingId/Users in the address bar or via fetch/XHR in the web UI console while logged in); proxies or applications that forward the user's cookies together with the SCIM Authorization header; automated tests that reuse an authenticated browser session against SCIM endpoints.","solutions":["Log out of the passbolt web UI (clear the session cookie) in the client making the SCIM request, or make SCIM calls from a non-browser client (curl, Postman, SDK) that does not send session cookies","Ensure the SCIM client sends only the Authorization: Bearer <token> header and does not forward cookies; use a separate domain/subdomain or cookie-free path for SCIM automation","If writing tests or integrations, authenticate against SCIM endpoints using a dedicated SCIM request token (obtained via the SCIM settings endpoints) rather than the logged-in session","Review any reverse-proxy or middleware that merges browser sessions into API requests and strip the session cookie for /scim/ routes"],"exampleFix":"// before (browser fetch while logged in - session cookie is sent)\nfetch('/scim/v2/abc123/Users', { headers: { Authorization: 'Bearer ' + token } });\n\n// after (server-side curl, no cookies)\ncurl -H \"Authorization: Bearer $SCIM_TOKEN\" https://passbolt.example.com/scim/v2/abc123/Users","handlingStrategy":"validation","validationCode":"if (document.cookie.includes('passbolt_session')) {\n  throw new Error('Cannot call SCIM endpoints from a session-authenticated browser context.');\n}","typeGuard":"function isScimSafeRequest(headers: Headers): boolean {\n  return headers.has('Authorization') && headers.get('Authorization')!.startsWith('Bearer ') && !hasSessionCookie();\n}","tryCatchPattern":"try {\n  const res = await fetch(scimUrl, { headers: { Authorization: `Bearer ${token}` }, credentials: 'omit' });\n  if (res.status === 403) throw new ScimSessionConflictError(await res.text());\n} catch (e) { /* handle ScimSessionConflictError / network errors */ }","preventionTips":["Always send SCIM requests with credentials: 'omit' (fetch) or a cookie-free client such as curl/Postman","Never test SCIM endpoints from the browser console of a logged-in passbolt session","Use a dedicated API client or service account for SCIM automation, separate from any browser session","Strip session cookies for /scim/ routes at any reverse proxy layer"],"tags":["scim","authentication","http","middleware","conflicting-auth"],"backgroundTag":"mutually-exclusive-options","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"}