import { VorionError } from '../common/errors.js';
import { type DPoPConfig, type DPoPVerificationResult, type JTICache, type TrustTier } from './types.js';
/**
 * DPoP-specific error
 */
export declare class DPoPError extends VorionError {
    code: string;
    statusCode: number;
    constructor(message: string, details?: Record<string, unknown>);
}
/**
 * Configuration for Redis JTI cache
 */
export interface RedisJTICacheConfig {
    /** Maximum number of JTIs to store (default: 100,000) */
    maxSize?: number;
    /** Default TTL in seconds for JTI entries (default: 300 = 5 minutes) */
    defaultTTLSeconds?: number;
    /** Interval in ms for cleanup of expired entries from sorted set (default: 60000 = 1 minute) */
    cleanupIntervalMs?: number;
    /** Whether to fall back to in-memory cache on Redis failure (default: true) */
    enableFallback?: boolean;
}
/**
 * Redis-backed JTI cache for scalable, multi-instance DPoP replay prevention
 *
 * Features:
 * - Uses SETNX for atomic "check and set" to prevent race conditions
 * - Bounded size with automatic eviction of oldest entries
 * - TTL-based expiration matching DPoP proof lifetime
 * - Graceful fallback to in-memory cache when Redis is unavailable
 * - Metrics for monitoring cache performance
 *
 * Key structure:
 * - Individual JTIs: `vorion:dpop:jti:{jti_hash}` (string with TTL)
 * - JTI index: `vorion:dpop:jti:index` (sorted set with timestamp scores for bounded size)
 */
export declare class RedisJTICache implements JTICache {
    private redis;
    private fallbackCache;
    private inFallbackMode;
    private cleanupInterval;
    private readonly config;
    constructor(config?: RedisJTICacheConfig);
    /**
     * Get Redis client, initializing if needed
     */
    private getRedis;
    /**
     * Calculate SHA-256 hash of JTI for key
     */
    private hashJti;
    /**
     * Build Redis key for a JTI
     */
    private buildKey;
    /**
     * Store a JTI with expiration, returning false if it already exists
     * Uses SETNX for atomic check-and-set
     */
    store(jti: string, expiresAt: Date): Promise<void>;
    /**
     * Check if a JTI exists (has been seen before)
     * Uses SETNX semantics: if we can't set it, it exists
     */
    exists(jti: string): Promise<boolean>;
    /**
     * Atomically check if JTI exists and store it if not
     * Returns true if JTI was new (not a replay), false if it already existed (replay detected)
     */
    checkAndStore(jti: string, expiresAt: Date): Promise<boolean>;
    /**
     * Enforce maximum size limit by removing oldest entries
     */
    private enforceSizeLimit;
    /**
     * Clean up expired entries from the sorted set
     * Individual JTI keys auto-expire via TTL, but we need to clean up the index
     */
    private cleanupExpiredFromIndex;
    /**
     * Start periodic cleanup of expired entries
     */
    private startCleanup;
    /**
     * Get current cache statistics
     */
    getStats(): Promise<{
        redisSize: number;
        fallbackSize: number;
        inFallbackMode: boolean;
        redisHealthy: boolean;
    }>;
    /**
     * Check if the cache is in fallback mode
     */
    isInFallbackMode(): boolean;
    /**
     * Destroy the cache and cleanup resources
     */
    destroy(): void;
}
/**
 * Create a Redis-backed JTI cache
 */
export declare function createRedisJTICache(config?: RedisJTICacheConfig): RedisJTICache;
/**
 * DPoP Service for generating and verifying DPoP proofs
 *
 * @example
 * ```typescript
 * const dpop = new DPoPService({
 *   requiredForTiers: [TrustTier.T2, TrustTier.T3, TrustTier.T4, TrustTier.T5],
 *   maxProofAge: 60,
 *   nonceRequired: false,
 *   clockSkewTolerance: 5,
 *   allowedAlgorithms: ['ES256'],
 * });
 *
 * // Generate a proof
 * const proof = await dpop.generateProof(privateKey, 'POST', 'https://api.example.com/token');
 *
 * // Verify a proof
 * const result = await dpop.verifyProof(proof, publicKey, 'POST', 'https://api.example.com/token');
 * ```
 */
export declare class DPoPService {
    private config;
    private jtiCache;
    /**
     * Create a new DPoP service
     *
     * @param config - DPoP configuration
     * @param jtiCache - JTI cache for replay prevention (defaults to in-memory)
     */
    constructor(config: Partial<DPoPConfig>, jtiCache?: JTICache);
    /**
     * Generate a DPoP proof JWT
     *
     * @param privateKey - ECDSA private key for signing
     * @param method - HTTP method (e.g., 'GET', 'POST')
     * @param uri - Target URI
     * @param accessTokenHash - SHA-256 hash of access token (for bound tokens)
     * @param algorithm - Signing algorithm (default: ES256)
     * @returns Signed DPoP proof JWT
     */
    generateProof(privateKey: CryptoKey, method: string, uri: string, accessTokenHash?: string, algorithm?: 'ES256' | 'ES384' | 'ES512'): Promise<string>;
    /**
     * Verify a DPoP proof JWT
     *
     * @param proof - DPoP proof JWT string
     * @param expectedMethod - Expected HTTP method
     * @param expectedUri - Expected target URI
     * @param expectedAth - Expected access token hash (for bound tokens)
     * @returns Verification result
     */
    verifyProof(proof: string, expectedMethod: string, expectedUri: string, expectedAth?: string): Promise<DPoPVerificationResult>;
    /**
     * Check if DPoP is required for a given trust tier
     *
     * @param trustTier - Trust tier to check
     * @returns Whether DPoP is required
     */
    isRequired(trustTier: TrustTier): boolean;
    /**
     * Validate that an access token is properly bound to a DPoP key
     *
     * @param accessToken - The access token
     * @param dpopProof - The DPoP proof
     * @param expectedMethod - Expected HTTP method
     * @param expectedUri - Expected target URI
     * @param tokenCnf - The cnf claim from the access token (containing jkt)
     * @returns Whether the token is properly bound
     */
    validateBoundToken(accessToken: string, dpopProof: string, expectedMethod: string, expectedUri: string, tokenCnf?: {
        jkt?: string;
    }): Promise<boolean>;
    /**
     * Generate an access token hash for the ath claim
     *
     * @param accessToken - Access token to hash
     * @returns Base64url-encoded SHA-256 hash
     */
    generateAccessTokenHash(accessToken: string): Promise<string>;
    /**
     * Get current configuration
     */
    getConfig(): Readonly<DPoPConfig>;
    /**
     * Get JTI cache statistics
     * Returns information about cache state including Redis/fallback status
     */
    getJTICacheStats(): Promise<{
        redisSize?: number;
        fallbackSize?: number;
        inFallbackMode?: boolean;
        redisHealthy?: boolean;
        cacheType: 'redis' | 'memory';
    }>;
    /**
     * Check if the JTI cache is in fallback mode (using in-memory instead of Redis)
     */
    isJTICacheInFallbackMode(): boolean;
    /**
     * Destroy the service and cleanup resources.
     * This stops the JTI cache cleanup interval.
     */
    destroy(): void;
}
/**
 * Options for creating a DPoP service
 */
export interface CreateDPoPServiceOptions {
    /** DPoP configuration */
    config?: Partial<DPoPConfig>;
    /** Custom JTI cache (if not provided, uses Redis-backed cache) */
    jtiCache?: JTICache;
    /** Redis JTI cache configuration (only used if jtiCache is not provided) */
    redisJTICacheConfig?: RedisJTICacheConfig;
    /** Use in-memory cache instead of Redis (for testing/development) */
    useInMemoryCache?: boolean;
}
/**
 * Create a DPoP service with default configuration for CAR ID
 *
 * By default, uses a Redis-backed JTI cache for scalability across multiple instances.
 * Set `useInMemoryCache: true` for development/testing with single instance.
 *
 * @example
 * ```typescript
 * // Production: Redis-backed cache (default)
 * const dpop = createDPoPService();
 *
 * // Development: In-memory cache
 * const dpop = createDPoPService({ useInMemoryCache: true });
 *
 * // Custom Redis cache configuration
 * const dpop = createDPoPService({
 *   redisJTICacheConfig: { maxSize: 50000, defaultTTLSeconds: 120 }
 * });
 * ```
 */
export declare function createDPoPService(options?: CreateDPoPServiceOptions | Partial<DPoPConfig>, jtiCache?: JTICache): DPoPService;
//# sourceMappingURL=dpop.d.ts.map