/** * Where an OrcaRouter key lives once we have one. * * REUSES THE PROJECT'S OWN HOME, not a new secret store. `optimizerHome()` already decides where * this package keeps state the user owns (`$TOKEN_OPTIMIZER_HOME`, else `~/.token-optimizer`), and * the routing manifest, the supervisor state and the accounting ledger all live under it. A second * credential directory for OrcaRouter alone would be one more thing to back up, one more thing to * leak, and one more thing a user has to find to revoke. * * WRITTEN 0600. The file holds a bearer credential that is billed to the user, so it is created * owner-read-write and nothing else, and re-tightened on every write in case it was copied. * * A PKCE-ISSUED KEY IS DURABLE, NOT A REFRESH TOKEN. There is no refresh endpoint and no refresh * grant: the key is reused until OrcaRouter revokes it. The one state change this file records is * `needsReauth`, set when the relay answers 401 -- and it is recorded against the exact * `{accountId, generation}` that made the rejected request, so a late failure from an old request * can never mark a freshly reauthorized credential as broken. Nothing here schedules a refresh and * nothing deletes a credential before a replacement has been stored. */ /** The two ways a user can end up holding a key. They share everything downstream. */ export type OrcaCredentialSource = 'api-key' | 'oauth-pkce'; /** Provider ids as the UI and the CLI present them. */ export declare const ORCA_API_KEY_PROVIDER_ID = "orcarouter"; export declare const ORCA_PKCE_PROVIDER_ID = "orcarouter-oauth"; export declare const ORCA_API_KEY_LABEL = "OrcaRouter - API"; export declare const ORCA_PKCE_LABEL = "OrcaRouter - Auth"; export interface StoredOrcaCredential { readonly source: OrcaCredentialSource; /** The secret. Never logged, never returned in an API response. */ readonly key: string; /** The OrcaRouter account the key belongs to, or `api-key` for a hand-pasted key. */ readonly accountId: string; /** Bumped on every successful save for this account; the unit a late 401 is scoped to. */ readonly generation: number; /** The scope the exchange actually granted, read back from the response. */ readonly scope: string | null; readonly createdAt: string; readonly needsReauth: boolean; readonly reauthReason: string | null; } interface CredentialFile { schema: 1; credentials: StoredOrcaCredential[]; } export declare function credentialStorePath(env?: NodeJS.ProcessEnv): string; /** * A key rendered safe to show. * * Keeps the scheme prefix and the last four characters, which is what makes two keys * distinguishable in a status line, and drops everything that identifies the credential. */ export declare function redactKey(key: string | null | undefined): string; /** * A cheap shape check, and nothing more. * * An `sk-orca-` prefix is not proof that a credential is valid, and this package has no * non-billing endpoint to prove it with, so validation is reported as unknown and the first real * request establishes it. Catching an obviously wrong paste is all this is for. */ export declare function looksLikeOrcaKey(value: string): boolean; /** Read the store. A missing or unreadable file is an empty store, never a thrown error. */ export declare function readCredentialFile(env?: NodeJS.ProcessEnv): Promise; export interface SaveCredentialInput { readonly source: OrcaCredentialSource; readonly key: string; readonly accountId?: string | null; readonly scope?: string | null; } export declare function saveCredential(input: SaveCredentialInput, env?: NodeJS.ProcessEnv): Promise; /** Remove every stored credential for a source. Used by "clear" and by explicit sign-out. */ export declare function clearCredentials(source?: OrcaCredentialSource | null, env?: NodeJS.ProcessEnv): Promise; /** * Which credential inference should use, and where it came from. * * Precedence is deliberate and documented to the user: an explicit `ORCAROUTER_API_KEY` in the * environment is an instruction from whoever configured the machine and wins over anything the * store holds. After that the most recently saved usable credential wins, regardless of which * adapter produced it -- downstream code never asks how a key was obtained. */ export interface ResolvedOrcaCredential { readonly key: string; readonly source: OrcaCredentialSource; readonly accountId: string; readonly generation: number; readonly scope: string | null; /** True when the key came from the environment and therefore cannot carry reauth state. */ readonly ephemeral: boolean; } export declare function resolveCredential(env?: NodeJS.ProcessEnv): Promise; export type ReauthOutcome = 'marked' | 'stale-generation' | 'unknown-account'; /** * Mark the exact credential that made a rejected request as needing reauthentication. * * THE GENERATION CHECK IS THE POINT. A request issued under generation 3 can fail after the user * has already reauthorized and generation 4 is stored. Flipping `needsReauth` there would take a * freshly working credential out of service, which is the failure mode this signature exists to * make impossible. */ export declare function markNeedsReauth(rejected: { accountId: string; generation: number; }, reason: string, env?: NodeJS.ProcessEnv): Promise; export {}; //# sourceMappingURL=credential-store.d.ts.map