/** * ApiTokenAuditor, minimum scope and rotation cadence enforcement. * * Security model (two audit dimensions): * 1. Scope audit , verifies each registered token only holds the scopes * its declared policy permits (minimum scope principle) * 2. Rotation audit, checks token age against the rotation cadence policy * and emits warnings at the warning threshold, errors * when rotation is overdue * * In managed mode, out-of-policy tokens are blocked from use. * In advisory mode, violations are reported but not blocked. */ import type { SecurityEvent } from '../../events/security.js'; import type { FeatureFlagReader } from '../runtime/feature-flags/index.js'; /** Default rotation cadence: 90 days in ms. */ export declare const DEFAULT_ROTATION_CADENCE_MS: number; /** Default warning threshold: 14 days before rotation deadline. */ export declare const DEFAULT_ROTATION_WARNING_THRESHOLD_MS: number; /** * Metadata for a registered API token. * Callers supply this when registering a token with the auditor. */ export interface ApiTokenMetadata { /** Stable identifier for this token (never the secret value). */ id: string; /** Human-readable label (e.g. 'OPENAI_API_KEY', 'SLACK_BOT_TOKEN'). */ label: string; /** Epoch ms when this token was issued / last rotated. */ issuedAt: number; /** Scopes granted to this token (provider-specific strings). */ grantedScopes: readonly string[]; /** Policy ID this token is evaluated against (maps to TokenScopePolicy.id). */ policyId: string; } /** * Scope policy for a category of tokens. * Defines the maximum set of scopes permitted under the minimum scope principle. */ export interface TokenScopePolicy { /** Stable policy identifier. */ id: string; /** Human-readable name. */ name: string; /** * The complete list of scopes permitted for tokens governed by this policy. * Tokens holding scopes outside this set violate the minimum scope principle. */ allowedScopes: readonly string[]; /** * Rotation cadence in ms. Tokens older than this value are overdue. * Defaults to DEFAULT_ROTATION_CADENCE_MS when not specified. */ rotationCadenceMs?: number | undefined; /** * Warning threshold in ms before the rotation deadline. * Defaults to DEFAULT_ROTATION_WARNING_THRESHOLD_MS when not specified. */ rotationWarningThresholdMs?: number | undefined; } /** Outcome of a single scope audit check. */ export type ScopeAuditOutcome = 'ok' | 'violation'; /** Outcome of a single rotation audit check. */ export type RotationAuditOutcome = 'ok' | 'warning' | 'overdue'; /** Result of a scope audit for one token. */ export interface TokenScopeAuditResult { tokenId: string; outcome: ScopeAuditOutcome; /** Scopes present on the token that are not in the policy's allowedScopes. */ excessScopes: string[]; /** The policy evaluated against. */ policyId: string; } /** Result of a rotation audit for one token. */ export interface TokenRotationAuditResult { tokenId: string; outcome: RotationAuditOutcome; /** Token age in ms. */ ageMs: number; /** The configured rotation cadence in ms. */ cadenceMs: number; /** Ms remaining until rotation is due (negative = overdue). */ msUntilDue: number; /** Epoch ms when rotation was / is due. */ dueAt: number; } /** Combined audit result for a single token. */ export interface TokenAuditResult { tokenId: string; label: string; scope: TokenScopeAuditResult; rotation: TokenRotationAuditResult; /** * Whether this token is blocked from use in managed mode. * A token is blocked when it has a scope violation or an overdue rotation. */ blocked: boolean; } /** Full audit report across all registered tokens. */ export interface TokenAuditReport { results: TokenAuditResult[]; /** Tokens blocked in managed mode. */ blocked: string[]; /** Tokens with scope violations. */ scopeViolations: string[]; /** Tokens with rotation warnings (approaching deadline). */ rotationWarnings: string[]; /** Tokens with overdue rotation. */ rotationOverdue: string[]; /** Epoch ms when this report was produced. */ capturedAt: number; } /** Configuration for the ApiTokenAuditor. */ export interface TokenAuditorConfig { /** * When true, out-of-policy tokens are blocked from use. * When false, violations are reported but tokens remain usable. */ managed: boolean; /** * The capability gates control managed blocking when supplied by SDK runtime services. * Audits still report violations while disabled. */ featureFlags?: FeatureFlagReader | undefined; /** * Default rotation cadence (ms) applied to tokens whose policy does not set its * own `rotationCadenceMs`. Sourced from config (security.tokenAudit.rotationCadenceDays) * by SDK runtime services; falls back to DEFAULT_ROTATION_CADENCE_MS when unset. */ defaultRotationCadenceMs?: number | undefined; /** * Default rotation warning lead time (ms) applied to tokens whose policy does not * set its own `rotationWarningThresholdMs`. Sourced from config * (security.tokenAudit.rotationWarningDays); falls back to * DEFAULT_ROTATION_WARNING_THRESHOLD_MS when unset. */ defaultRotationWarningThresholdMs?: number | undefined; } /** * Callback invoked after each token is audited in `auditAll()`. * Receives one SecurityEvent per relevant audit outcome. * No-op by default, pass via `ApiTokenAuditor` constructor options. */ export type SecurityEventEmitter = (event: SecurityEvent) => void; /** * Audits registered API tokens for scope minimization and rotation cadence. * * Usage: * ```ts * const auditor = new ApiTokenAuditor({ managed: true }); * auditor.registerPolicy({ * id: 'openai', * name: 'OpenAI API', * allowedScopes: ['completions:write', 'models:read'], * rotationCadenceMs: 90 * 24 * 60 * 60 * 1000, * }); * auditor.registerToken({ * id: 'tok_openai_main', * label: 'OPENAI_API_KEY', * issuedAt: Date.now() - 30 * 24 * 60 * 60 * 1000, * grantedScopes: ['completions:write', 'models:read'], * policyId: 'openai', * }); * const report = auditor.auditAll(); * ``` */ export declare class ApiTokenAuditor { private readonly _policies; private readonly _tokens; private readonly _config; private readonly _emitter; constructor(config?: TokenAuditorConfig, options?: { emitter?: SecurityEventEmitter; }); private _managedBlockingEnabled; /** * Register a scope policy. Policies must be registered before tokens that * reference them. */ registerPolicy(policy: TokenScopePolicy): void; /** * Register an API token for auditing. * Throws if the referenced policyId is not registered. */ registerToken(metadata: ApiTokenMetadata): void; /** * Deregister a token (e.g. on rotation - remove the previous registration, * then registerToken with the new metadata). */ deregisterToken(tokenId: string): boolean; /** * Audit the scope of a single token against its policy. * Returns a TokenScopeAuditResult or null if the token is not registered. */ auditScope(tokenId: string): TokenScopeAuditResult | null; /** * Audit the rotation cadence of a single token. * Returns a TokenRotationAuditResult or null if the token is not registered. */ auditRotation(tokenId: string, now?: number): TokenRotationAuditResult | null; private _auditScopeFor; private _auditRotationFor; /** * Run scope and rotation audits for all registered tokens. * * In managed mode, tokens with scope violations or overdue rotation are * flagged as blocked. Callers must check `result.blocked` or * `report.blocked` before using a token. */ auditAll(now?: number): TokenAuditReport; /** * Check whether a specific token is currently blocked. * Returns false when not in managed mode or when the token is not registered. */ isBlocked(tokenId: string, now?: number): boolean; /** Whether managed mode is active. */ get isManaged(): boolean; /** Number of registered tokens. */ get tokenCount(): number; /** Number of registered policies. */ get policyCount(): number; /** Get a registered policy by id, or undefined if not found. */ getPolicy(id: string): TokenScopePolicy | undefined; /** Get registered token metadata by id (without the secret value). */ getTokenMetadata(id: string): ApiTokenMetadata | undefined; } //# sourceMappingURL=token-audit.d.ts.map