export declare const DEVICE_CREDENTIAL_SCHEMA_VERSION: 1; export interface DeviceCredentials { schemaVersion: typeof DEVICE_CREDENTIAL_SCHEMA_VERSION; /** HTTPS origin pinned when enrollment starts. */ issuer: string; /** Short-lived signed bearer. Never expose outside the host process. */ accessToken: string; /** Absolute access-token expiry supplied by the server, Unix epoch ms. */ accessExpiresAt: number; /** Rotating opaque secret. Never expose outside the host process. */ refreshToken: string; /** Absolute server-issued device expiry, represented as Unix epoch ms. */ deviceExp: number; /** Local metadata only; ISO timestamp of the last atomic credential write. */ savedAt: string; /** * Durable idempotency key for an in-flight refresh rotation. A failed or * interrupted request keeps this value so the next host process can replay * the same server operation instead of reusing the old refresh as a new one. */ pendingRefreshRequestId?: string; /** Unix epoch ms when the current replay window began. */ pendingRefreshStartedAt?: number; /** Ambiguous/unsafe refresh state: never send the stored refresh again. */ refreshRecoveryRequired?: true; } export type DeviceCredentialWriteInput = Pick & { pendingRefreshRequestId?: string; pendingRefreshStartedAt?: number; refreshRecoveryRequired?: true; }; export type DevicePublicStatus = { schemaVersion: typeof DEVICE_CREDENTIAL_SCHEMA_VERSION; enrolled: false; } | { schemaVersion: typeof DEVICE_CREDENTIAL_SCHEMA_VERSION; enrolled: true; issuer: string; deviceExp: number; savedAt: string; }; export interface DeviceCredentialPathOptions { /** Test/embedding seam. Defaults to os.homedir(). */ homeDir?: string; /** Exact file override. Takes precedence over homeDir. */ filePath?: string; } export interface WriteDeviceCredentialsOptions extends DeviceCredentialPathOptions { /** Test seam; defaults to the current wall clock. */ now?: () => Date; } export declare class DeviceCredentialError extends Error { readonly code: 'invalid_issuer' | 'issuer_mismatch' | 'unsafe_file' | 'invalid_file'; constructor(message: string, code: 'invalid_issuer' | 'issuer_mismatch' | 'unsafe_file' | 'invalid_file'); } export declare function deviceCredentialsPath(options?: DeviceCredentialPathOptions): string; /** * Normalize and validate the credential issuer. * * Production enrollment is HTTPS-only. Loopback HTTP is accepted solely for * local development/self-tests; credentials are never sent over cleartext to * a non-loopback host. Paths, query strings, fragments and userinfo are * rejected so every request stays pinned to one unambiguous origin. */ export declare function normalizeDeviceIssuer(raw: string): string; export declare function readDeviceCredentials(options?: DeviceCredentialPathOptions): DeviceCredentials | null; /** * Atomically replace the device credential pair with exact 0600 permissions. * If a credential already exists, its issuer is immutable until explicit * logout. This prevents a changed env/platform binding from exfiltrating the * rotating refresh token to another origin. */ export declare function writeDeviceCredentials(input: DeviceCredentialWriteInput, options?: WriteDeviceCredentialsOptions): DeviceCredentials; /** Delete only the local credential file. Server-side revocation is separate. */ export declare function clearDeviceCredentials(options?: DeviceCredentialPathOptions): boolean; export declare function readDevicePublicStatus(options?: DeviceCredentialPathOptions): DevicePublicStatus; //# sourceMappingURL=device.d.ts.map