/** * Session Claims Cookie Utilities * * Implements signed session claims to reduce API calls in middleware. * Claims contain minimal session info (userId, sessionId hash) that can be * verified locally without database lookup. * * Security: * - HMAC-SHA256 signing prevents tampering * - 5-minute expiration ensures quick revocation * - HttpOnly, Secure, SameSite cookies * - Context-separated signing keys (HKDF-SHA256): the deployment secret * (`SESSION_CLAIMS_SECRET`) is never used directly as an HMAC key. * `signSessionClaims`/`verifySessionClaims` derive a dedicated key under * the `voyant:session-claims:v1` context, so a leak of a token-signing * key (or any other derived key) does not compromise sibling contexts * (e.g. the cloud-admin state cookie) or the raw Better Auth secret. * * Compatible with environments that expose the standard Web Crypto API, * including Node.js, browsers, and Cloudflare Workers. */ export interface SessionClaims { userId: string; sessionId: string; iat: number; exp: number; } /** * HKDF context label under which session-claims bearer tokens are signed. * Bumping the version suffix invalidates all outstanding tokens. */ export declare const SESSION_CLAIMS_KEY_CONTEXT = "voyant:session-claims:v1"; /** * HKDF context label for the Voyant Cloud admin-auth state-cookie HMAC key. * Consumers (e.g. the operator auth handler) derive this at the boundary and * pass the derived key down as `cookieSecret`. */ export declare const CLOUD_STATE_COOKIE_KEY_CONTEXT = "voyant:cloud-state-cookie:v1"; /** * Derive a context-separated subkey from a root secret via HKDF-SHA256 * (Web Crypto, Workers-compatible). * * The same root secret yields independent keys per context label, so a * compromise of one derived key cannot be replayed against another context * or against anything still using the root secret (e.g. Better Auth). * * @param secret - Root secret (e.g. `SESSION_CLAIMS_SECRET`) * @param context - Context label, e.g. `"voyant:session-claims:v1"` * @returns base64url-encoded 256-bit key (43 chars — satisfies >=32-char * secret checks downstream) */ export declare function deriveContextKey(secret: string, context: string): Promise; /** * Sign session claims and return as JWT-like token * * Format: base64url(header).base64url(payload).base64url(signature) * * The HMAC key is NOT the raw `secret`: it is derived via * `deriveContextKey(secret, SESSION_CLAIMS_KEY_CONTEXT)` so the root secret * is never used directly as a token-signing key (context separation). * * @param userId - User ID from verified session * @param sessionId - Full session ID (will be hashed) * @param secret - Root secret; the signing key is derived from it * @returns Signed token string */ export declare function signSessionClaims(userId: string, sessionId: string, secret: string): Promise; /** * Verify and decode session claims token * * Verification uses the same context-derived key as `signSessionClaims` * (`SESSION_CLAIMS_KEY_CONTEXT`), so tokens signed with the raw secret * (pre context-separation) are rejected. * * @param token - Signed token from cookie * @param secret - Root secret; the verification key is derived from it * @returns Decoded claims if valid, null if invalid/expired */ export declare function verifySessionClaims(token: string, secret: string): Promise; //# sourceMappingURL=session-claims.d.ts.map