{"record":{"id":"f7e64309f1149b1a","repo":"BookStackApp/BookStack","slug":"missing-token-subject-value","errorCode":null,"errorMessage":"Missing token subject value","messagePattern":"Missing token subject value","errorType":"exception","errorClass":"OidcInvalidTokenException","httpStatus":null,"severity":"error","filePath":"app/Access/Oidc/OidcIdToken.php","lineNumber":86,"sourceCode":"        }\n\n        $dayAgo = time() - 86400;\n        $iat = intval($this->payload['iat']);\n        if ($iat > ($now + $skewSeconds) || $iat < $dayAgo) {\n            throw new OidcInvalidTokenException('Token issue at time is not recent or is invalid');\n        }\n\n        // 7. If the acr Claim was requested, the Client SHOULD check that the asserted Claim Value is appropriate.\n        // The meaning and processing of acr Claim Values is out of scope for this document.\n        // NOTE: Not used for our case here. acr is not requested.\n\n        // 8. When a max_age request is made, the Client SHOULD check the auth_time Claim value and request\n        // re-authentication if it determines too much time has elapsed since the last End-User authentication.\n        // NOTE: Not used for our case here. A max_age request is not made.\n\n        // Custom: Ensure the \"sub\" (Subject) Claim exists and has a value.\n        if (empty($this->payload['sub'])) {\n            throw new OidcInvalidTokenException('Missing token subject value');\n        }\n    }\n}\n","sourceCodeStart":68,"sourceCodeEnd":90,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Access/Oidc/OidcIdToken.php#L68-L90","documentation":"The 'sub' (Subject) claim uniquely identifies the end user and is REQUIRED by the OIDC spec. As a custom check, validateTokenClaims throws when the token payload has no 'sub' value, because the application cannot attribute the session to any user.","triggerScenarios":"validate() on an ID token whose payload lacks 'sub' or has it empty/null.","commonSituations":"Non-conformant IdP omitting subject; tokens generated by custom/legacy auth services; test fixtures missing 'sub'; claim-filtering middleware stripping the subject for privacy.","solutions":["Fix the IdP to include a non-empty 'sub' claim per OIDC Core spec","Update test token fixtures to include 'sub'","Check no proxy/middleware removes claims from the id_token","Map the correct user identifier if the IdP uses a different claim and you control token minting"],"exampleFix":"// before (test fixture payload)\n['iss' => $iss, 'aud' => $aud, 'exp' => time()+3600, 'iat' => time()]\n// after\n['iss' => $iss, 'aud' => $aud, 'exp' => time()+3600, 'iat' => time(), 'sub' => 'user-123']","handlingStrategy":"validation","validationCode":"if (empty($payload['sub'])) { throw new \\RuntimeException('ID token missing sub claim'); }","typeGuard":null,"tryCatchPattern":"try { $token->validate($now); } catch (OidcInvalidTokenException $e) { if ($e->getMessage() === 'Missing token subject value') { /* reject login; report non-conformant IdP */ } throw $e; }","preventionTips":["Validate IdP conformance (sub is REQUIRED by OIDC Core)","Keep test fixtures aligned with real token claims including sub","Ensure no middleware strips claims from the id_token"],"tags":["oidc","jwt","token-validation"],"backgroundTag":"jwt-missing-claim","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}