3.5 KiB
token-verifier
(no submodules)
Purpose
Verifies signed JWTs against local keys or remote JWKS endpoints. The TokenVerifier class resolves verification keys from either an in-memory key cache or a remote JWKS URI (with retry and AbortSignal support), then delegates cryptographic verification to jose. After successful signature verification, per-verification constraint checks enforce tenant isolation, role requirements, and permission scopes.
Features
TokenVerifierclass with configurable issuer, audience, clock tolerance, and injectable clock- Remote JWKS URI support with configurable TTL caching and retry (default 3 attempts)
AbortSignalcancellation for JWKS fetch operationsaddKey(jwk)— register a local JWK for key-only verification (no remote fetch)clearCache()— invalidate the JWKS cache for immediate rotationverifyToken(token, options?)— returnsVerifyTokenResult(never throws)- Per-verification constraints:
requiredTenantId,requiredRole,requiredPermissions,requiredClaims,requiredDomains verifyTokenWithKey(token, key, options?)— standalone function for pre-imported keyscreateTokenVerifier(config?)— factory function
Usage: Basic Example
import { generateKeyPair, keyPairToJWK } from "@suaveplan/jwt-tenant/keys/key-generator";
import { TokenIssuer } from "@suaveplan/jwt-tenant/token/token-issuer";
import { TokenVerifier } from "@suaveplan/jwt-tenant/token/token-verifier";
const kp = await generateKeyPair("EdDSA");
const issuer = new TokenIssuer({ issuer: "https://auth.example.com" });
const token = await issuer.createToken(kp, { subject: "u1", tenantId: "acme" });
const verifier = new TokenVerifier({ issuer: "https://auth.example.com" });
const jwk = await keyPairToJWK(kp);
verifier.addKey(jwk);
const result = await verifier.verifyToken(token);
// result.valid === true
// result.payload.tenant_id === "acme"
Usage: Advanced Example
const verifier = new TokenVerifier({
jwksUri: "https://auth.example.com/.well-known/jwks.json",
issuer: "https://auth.example.com",
cacheMaxAge: 5 * 60 * 1000,
clockTolerance: 30,
maxRetries: 3,
signal: AbortSignal.timeout(5000),
});
const result = await verifier.verifyToken(token, {
requiredTenantId: "acme",
requiredRole: "admin",
requiredPermissions: ["write:data"],
requiredDomains: ["acme.example.com"],
});
API Reference
TokenVerifier
Constructor: new TokenVerifier(config?: TokenVerifierConfig).
Methods
verifyToken(token, options?): Promise<VerifyTokenResult>— Verifies the token. Returns{ valid: true, payload }or{ valid: false, error, errorCode }. Never throws.addKey(jwk): void— Adds a local JWK to the key cache.clearCache(): void— Clears the key cache.
createTokenVerifier(config?): TokenVerifier
Factory function.
verifyTokenWithKey(token, key, options?): Promise<VerifyTokenResult>
Standalone verification with a pre-imported key reference.
Implementation Notes
JWKS cache uses timestamp comparison (clock() >= cacheExpiresAt) for expiry. Multi-key verification tries each JWK in order and returns on the first success — the last error is preserved and wrapped if all keys fail. The checkConstraints method is protected to allow subclass extension without exposing it in the public API. All jose errors are classified by message substring matching into one of the JWT error codes.