@skrr-ai/auth-core 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -0
- package/dist/cjs/aead.d.ts +24 -0
- package/dist/cjs/aead.js +65 -0
- package/dist/cjs/authExpiredDetector.d.ts +65 -0
- package/dist/cjs/authExpiredDetector.js +89 -0
- package/dist/cjs/authHelper.d.ts +51 -0
- package/dist/cjs/authHelper.js +321 -0
- package/dist/cjs/credentialEnvelope.d.ts +85 -0
- package/dist/cjs/credentialEnvelope.js +230 -0
- package/dist/cjs/credentialEnvelopeBridge.d.ts +116 -0
- package/dist/cjs/credentialEnvelopeBridge.js +637 -0
- package/dist/cjs/credentialResolver.d.ts +278 -0
- package/dist/cjs/credentialResolver.js +423 -0
- package/dist/cjs/daemonPair.d.ts +172 -0
- package/dist/cjs/daemonPair.js +495 -0
- package/dist/cjs/daemonScopes.d.ts +74 -0
- package/dist/cjs/daemonScopes.js +84 -0
- package/dist/cjs/deviceIdentityBridge.d.ts +113 -0
- package/dist/cjs/deviceIdentityBridge.js +591 -0
- package/dist/cjs/deviceKey.d.ts +167 -0
- package/dist/cjs/deviceKey.js +332 -0
- package/dist/cjs/fdToken.d.ts +17 -0
- package/dist/cjs/fdToken.js +238 -0
- package/dist/cjs/harnessTrust.d.ts +72 -0
- package/dist/cjs/harnessTrust.js +103 -0
- package/dist/cjs/headers-helper.d.ts +25 -0
- package/dist/cjs/headers-helper.js +323 -0
- package/dist/cjs/index.d.ts +37 -0
- package/dist/cjs/index.js +305 -0
- package/dist/cjs/jwtUtils.d.ts +35 -0
- package/dist/cjs/jwtUtils.js +61 -0
- package/dist/cjs/kek/index.d.ts +89 -0
- package/dist/cjs/kek/index.js +208 -0
- package/dist/cjs/kek/linux.d.ts +92 -0
- package/dist/cjs/kek/linux.js +596 -0
- package/dist/cjs/kek/macos.d.ts +112 -0
- package/dist/cjs/kek/macos.js +599 -0
- package/dist/cjs/kek/types.d.ts +111 -0
- package/dist/cjs/kek/types.js +43 -0
- package/dist/cjs/kek/windows.d.ts +71 -0
- package/dist/cjs/kek/windows.js +350 -0
- package/dist/cjs/kek/zeroize-registry.d.ts +44 -0
- package/dist/cjs/kek/zeroize-registry.js +63 -0
- package/dist/cjs/legacyStatePreflight.d.ts +67 -0
- package/dist/cjs/legacyStatePreflight.js +78 -0
- package/dist/cjs/localIdentity.d.ts +54 -0
- package/dist/cjs/localIdentity.js +57 -0
- package/dist/cjs/loginLocalhost.d.ts +115 -0
- package/dist/cjs/loginLocalhost.js +368 -0
- package/dist/cjs/loginWithLocalhost.d.ts +131 -0
- package/dist/cjs/loginWithLocalhost.js +359 -0
- package/dist/cjs/machineId.d.ts +35 -0
- package/dist/cjs/machineId.js +239 -0
- package/dist/cjs/messages.d.ts +9 -0
- package/dist/cjs/messages.js +44 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/pkce.d.ts +62 -0
- package/dist/cjs/pkce.js +158 -0
- package/dist/cjs/recoveryCode.d.ts +61 -0
- package/dist/cjs/recoveryCode.js +213 -0
- package/dist/cjs/refresh.d.ts +215 -0
- package/dist/cjs/refresh.js +877 -0
- package/dist/cjs/refreshClassification.d.ts +53 -0
- package/dist/cjs/refreshClassification.js +105 -0
- package/dist/cjs/refreshScheduler.d.ts +53 -0
- package/dist/cjs/refreshScheduler.js +332 -0
- package/dist/cjs/runtime.d.ts +149 -0
- package/dist/cjs/runtime.js +136 -0
- package/dist/cjs/spawnEnv.d.ts +76 -0
- package/dist/cjs/spawnEnv.js +153 -0
- package/dist/cjs/ttlParser.d.ts +54 -0
- package/dist/cjs/ttlParser.js +87 -0
- package/dist/cjs/types.d.ts +91 -0
- package/dist/cjs/types.js +26 -0
- package/dist/esm/aead.d.ts +24 -0
- package/dist/esm/aead.js +57 -0
- package/dist/esm/authExpiredDetector.d.ts +65 -0
- package/dist/esm/authExpiredDetector.js +85 -0
- package/dist/esm/authHelper.d.ts +51 -0
- package/dist/esm/authHelper.js +311 -0
- package/dist/esm/credentialEnvelope.d.ts +85 -0
- package/dist/esm/credentialEnvelope.js +213 -0
- package/dist/esm/credentialEnvelopeBridge.d.ts +116 -0
- package/dist/esm/credentialEnvelopeBridge.js +620 -0
- package/dist/esm/credentialResolver.d.ts +278 -0
- package/dist/esm/credentialResolver.js +414 -0
- package/dist/esm/daemonPair.d.ts +172 -0
- package/dist/esm/daemonPair.js +476 -0
- package/dist/esm/daemonScopes.d.ts +74 -0
- package/dist/esm/daemonScopes.js +80 -0
- package/dist/esm/deviceIdentityBridge.d.ts +113 -0
- package/dist/esm/deviceIdentityBridge.js +572 -0
- package/dist/esm/deviceKey.d.ts +167 -0
- package/dist/esm/deviceKey.js +320 -0
- package/dist/esm/fdToken.d.ts +17 -0
- package/dist/esm/fdToken.js +231 -0
- package/dist/esm/harnessTrust.d.ts +72 -0
- package/dist/esm/harnessTrust.js +97 -0
- package/dist/esm/headers-helper.d.ts +25 -0
- package/dist/esm/headers-helper.js +316 -0
- package/dist/esm/index.d.ts +37 -0
- package/dist/esm/index.js +144 -0
- package/dist/esm/jwtUtils.d.ts +35 -0
- package/dist/esm/jwtUtils.js +57 -0
- package/dist/esm/kek/index.d.ts +89 -0
- package/dist/esm/kek/index.js +162 -0
- package/dist/esm/kek/linux.d.ts +92 -0
- package/dist/esm/kek/linux.js +585 -0
- package/dist/esm/kek/macos.d.ts +112 -0
- package/dist/esm/kek/macos.js +586 -0
- package/dist/esm/kek/types.d.ts +111 -0
- package/dist/esm/kek/types.js +39 -0
- package/dist/esm/kek/windows.d.ts +71 -0
- package/dist/esm/kek/windows.js +344 -0
- package/dist/esm/kek/zeroize-registry.d.ts +44 -0
- package/dist/esm/kek/zeroize-registry.js +58 -0
- package/dist/esm/legacyStatePreflight.d.ts +67 -0
- package/dist/esm/legacyStatePreflight.js +71 -0
- package/dist/esm/localIdentity.d.ts +54 -0
- package/dist/esm/localIdentity.js +54 -0
- package/dist/esm/loginLocalhost.d.ts +115 -0
- package/dist/esm/loginLocalhost.js +355 -0
- package/dist/esm/loginWithLocalhost.d.ts +131 -0
- package/dist/esm/loginWithLocalhost.js +353 -0
- package/dist/esm/machineId.d.ts +35 -0
- package/dist/esm/machineId.js +231 -0
- package/dist/esm/messages.d.ts +9 -0
- package/dist/esm/messages.js +40 -0
- package/dist/esm/pkce.d.ts +62 -0
- package/dist/esm/pkce.js +148 -0
- package/dist/esm/recoveryCode.d.ts +61 -0
- package/dist/esm/recoveryCode.js +207 -0
- package/dist/esm/refresh.d.ts +215 -0
- package/dist/esm/refresh.js +863 -0
- package/dist/esm/refreshClassification.d.ts +53 -0
- package/dist/esm/refreshClassification.js +106 -0
- package/dist/esm/refreshScheduler.d.ts +53 -0
- package/dist/esm/refreshScheduler.js +329 -0
- package/dist/esm/runtime.d.ts +149 -0
- package/dist/esm/runtime.js +121 -0
- package/dist/esm/spawnEnv.d.ts +76 -0
- package/dist/esm/spawnEnv.js +149 -0
- package/dist/esm/ttlParser.d.ts +54 -0
- package/dist/esm/ttlParser.js +83 -0
- package/dist/esm/types.d.ts +91 -0
- package/dist/esm/types.js +21 -0
- package/package.json +82 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* credentialResolver.ts — documented credential precedence for the
|
|
3
|
+
* OverSky daemon and CLI.
|
|
4
|
+
*
|
|
5
|
+
* Roadmap: docs/daemon-auth-roadmap.md, Phase H.
|
|
6
|
+
*
|
|
7
|
+
* The resolver walks a fixed, ordered list of credential sources and
|
|
8
|
+
* returns the first non-null token along with its source name. Source
|
|
9
|
+
* names are part of the public surface — they show up in
|
|
10
|
+
* `oversky doctor`, `oversky status`, and `sky whoami`, and operators
|
|
11
|
+
* use them to triage "where did this token come from?" tickets.
|
|
12
|
+
*
|
|
13
|
+
* Precedence (high → low):
|
|
14
|
+
*
|
|
15
|
+
* 1. flag — `--token <jwt>` CLI flag (debugging)
|
|
16
|
+
* 2. env-token — `OVERSKY_TOKEN` env (CI / static; Phase I adds
|
|
17
|
+
* server-side scope=ci validation)
|
|
18
|
+
* 3. auth-helper — `OVERSKY_AUTH_HELPER` script output (rotating
|
|
19
|
+
* creds — Vault, AWS SM, internal SSO proxy)
|
|
20
|
+
* 4. fd-handoff — `OVERSKY_AUTH_FD` parent→child IPC (Electron
|
|
21
|
+
* supervisor → daemon child). Internal; never
|
|
22
|
+
* user-configured.
|
|
23
|
+
* 5. keychain — macOS Keychain (`ai.skrr.daemon`)
|
|
24
|
+
* 6. file — `~/.skrr/auth.json` (0600)
|
|
25
|
+
* 7. interactive — Browser/device-code login (TTY only, blocked
|
|
26
|
+
* under launchd via `isHeadless()`)
|
|
27
|
+
*
|
|
28
|
+
* Skip rules (Phase H.2 + H.4):
|
|
29
|
+
* - `bareMode: true` skips slots 4–7 (no platform storage, no IPC,
|
|
30
|
+
* no interactive). Bare mode demands an explicit token from env or
|
|
31
|
+
* flag — designed for reproducible CI runs and "is the daemon
|
|
32
|
+
* broken or is my config corrupted?" triage.
|
|
33
|
+
* - `storeMode: 'env-only'` skips slots 5 + 6 (and the daemon
|
|
34
|
+
* wrapper additionally disables the auth-generation.json sidecar).
|
|
35
|
+
* - `storeMode: 'keychain'` skips slot 6 (file backend).
|
|
36
|
+
* - `storeMode: 'file'` skips slot 5 (keychain backend).
|
|
37
|
+
*
|
|
38
|
+
* Backend access uses dependency-injected callbacks
|
|
39
|
+
* (`readKeychainToken`, `readFileToken`, `runInteractiveLogin`) so this
|
|
40
|
+
* module stays free of OS-specific imports and the Sky CLI can wire its
|
|
41
|
+
* own backends without dragging the daemon's `keychain.ts` into
|
|
42
|
+
* non-daemon binaries.
|
|
43
|
+
*/
|
|
44
|
+
import { type AuthHelperFailureReason } from './authHelper.js';
|
|
45
|
+
export type CredentialSource = 'flag' | 'env-token' | 'auth-helper' | 'fd-handoff' | 'keychain' | 'file' | 'interactive' | 'none';
|
|
46
|
+
/**
|
|
47
|
+
* Ordered slots tried by `CredentialResolver.resolve()`. Excludes
|
|
48
|
+
* `'none'` (only emitted when no slot produced a token). Treat this as
|
|
49
|
+
* the canonical published precedence — flipping the order is a public
|
|
50
|
+
* API change and breaks operator runbooks.
|
|
51
|
+
*/
|
|
52
|
+
export declare const CREDENTIAL_PRECEDENCE: readonly ["flag", "env-token", "auth-helper", "fd-handoff", "keychain", "file", "interactive"];
|
|
53
|
+
export type CredentialStoreMode = 'auto' | 'keychain' | 'file' | 'env-only';
|
|
54
|
+
export interface CredentialResolverOptions {
|
|
55
|
+
/** `--token <jwt>` flag value, when present on the CLI. */
|
|
56
|
+
flagToken?: string;
|
|
57
|
+
/** `--bare` mode (or `OVERSKY_BARE_MODE=1`): skips slots 4–7. */
|
|
58
|
+
bareMode?: boolean;
|
|
59
|
+
/** `config.credentials.store` value; defaults to 'auto'. */
|
|
60
|
+
storeMode?: CredentialStoreMode;
|
|
61
|
+
/**
|
|
62
|
+
* Test/explicit override for `OVERSKY_TOKEN`. Pass `undefined` to read
|
|
63
|
+
* from `process.env`; pass `null` to force-skip the slot; pass a
|
|
64
|
+
* string to use that value directly.
|
|
65
|
+
*/
|
|
66
|
+
envTokenOverride?: string | null;
|
|
67
|
+
/** Test/explicit override for `OVERSKY_AUTH_HELPER` env. Same semantics. */
|
|
68
|
+
authHelperPathOverride?: string | null;
|
|
69
|
+
/**
|
|
70
|
+
* Predicate consulted before invoking the interactive slot. The daemon
|
|
71
|
+
* wires `isHeadlessDaemon()`; the CLI may wire its own check.
|
|
72
|
+
*/
|
|
73
|
+
isHeadless?: () => boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Read the keychain backend. Returns the token string or null. The
|
|
76
|
+
* daemon wraps `keychain.readToken()` (and handles `resetAvailability`
|
|
77
|
+
* on misses) inside this callback.
|
|
78
|
+
*/
|
|
79
|
+
readKeychainToken?: () => string | null;
|
|
80
|
+
/** Read the file backend (`~/.skrr/auth.json`). */
|
|
81
|
+
readFileToken?: () => string | null;
|
|
82
|
+
/** Trigger interactive login; returns the new token or null. */
|
|
83
|
+
runInteractiveLogin?: () => Promise<string | null>;
|
|
84
|
+
/**
|
|
85
|
+
* L6.1 — workspace-trust gate for `OVERSKY_AUTH_HELPER`.
|
|
86
|
+
*
|
|
87
|
+
* Called BEFORE the helper is invoked. The daemon wires this to the
|
|
88
|
+
* `daemon/src/permissions/workspace-trust.ts` checker; tests can pass a
|
|
89
|
+
* stub directly. When this returns `{trusted: false, ...}` for a
|
|
90
|
+
* project- or local-scope helper, the resolver:
|
|
91
|
+
* 1. Logs an `auth_helper_blocked_untrusted` event via
|
|
92
|
+
* `onAuthHelperBlocked` if wired.
|
|
93
|
+
* 2. Fails CLOSED — returns a `{token: null, source: 'auth-helper'}`
|
|
94
|
+
* record with `failClosed: true` so the chain does NOT fall
|
|
95
|
+
* through to OAuth. (See L6.1 spec point 4.)
|
|
96
|
+
*
|
|
97
|
+
* Absent → no trust check is performed (backward-compat for the CLI
|
|
98
|
+
* and tests that don't care about workspace-trust). Production daemon
|
|
99
|
+
* MUST wire this.
|
|
100
|
+
*/
|
|
101
|
+
helperTrustGate?: (helperPath: string, fromEnvVar: boolean) => HelperTrustDecision;
|
|
102
|
+
/**
|
|
103
|
+
* Audit hook fired when `helperTrustGate` blocks the helper. Daemon
|
|
104
|
+
* wires this to the event-log so security-sensitive denials are
|
|
105
|
+
* persisted alongside other auth events.
|
|
106
|
+
*/
|
|
107
|
+
onAuthHelperBlocked?: (info: AuthHelperBlockedInfo) => void;
|
|
108
|
+
/**
|
|
109
|
+
* Audit hook fired when L6.3 returns the cold-cache failure sentinel.
|
|
110
|
+
* Useful for surfacing "your helper is broken" without spamming the
|
|
111
|
+
* event-log on every read within the TTL.
|
|
112
|
+
*/
|
|
113
|
+
onAuthHelperSentinelHit?: (info: AuthHelperSentinelInfo) => void;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* L6.1 — return value of the workspace-trust callback.
|
|
117
|
+
*/
|
|
118
|
+
export interface HelperTrustDecision {
|
|
119
|
+
trusted: boolean;
|
|
120
|
+
origin: 'user' | 'project' | 'local';
|
|
121
|
+
reason?: 'no-record' | 'helper-changed';
|
|
122
|
+
}
|
|
123
|
+
export interface AuthHelperBlockedInfo {
|
|
124
|
+
helperPath: string;
|
|
125
|
+
origin: 'user' | 'project' | 'local';
|
|
126
|
+
reason: 'no-record' | 'helper-changed';
|
|
127
|
+
cwd: string;
|
|
128
|
+
}
|
|
129
|
+
export interface AuthHelperSentinelInfo {
|
|
130
|
+
helperPath: string;
|
|
131
|
+
reason: AuthHelperFailureReason;
|
|
132
|
+
cachedAt: number;
|
|
133
|
+
ttlMs: number;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Token kind discriminator (Phase I).
|
|
137
|
+
*
|
|
138
|
+
* - 'standard' — anything that should be treated as a JWT (the default
|
|
139
|
+
* daemon device-code-issued access token, refresh-derived
|
|
140
|
+
* rotations, the user's CLI session token, etc.).
|
|
141
|
+
* - 'ci' — long-lived CI token with the `osk_ci_` prefix. The
|
|
142
|
+
* daemon uses this for the bootstrap-to-daemon-JWT flow
|
|
143
|
+
* (POST /api/daemons/token), MUST NOT schedule refresh,
|
|
144
|
+
* and on auth failure exits 75 with a CI-specific error
|
|
145
|
+
* rather than writing needs-reauth.json.
|
|
146
|
+
* - 'install' — short-lived web-minted JWT with `scope=daemon-install`.
|
|
147
|
+
* The daemon exchanges it through the same /api/daemons/token
|
|
148
|
+
* bootstrap path, persists only the returned daemon
|
|
149
|
+
* credential, and never treats the install JWT as a normal
|
|
150
|
+
* session token.
|
|
151
|
+
*
|
|
152
|
+
* Detection is local-only; no server round-trip. The JWT payload read is
|
|
153
|
+
* intentionally signature-less and is only used to select the client
|
|
154
|
+
* bootstrap path. The server remains the authority when the token is
|
|
155
|
+
* exchanged at /api/daemons/token.
|
|
156
|
+
*
|
|
157
|
+
* The kill switch `OVERSKY_DISABLE_CI_TOKEN_RESOLVER=1` forces every token to
|
|
158
|
+
* `'standard'` for triage purposes.
|
|
159
|
+
*/
|
|
160
|
+
export type TokenKind = 'standard' | 'ci' | 'install';
|
|
161
|
+
/** CI-token plaintext prefix; mirrors api/server/services/Auth/daemonCiTokens.js. */
|
|
162
|
+
export declare const CI_TOKEN_PREFIX = "osk_ci_";
|
|
163
|
+
/**
|
|
164
|
+
* Classify a token by local shape. Pure function; safe to call on any string
|
|
165
|
+
* (including `null`-coerced empty). Returns `'standard'` for empty input
|
|
166
|
+
* so callers don't need to null-check before classification.
|
|
167
|
+
*
|
|
168
|
+
* Honors `OVERSKY_DISABLE_CI_TOKEN_RESOLVER=1` kill switch — when set,
|
|
169
|
+
* everything classifies as `'standard'` so the resolver can be used as
|
|
170
|
+
* a triage tool ("is the CI-token path the problem?").
|
|
171
|
+
*/
|
|
172
|
+
/**
|
|
173
|
+
* SECURITY NOTE — this reads `scope` out of an UNVERIFIED JWT payload.
|
|
174
|
+
*
|
|
175
|
+
* That is safe here, and stays safe only under one condition: the return value
|
|
176
|
+
* selects a local code path and nothing else. `'install'` means "refresh this
|
|
177
|
+
* the install-token way"; it grants no capability, skips no check, and asserts
|
|
178
|
+
* no identity. The server still validates the token on every request, so a
|
|
179
|
+
* forged `scope: daemon-install` buys an attacker a different local branch and
|
|
180
|
+
* the same 401.
|
|
181
|
+
*
|
|
182
|
+
* The forgery is trivial — no signature is checked, so anyone who can write the
|
|
183
|
+
* credential file or set the env var can put any claim in it. That is fine
|
|
184
|
+
* while the only consequence is routing. It stops being fine the moment a
|
|
185
|
+
* caller treats `TokenKind` as a permission. Do not let this value gate a
|
|
186
|
+
* capability, and do not add a branch here that returns a kind meaning "more
|
|
187
|
+
* privileged".
|
|
188
|
+
*
|
|
189
|
+
* See `jwtUtils.ts` for the general rule.
|
|
190
|
+
*/
|
|
191
|
+
export declare function classifyTokenKind(token: string | null | undefined): TokenKind;
|
|
192
|
+
export interface ResolvedCredential {
|
|
193
|
+
token: string | null;
|
|
194
|
+
source: CredentialSource;
|
|
195
|
+
/**
|
|
196
|
+
* Phase I — discriminator the daemon uses to branch on refresh
|
|
197
|
+
* scheduling, needs-reauth handling, and the bootstrap-to-daemon-JWT
|
|
198
|
+
* flow. Always `'standard'` when `token` is null.
|
|
199
|
+
*/
|
|
200
|
+
kind: TokenKind;
|
|
201
|
+
}
|
|
202
|
+
/** @internal test-only — drop the helper cache between tests. */
|
|
203
|
+
export declare function __resetCredentialResolverForTest(): void;
|
|
204
|
+
/**
|
|
205
|
+
* L6.3 — typed error thrown when the cold-cache failure sentinel is in
|
|
206
|
+
* effect. Callers (daemon refresh path, CLI) can catch this specifically
|
|
207
|
+
* to render "auth helper unavailable: <reason>" without falling through
|
|
208
|
+
* to OAuth or device-code retry.
|
|
209
|
+
*/
|
|
210
|
+
export declare class AuthHelperUnavailableError extends Error {
|
|
211
|
+
readonly reason: AuthHelperFailureReason;
|
|
212
|
+
readonly cachedAt: number;
|
|
213
|
+
constructor(reason: AuthHelperFailureReason, cachedAt: number);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* L6.1 — typed error thrown when the workspace-trust gate blocks a
|
|
217
|
+
* project- or local-scope helper. Surfaces the actionable next step
|
|
218
|
+
* (`oversky trust accept`) to the user; the daemon catches and presents
|
|
219
|
+
* this without falling through to OAuth.
|
|
220
|
+
*/
|
|
221
|
+
export declare class AuthHelperUntrustedError extends Error {
|
|
222
|
+
readonly origin: 'user' | 'project' | 'local';
|
|
223
|
+
readonly reason: 'no-record' | 'helper-changed';
|
|
224
|
+
readonly helperPath: string;
|
|
225
|
+
constructor(helperPath: string, origin: 'user' | 'project' | 'local', reason: 'no-record' | 'helper-changed');
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* H3-6 — public invalidation seam for the `OVERSKY_AUTH_HELPER` result
|
|
229
|
+
* cache. 401 handlers call this right after receiving a 401 from the
|
|
230
|
+
* server so the NEXT credential resolve re-invokes the helper to mint
|
|
231
|
+
* a fresh token instead of serving the stale (cached) one for up to
|
|
232
|
+
* `OVERSKY_AUTH_HELPER_TTL_MS`.
|
|
233
|
+
*
|
|
234
|
+
* Without this seam, a rotated secret at the helper's source (Vault,
|
|
235
|
+
* AWS Secrets Manager, etc.) could take up to 5 minutes to propagate
|
|
236
|
+
* to OverSky even when the server is actively rejecting the old
|
|
237
|
+
* value. The helper is the only slot in the precedence chain that
|
|
238
|
+
* naturally caches; keychain/file reads are already one-shot per
|
|
239
|
+
* resolve.
|
|
240
|
+
*
|
|
241
|
+
* L6.3 — also clears the cold-cache failure sentinel. A 401 means the
|
|
242
|
+
* server is rejecting whatever we sent, which usually means the helper
|
|
243
|
+
* needs to retry from scratch — even when the LAST helper attempt
|
|
244
|
+
* failed and seeded the sentinel. Without this, a transient helper
|
|
245
|
+
* failure during the same TTL window as a server-issued 401 would lock
|
|
246
|
+
* the daemon out for the full TTL.
|
|
247
|
+
*
|
|
248
|
+
* Idempotent: calling this on an already-empty cache is a no-op.
|
|
249
|
+
*/
|
|
250
|
+
export declare function invalidateAuthHelperCache(): void;
|
|
251
|
+
export declare class CredentialResolver {
|
|
252
|
+
private readonly opts;
|
|
253
|
+
constructor(opts?: CredentialResolverOptions);
|
|
254
|
+
/**
|
|
255
|
+
* Walk the precedence chain and return the first non-null token.
|
|
256
|
+
* Returns `{ token: null, source: 'none' }` when nothing matches.
|
|
257
|
+
*
|
|
258
|
+
* Fail-closed exceptions from the auth-helper slot
|
|
259
|
+
* (`AuthHelperUntrustedError`, `AuthHelperUnavailableError`) propagate
|
|
260
|
+
* out — they intentionally PREVENT fall-through to OAuth. Callers
|
|
261
|
+
* that want soft-fall-through behavior must catch explicitly. See
|
|
262
|
+
* L6.1 spec point 4 and L6.3.
|
|
263
|
+
*/
|
|
264
|
+
resolve(): Promise<ResolvedCredential>;
|
|
265
|
+
/**
|
|
266
|
+
* Test seam: invoke a single slot in isolation. Production code should
|
|
267
|
+
* always go through `resolve()` so the chain ordering is enforced.
|
|
268
|
+
*/
|
|
269
|
+
tryResolveSlot(source: Exclude<CredentialSource, 'none'>): Promise<string | null>;
|
|
270
|
+
private shouldSkip;
|
|
271
|
+
private tryResolveFlag;
|
|
272
|
+
private tryResolveEnvToken;
|
|
273
|
+
private tryResolveAuthHelper;
|
|
274
|
+
private tryResolveFdHandoff;
|
|
275
|
+
private tryResolveKeychain;
|
|
276
|
+
private tryResolveFile;
|
|
277
|
+
private tryResolveInteractive;
|
|
278
|
+
}
|