{"record":{"id":"19871edf6b10d45b","repo":"passbolt/passbolt_api","slug":"the-route-0-is-not-permitted-with-jwt-authentication","errorCode":null,"errorMessage":"The route {0} is not permitted with JWT authentication.","messagePattern":"The route (.+?) is not permitted with JWT authentication\\.","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"plugins/PassboltCe/JwtAuthentication/src/Middleware/JwtRouteFilterMiddleware.php","lineNumber":75,"sourceCode":"        return [\n            '/auth/login',\n            '/auth/logout',\n        ];\n    }\n\n    /**\n     * Checks that the request is JWT related, and throws an exception if the required routes are not allowed.\n     *\n     * @param \\Cake\\Http\\ServerRequest $request Request\n     * @return void\n     * @throws \\Cake\\Http\\Exception\\BadRequestException\n     */\n    protected function throwExceptionIfRouteIsNotAllowedWithJwtAuth(ServerRequest $request): void\n    {\n        if ($request->getAttribute(JwtRequestDetectionService::IS_JWT_AUTH_REQUEST)) {\n            $route = $request->getAttribute('params')['_matchedRoute'] ?? null;\n            if (in_array($route, $this->getBlockedRoutes())) {\n                throw new BadRequestException(\n                    __('The route {0} is not permitted with JWT authentication.', $route)\n                );\n            }\n        }\n    }\n}\n","sourceCodeStart":57,"sourceCodeEnd":82,"githubUrl":"https://github.com/passbolt/passbolt_api/blob/31c1bbc10f32808a607fa9bd81891e898779c0bc/plugins/PassboltCe/JwtAuthentication/src/Middleware/JwtRouteFilterMiddleware.php#L57-L82","documentation":"Thrown by JwtRouteFilterMiddleware::throwExceptionIfRouteIsNotAllowedWithJwtAuth (invoked from process). Certain legacy routes that rely on session/cookie auth are deliberately blocked when the request is a JWT-auth request, returning a 400 naming the route.","triggerScenarios":"A request authenticated with a JWT bearer token hits one of the routes returned by getBlockedRoutes() (e.g. /auth/logout, /users/me/settings-type endpoints that require session auth).","commonSituations":"Client uses a JWT access token to call session-only routes (e.g. logout or csrf-protected endpoints); frontend partially migrated between auth modes; API clients mixing session cookies and JWT in one session.","solutions":["Use the JWT-appropriate endpoint instead of the blocked route (e.g. DELETE the JWT itself rather than /auth/logout)","Perform session-based auth (login without JWT) when calling the blocked routes","Review getBlockedRoutes() in JwtRouteFilterMiddleware to see which routes are JWT-forbidden","Update the client to the protocol-mandated endpoints for JWT authentication"],"exampleFix":"// before (with JWT token)\nPOST /auth/logout\n// after\nPOST /auth/jwt/logout  (or discard the JWT client-side)","handlingStrategy":"validation","validationCode":"const blockedRoutes = ['/auth/logout', '/users/abuseReports', /* see getBlockedRoutes */];\nif (usingJwt && blockedRoutes.some(r => path.startsWith(r))) useSessionAuthInstead();","typeGuard":null,"tryCatchPattern":"try { await api(path, { token: jwt }); } catch (e) { if (String(e.message).includes('not permitted with JWT authentication')) { reauthWithSession(path); } }","preventionTips":["Know which routes are session-only and never call them with a bearer JWT","Use the JWT logout/dispose flow instead of session logout","Keep clients updated with protocol changes"],"tags":["http","routing","jwt","middleware","bad-request"],"backgroundTag":"operation-not-supported","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"}