{"record":{"id":"42d24f11fb3d0d42","repo":"BookStackApp/BookStack","slug":"only-rs256-signature-validation-is-supported-toke","errorCode":null,"errorMessage":"Only RS256 signature validation is supported. Token reports using {$this->header['alg']}","messagePattern":"Only RS256 signature validation is supported\\. Token reports using (.+?)","errorType":"exception","errorClass":"OidcInvalidTokenException","httpStatus":null,"severity":"error","filePath":"app/Access/Oidc/OidcJwtWithClaims.php","lineNumber":123,"sourceCode":"            if (empty($this->$prop)) {\n                throw new OidcInvalidTokenException(\"Could not parse out a valid {$prop} within the provided token\");\n            }\n        }\n\n        if (empty($this->signature)) {\n            throw new OidcInvalidTokenException('Could not parse out a valid signature within the provided token');\n        }\n    }\n\n    /**\n     * Validate the signature of the given token and ensure it validates against the provided key.\n     *\n     * @throws OidcInvalidTokenException\n     */\n    protected function validateTokenSignature(): void\n    {\n        if ($this->header['alg'] !== 'RS256') {\n            throw new OidcInvalidTokenException(\"Only RS256 signature validation is supported. Token reports using {$this->header['alg']}\");\n        }\n\n        $parsedKeys = array_map(function ($key) {\n            try {\n                return new OidcJwtSigningKey($key);\n            } catch (OidcInvalidKeyException $e) {\n                throw new OidcInvalidTokenException('Failed to read signing key with error: ' . $e->getMessage());\n            }\n        }, $this->keys);\n\n        $contentToSign = $this->tokenParts[0] . '.' . $this->tokenParts[1];\n        /** @var OidcJwtSigningKey $parsedKey */\n        foreach ($parsedKeys as $parsedKey) {\n            if ($parsedKey->verify($contentToSign, $this->signature)) {\n                return;\n            }\n        }\n","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/BookStackApp/BookStack/blob/18f8469a1c72f8cc8497e9372635e6dea5028071/app/Access/Oidc/OidcJwtWithClaims.php#L105-L141","documentation":"OidcJwtWithClaims::validateTokenSignature only supports RS256 (RSA + SHA-256). Before verifying, it reads the token header's 'alg' claim and throws OidcInvalidTokenException for anything else (HS256, ES256, RS384, none, etc.), since the library only loads RSA signing keys and verifies with PKCS1 padding.","triggerScenarios":"The OIDC provider issues id_tokens with an alg other than RS256 in the JWT header, and that token reaches validateTokenSignature during validateCommonTokenDetails.","commonSituations":"IdP default algorithm set to HS256 (client-secret-based) or ES256; provider tenant misconfiguration; switching IdPs or upgrading a provider that changed its default signing algorithm.","solutions":["Reconfigure the identity provider to sign id_tokens with RS256","If using a provider with per-client algorithm settings, set the client's token signing algorithm to RS256","Check the reported alg in the error to confirm which unsupported algorithm is in use and align provider docs accordingly"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function tokenAlg(string $idToken): ?string {\n    $h = json_decode(base64_decode(strtr(explode('.', $idToken)[0] ?? '', '-_', '+/') ?: '', true) ?: '', true);\n    return is_array($h) ? ($h['alg'] ?? null) : null;\n}\n// call before validating: if (tokenAlg($idToken) !== 'RS256') { abort with config guidance }","typeGuard":"function isRs256Token(array $header): bool { return ($header['alg'] ?? null) === 'RS256'; }","tryCatchPattern":"try {\n    $jwt->validate($token);\n} catch (\\BookStack\\Access\\Oidc\\OidcInvalidTokenException $e) {\n    if (str_contains($e->getMessage(), 'RS256')) {\n        // IdP signing alg mismatch: reconfigure provider to RS256\n    }\n}","preventionTips":["Set the IdP's id_token signing algorithm to RS256 during OIDC client setup","Decode and check the header alg immediately after receiving the token to fail fast with a clear config message","Document the RS256 requirement for your OIDC provider (Auth0/Okta/Azure AD defaults vary)"],"tags":["php","oidc","jwt","rs256","algorithm-mismatch"],"backgroundTag":"jwt-signing-algorithm-unsupported","analyzedSha":"18f8469a1c72f8cc8497e9372635e6dea5028071","analyzedAt":"2026-09-02T19:49:33.068Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}