@centient/secrets 0.9.0 → 0.10.0
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 +70 -2
- package/dist/cli/secrets-cli.d.ts.map +1 -1
- package/dist/cli/secrets-cli.js +191 -32
- package/dist/cli/secrets-cli.js.map +1 -1
- package/dist/crypto/darwin-keychain.d.ts +394 -0
- package/dist/crypto/darwin-keychain.d.ts.map +1 -0
- package/dist/crypto/darwin-keychain.js +793 -0
- package/dist/crypto/darwin-keychain.js.map +1 -0
- package/dist/crypto/vault-common.d.ts +55 -12
- package/dist/crypto/vault-common.d.ts.map +1 -1
- package/dist/crypto/vault-common.js +74 -71
- package/dist/crypto/vault-common.js.map +1 -1
- package/dist/environment/EnvironmentManager.d.ts.map +1 -1
- package/dist/environment/EnvironmentManager.js +5 -10
- package/dist/environment/EnvironmentManager.js.map +1 -1
- package/dist/index.d.ts +20 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +23 -5
- package/dist/index.js.map +1 -1
- package/dist/key-providers/keychain-provider.d.ts +30 -2
- package/dist/key-providers/keychain-provider.d.ts.map +1 -1
- package/dist/key-providers/keychain-provider.js +29 -5
- package/dist/key-providers/keychain-provider.js.map +1 -1
- package/dist/key-providers/onepassword-provider.d.ts +65 -5
- package/dist/key-providers/onepassword-provider.d.ts.map +1 -1
- package/dist/key-providers/onepassword-provider.js +159 -67
- package/dist/key-providers/onepassword-provider.js.map +1 -1
- package/dist/key-providers/op-cli.d.ts +78 -0
- package/dist/key-providers/op-cli.d.ts.map +1 -0
- package/dist/key-providers/op-cli.js +123 -0
- package/dist/key-providers/op-cli.js.map +1 -0
- package/dist/key-providers/passphrase-provider.d.ts +20 -0
- package/dist/key-providers/passphrase-provider.d.ts.map +1 -1
- package/dist/key-providers/passphrase-provider.js +49 -0
- package/dist/key-providers/passphrase-provider.js.map +1 -1
- package/dist/key-providers/probe.d.ts +46 -0
- package/dist/key-providers/probe.d.ts.map +1 -0
- package/dist/key-providers/probe.js +70 -0
- package/dist/key-providers/probe.js.map +1 -0
- package/dist/key-providers/types.d.ts +51 -1
- package/dist/key-providers/types.d.ts.map +1 -1
- package/dist/platform/agent-detect.d.ts +39 -3
- package/dist/platform/agent-detect.d.ts.map +1 -1
- package/dist/platform/agent-detect.js +55 -9
- package/dist/platform/agent-detect.js.map +1 -1
- package/dist/platform/session-context.d.ts +77 -0
- package/dist/platform/session-context.d.ts.map +1 -0
- package/dist/platform/session-context.js +83 -0
- package/dist/platform/session-context.js.map +1 -0
- package/dist/secret-state.d.ts +54 -0
- package/dist/secret-state.d.ts.map +1 -0
- package/dist/secret-state.js +2 -0
- package/dist/secret-state.js.map +1 -0
- package/dist/vault/session-vault-errors.d.ts +72 -4
- package/dist/vault/session-vault-errors.d.ts.map +1 -1
- package/dist/vault/session-vault-errors.js +95 -4
- package/dist/vault/session-vault-errors.js.map +1 -1
- package/dist/vault/session-vault.d.ts +102 -2
- package/dist/vault/session-vault.d.ts.map +1 -1
- package/dist/vault/session-vault.js +225 -36
- package/dist/vault/session-vault.js.map +1 -1
- package/dist/vault/types.d.ts +42 -1
- package/dist/vault/types.d.ts.map +1 -1
- package/dist/vault/types.js.map +1 -1
- package/dist/vault/vault-env.d.ts +14 -0
- package/dist/vault/vault-env.d.ts.map +1 -1
- package/dist/vault/vault-env.js +15 -0
- package/dist/vault/vault-env.js.map +1 -1
- package/dist/vault/vault-gpg.d.ts +5 -1
- package/dist/vault/vault-gpg.d.ts.map +1 -1
- package/dist/vault/vault-gpg.js +9 -8
- package/dist/vault/vault-gpg.js.map +1 -1
- package/dist/vault/vault-libsecret.d.ts +5 -1
- package/dist/vault/vault-libsecret.d.ts.map +1 -1
- package/dist/vault/vault-libsecret.js +9 -8
- package/dist/vault/vault-libsecret.js.map +1 -1
- package/dist/vault/vault-onepassword.d.ts +118 -0
- package/dist/vault/vault-onepassword.d.ts.map +1 -0
- package/dist/vault/vault-onepassword.js +270 -0
- package/dist/vault/vault-onepassword.js.map +1 -0
- package/dist/vault/vault-utils.d.ts +33 -0
- package/dist/vault/vault-utils.d.ts.map +1 -1
- package/dist/vault/vault-utils.js +61 -0
- package/dist/vault/vault-utils.js.map +1 -1
- package/dist/vault/vault-windows.d.ts +5 -1
- package/dist/vault/vault-windows.d.ts.map +1 -1
- package/dist/vault/vault-windows.js +9 -8
- package/dist/vault/vault-windows.js.map +1 -1
- package/dist/vault/vault.d.ts +116 -4
- package/dist/vault/vault.d.ts.map +1 -1
- package/dist/vault/vault.js +251 -12
- package/dist/vault/vault.js.map +1 -1
- package/package.json +1 -1
|
@@ -12,11 +12,15 @@
|
|
|
12
12
|
* Storage: credentials are stored in the Windows Credential Manager under the
|
|
13
13
|
* resource name "centient", with the logical key as the username.
|
|
14
14
|
*
|
|
15
|
-
* Error handling:
|
|
15
|
+
* Error handling: a storage failure returns false/null — this backend never
|
|
16
|
+
* throws for that. A credential key that violates the shared key grammar is
|
|
17
|
+
* NOT a storage failure and throws `InvalidCredentialKeyError` (#168): such a
|
|
18
|
+
* key is unaddressable here, and reporting it as a failed write or an absent
|
|
19
|
+
* credential would be indistinguishable from the ordinary miss.
|
|
16
20
|
*/
|
|
17
21
|
import { spawnSync } from "child_process";
|
|
18
22
|
import { readFileSync } from "fs";
|
|
19
|
-
import {
|
|
23
|
+
import { assertValidKey } from "./vault-utils.js";
|
|
20
24
|
// =============================================================================
|
|
21
25
|
// Constants
|
|
22
26
|
// =============================================================================
|
|
@@ -118,8 +122,7 @@ export class WindowsVault {
|
|
|
118
122
|
* @returns true on success, false if storage fails
|
|
119
123
|
*/
|
|
120
124
|
store(key, value) {
|
|
121
|
-
|
|
122
|
-
return false;
|
|
125
|
+
assertValidKey(key, "write");
|
|
123
126
|
const escapedKey = escapePsValue(key);
|
|
124
127
|
const escapedValue = escapePsValue(value);
|
|
125
128
|
const command = [
|
|
@@ -140,8 +143,7 @@ export class WindowsVault {
|
|
|
140
143
|
* @returns The stored password, or null if not found / retrieval fails
|
|
141
144
|
*/
|
|
142
145
|
retrieve(key) {
|
|
143
|
-
|
|
144
|
-
return null;
|
|
146
|
+
assertValidKey(key, "read");
|
|
145
147
|
const escapedKey = escapePsValue(key);
|
|
146
148
|
const command = [
|
|
147
149
|
"& {",
|
|
@@ -164,8 +166,7 @@ export class WindowsVault {
|
|
|
164
166
|
* @returns true on success (including "not found"), false on unexpected error
|
|
165
167
|
*/
|
|
166
168
|
delete(key) {
|
|
167
|
-
|
|
168
|
-
return false;
|
|
169
|
+
assertValidKey(key, "delete");
|
|
169
170
|
const escapedKey = escapePsValue(key);
|
|
170
171
|
const command = [
|
|
171
172
|
"& {",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-windows.js","sourceRoot":"","sources":["../../src/vault/vault-windows.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vault-windows.js","sourceRoot":"","sources":["../../src/vault/vault-windows.ts"],"names":[],"mappings":"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"}
|
package/dist/vault/vault.d.ts
CHANGED
|
@@ -11,11 +11,69 @@
|
|
|
11
11
|
* The active backend is selected once at module load by calling each backend's
|
|
12
12
|
* static `detect()` method in order and choosing the first one that returns true.
|
|
13
13
|
*
|
|
14
|
+
* **Explicit selection (ADR-004) sits in front of that cascade.** `secrets.backend`
|
|
15
|
+
* (or `CENTIENT_SECRETS_BACKEND`) names a backend directly and fails closed if it
|
|
16
|
+
* is unusable — it is never silently substituted. `OnePasswordVault` is reachable
|
|
17
|
+
* *only* this way: having `op` installed is not consent to route credentials into
|
|
18
|
+
* someone's 1Password vault.
|
|
19
|
+
*
|
|
14
20
|
* Session TTL: 4 hours from the last successful read/write.
|
|
15
21
|
*
|
|
16
|
-
* Error handling:
|
|
22
|
+
* Error handling: a *storage* failure is reported as `null`/`false` — the
|
|
23
|
+
* backend contract is non-throwing. Three things do throw, because they are
|
|
24
|
+
* not storage outcomes: a policy `before` hook rejecting the operation
|
|
25
|
+
* (ADR-002 §1.0.0), a backend surfacing an unexpected transport failure from
|
|
26
|
+
* `retrieve`/`listKeys`, and a malformed credential key
|
|
27
|
+
* (`InvalidCredentialKeyError`, see the key-validation section below).
|
|
28
|
+
*/
|
|
29
|
+
import type { KeychainDeps } from "../crypto/darwin-keychain.js";
|
|
30
|
+
import type { SecretState } from "../secret-state.js";
|
|
31
|
+
import type { VaultBackend, VaultType } from "./types.js";
|
|
32
|
+
/**
|
|
33
|
+
* The keychain service every credential VALUE lives under. Exported because
|
|
34
|
+
* the migration helper (`migrateLoginCredentialToSystem`) and operator
|
|
35
|
+
* tooling have to name the same service — a second literal somewhere else is
|
|
36
|
+
* how a migration silently moves nothing.
|
|
17
37
|
*/
|
|
18
|
-
|
|
38
|
+
export declare const AUTH_KEYCHAIN_SERVICE = "centient-auth";
|
|
39
|
+
/**
|
|
40
|
+
* Wraps the macOS Keychain helper functions as a VaultBackend.
|
|
41
|
+
*
|
|
42
|
+
* Every method routes through `crypto/darwin-keychain.ts` (#188), so credential
|
|
43
|
+
* values inherit explicit System-keychain reads in a sessionless context,
|
|
44
|
+
* `-U` replace-in-place writes and `-T /usr/bin/security` reader
|
|
45
|
+
* preauthorization — the same posture the KeyProvider layer gets for the vault
|
|
46
|
+
* master key.
|
|
47
|
+
*
|
|
48
|
+
* Only available on macOS (darwin).
|
|
49
|
+
*/
|
|
50
|
+
export declare class KeychainVault implements VaultBackend {
|
|
51
|
+
private readonly deps;
|
|
52
|
+
/**
|
|
53
|
+
* @param deps - Injection seam for the `security` CLI and the
|
|
54
|
+
* platform/environment that decide the read path. Omitted in production;
|
|
55
|
+
* supplied by tests so the exact argv is assertable.
|
|
56
|
+
*/
|
|
57
|
+
constructor(deps?: Partial<KeychainDeps>);
|
|
58
|
+
static detect(): boolean;
|
|
59
|
+
store(key: string, value: string): boolean;
|
|
60
|
+
retrieve(key: string): string | null;
|
|
61
|
+
delete(key: string): boolean;
|
|
62
|
+
listKeys(prefix?: string): Promise<string[]>;
|
|
63
|
+
/**
|
|
64
|
+
* The credential state probe: runs the SAME read {@link retrieve} would run
|
|
65
|
+
* in this context — same path, same explicit target — then discards the
|
|
66
|
+
* value and returns only the value-free {@link SecretState}.
|
|
67
|
+
*
|
|
68
|
+
* A metadata-only lookup would be cheaper and would leave the secret on
|
|
69
|
+
* disk, but it can only report presence: an item whose ACL does not
|
|
70
|
+
* preauthorize the reader, or that sits in a locked keychain, is present and
|
|
71
|
+
* unreadable, and calling that `found` hands a caller trusted state that is
|
|
72
|
+
* wrong in exactly the direction #188 exists to fix. `found` here means the
|
|
73
|
+
* reader will get bytes.
|
|
74
|
+
*/
|
|
75
|
+
probe(key: string): SecretState;
|
|
76
|
+
}
|
|
19
77
|
/**
|
|
20
78
|
* Returns true if the in-process session is still within the TTL window.
|
|
21
79
|
* This does NOT validate the token itself — use validateToken() for that.
|
|
@@ -31,9 +89,12 @@ export declare function getActiveVaultType(): VaultType;
|
|
|
31
89
|
/**
|
|
32
90
|
* Store a credential in the active vault backend.
|
|
33
91
|
*
|
|
34
|
-
* @param key - Logical key name (e.g. 'auth-token', 'refresh-token')
|
|
92
|
+
* @param key - Logical key name (e.g. 'auth-token', 'refresh-token').
|
|
93
|
+
* Must match the key grammar — see "Key validation" above.
|
|
35
94
|
* @param value - The credential value to store
|
|
36
95
|
* @returns true on success, false if the backend write fails
|
|
96
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
97
|
+
* Nothing is written and no backend is contacted.
|
|
37
98
|
*/
|
|
38
99
|
export declare function storeCredential(key: string, value: string): Promise<boolean>;
|
|
39
100
|
/**
|
|
@@ -41,6 +102,10 @@ export declare function storeCredential(key: string, value: string): Promise<boo
|
|
|
41
102
|
*
|
|
42
103
|
* @param key - Logical key name (e.g. 'auth-token')
|
|
43
104
|
* @returns The stored value, or null if not found / backend unavailable
|
|
105
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
106
|
+
* Deliberately not `null`: "malformed" and "not stored" are different
|
|
107
|
+
* answers, and returning the not-found shape for the first is the silent
|
|
108
|
+
* degradation this path used to have.
|
|
44
109
|
*/
|
|
45
110
|
export declare function getCredential(key: string): Promise<string | null>;
|
|
46
111
|
/**
|
|
@@ -48,6 +113,9 @@ export declare function getCredential(key: string): Promise<string | null>;
|
|
|
48
113
|
*
|
|
49
114
|
* @param key - Logical key name (e.g. 'auth-token')
|
|
50
115
|
* @returns true on success (including "already deleted"), false on unexpected error
|
|
116
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
117
|
+
* Not reported as an idempotent success: such a key was never storable, so
|
|
118
|
+
* "already deleted" would be a claim the vault cannot make.
|
|
51
119
|
*/
|
|
52
120
|
export declare function deleteCredential(key: string): Promise<boolean>;
|
|
53
121
|
/**
|
|
@@ -64,7 +132,15 @@ export declare function deleteCredential(key: string): Promise<boolean>;
|
|
|
64
132
|
* Note: credential keys must match `isValidKey` — lowercase alphanumeric
|
|
65
133
|
* plus hyphen and dot, first and last character alphanumeric, <=64 chars.
|
|
66
134
|
* Both `-` and `.` work as namespace separators; pick whichever convention
|
|
67
|
-
* reads best.
|
|
135
|
+
* reads best. **This is enforced, not merely documented** (#168): every
|
|
136
|
+
* function on this path rejects a non-conforming key before dispatching.
|
|
137
|
+
*
|
|
138
|
+
* A `prefix` is checked against `isValidKeyPrefix` rather than `isValidKey`,
|
|
139
|
+
* so it may end on a separator — `"soma.anthropic."` is the intended way to
|
|
140
|
+
* scope an enumeration to a namespace, and is not itself a valid key.
|
|
141
|
+
*
|
|
142
|
+
* @throws {InvalidCredentialKeyError} if `prefix` could not be the leading
|
|
143
|
+
* substring of any valid key.
|
|
68
144
|
*
|
|
69
145
|
* @example
|
|
70
146
|
* // Enumerate all soma-owned Anthropic credentials
|
|
@@ -75,4 +151,40 @@ export declare function deleteCredential(key: string): Promise<boolean>;
|
|
|
75
151
|
* }
|
|
76
152
|
*/
|
|
77
153
|
export declare function listCredentials(prefix?: string): Promise<string[]>;
|
|
154
|
+
/** A value-free answer about one credential in one backend. */
|
|
155
|
+
export interface BackendStateProbe {
|
|
156
|
+
/** Always `"value"` — distinguishes this from the key-layer probe. */
|
|
157
|
+
layer: "value";
|
|
158
|
+
/** Which backend answered. */
|
|
159
|
+
backend: VaultType;
|
|
160
|
+
state: SecretState;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Probe one credential's state in a specific backend.
|
|
164
|
+
*
|
|
165
|
+
* Backends that implement `probe()` answer directly. For the rest this falls
|
|
166
|
+
* back to a `retrieve()`-based mapping — the value is discarded immediately
|
|
167
|
+
* and never returned — which yields `found`/`absent` honestly and `failed`
|
|
168
|
+
* when the backend threw. It never invents `locked`, because a backend that
|
|
169
|
+
* did not report one cannot be assumed to have one, and it never converts a
|
|
170
|
+
* throw into `absent`.
|
|
171
|
+
*
|
|
172
|
+
* Both paths answer readability, not mere presence: the fallback runs the real
|
|
173
|
+
* `retrieve()`, and an implementing backend is required to exercise the same
|
|
174
|
+
* access path it would for a read (see `VaultBackend.probe`). `found`
|
|
175
|
+
* therefore means the reader will get bytes.
|
|
176
|
+
*
|
|
177
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar —
|
|
178
|
+
* the same rule every other vault entry point enforces (#168). Policy hooks
|
|
179
|
+
* are deliberately NOT run: a probe reads no value, so there is nothing for
|
|
180
|
+
* an access-control hook to allow or deny.
|
|
181
|
+
*/
|
|
182
|
+
export declare function probeVaultBackendState(backend: VaultBackend, type: VaultType, key: string): Promise<BackendStateProbe>;
|
|
183
|
+
/**
|
|
184
|
+
* Probe one credential's state in the backend this process actually uses.
|
|
185
|
+
*
|
|
186
|
+
* The value-layer half of the two-layer probe; see `probeKeyProviderState()`
|
|
187
|
+
* for the vault master key.
|
|
188
|
+
*/
|
|
189
|
+
export declare function probeBackendState(key: string): Promise<BackendStateProbe>;
|
|
78
190
|
//# sourceMappingURL=vault.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"vault.d.ts","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AASH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAMtD,OAAO,KAAK,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAe1D;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,kBAAkB,CAAC;AAOrD;;;;;;;;;;GAUG;AACH,qBAAa,aAAc,YAAW,YAAY;IAMpC,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC;;;;OAIG;gBAC0B,IAAI,GAAE,OAAO,CAAC,YAAY,CAAM;IAE7D,MAAM,CAAC,MAAM,IAAI,OAAO;IAIxB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO;IAI1C,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAIpC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAItB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAIlD;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW;CAGhC;AAmFD;;;GAGG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAGxC;AAoFD;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,SAAS,CAE9C;AAED;;;;;;;;;GASG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAED;;;;;;;;;GASG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAkCvE;AAED;;;;;;;;GAQG;AACH,wBAAsB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAoBpE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,eAAe,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAmCxE;AAuBD,+DAA+D;AAC/D,MAAM,WAAW,iBAAiB;IAChC,sEAAsE;IACtE,KAAK,EAAE,OAAO,CAAC;IACf,8BAA8B;IAC9B,OAAO,EAAE,SAAS,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE,SAAS,EACf,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,iBAAiB,CAAC,CAiC5B;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAE/E"}
|
package/dist/vault/vault.js
CHANGED
|
@@ -11,53 +11,152 @@
|
|
|
11
11
|
* The active backend is selected once at module load by calling each backend's
|
|
12
12
|
* static `detect()` method in order and choosing the first one that returns true.
|
|
13
13
|
*
|
|
14
|
+
* **Explicit selection (ADR-004) sits in front of that cascade.** `secrets.backend`
|
|
15
|
+
* (or `CENTIENT_SECRETS_BACKEND`) names a backend directly and fails closed if it
|
|
16
|
+
* is unusable — it is never silently substituted. `OnePasswordVault` is reachable
|
|
17
|
+
* *only* this way: having `op` installed is not consent to route credentials into
|
|
18
|
+
* someone's 1Password vault.
|
|
19
|
+
*
|
|
14
20
|
* Session TTL: 4 hours from the last successful read/write.
|
|
15
21
|
*
|
|
16
|
-
* Error handling:
|
|
22
|
+
* Error handling: a *storage* failure is reported as `null`/`false` — the
|
|
23
|
+
* backend contract is non-throwing. Three things do throw, because they are
|
|
24
|
+
* not storage outcomes: a policy `before` hook rejecting the operation
|
|
25
|
+
* (ADR-002 §1.0.0), a backend surfacing an unexpected transport failure from
|
|
26
|
+
* `retrieve`/`listKeys`, and a malformed credential key
|
|
27
|
+
* (`InvalidCredentialKeyError`, see the key-validation section below).
|
|
17
28
|
*/
|
|
18
29
|
import { storeStringInKeychain, getStringFromKeychain, deleteFromKeychain, listAccountsInKeychain, } from "../crypto/vault-common.js";
|
|
30
|
+
import { probeKeychainCredentialState } from "../crypto/darwin-keychain.js";
|
|
19
31
|
import { WindowsVault } from "./vault-windows.js";
|
|
20
32
|
import { LibsecretVault } from "./vault-libsecret.js";
|
|
21
33
|
import { GpgVault } from "./vault-gpg.js";
|
|
22
34
|
import { EnvVault } from "./vault-env.js";
|
|
23
|
-
import {
|
|
35
|
+
import { OnePasswordVault } from "./vault-onepassword.js";
|
|
36
|
+
import { loadConfig } from "../key-providers/resolve.js";
|
|
37
|
+
import { runBeforeHooks, runAfterHooks, rejectedEventType } from "./policy.js";
|
|
38
|
+
import { assertValidKey, isValidKey, isValidKeyPrefix } from "./vault-utils.js";
|
|
39
|
+
import { InvalidCredentialKeyError } from "./session-vault-errors.js";
|
|
24
40
|
// =============================================================================
|
|
25
41
|
// Constants
|
|
26
42
|
// =============================================================================
|
|
27
|
-
|
|
43
|
+
/**
|
|
44
|
+
* The keychain service every credential VALUE lives under. Exported because
|
|
45
|
+
* the migration helper (`migrateLoginCredentialToSystem`) and operator
|
|
46
|
+
* tooling have to name the same service — a second literal somewhere else is
|
|
47
|
+
* how a migration silently moves nothing.
|
|
48
|
+
*/
|
|
49
|
+
export const AUTH_KEYCHAIN_SERVICE = "centient-auth";
|
|
28
50
|
const SESSION_TTL_MS = 4 * 60 * 60 * 1000; // 4 hours
|
|
29
51
|
// =============================================================================
|
|
30
52
|
// KeychainVault wrapper
|
|
31
53
|
// =============================================================================
|
|
32
54
|
/**
|
|
33
|
-
* Wraps the
|
|
55
|
+
* Wraps the macOS Keychain helper functions as a VaultBackend.
|
|
56
|
+
*
|
|
57
|
+
* Every method routes through `crypto/darwin-keychain.ts` (#188), so credential
|
|
58
|
+
* values inherit explicit System-keychain reads in a sessionless context,
|
|
59
|
+
* `-U` replace-in-place writes and `-T /usr/bin/security` reader
|
|
60
|
+
* preauthorization — the same posture the KeyProvider layer gets for the vault
|
|
61
|
+
* master key.
|
|
62
|
+
*
|
|
34
63
|
* Only available on macOS (darwin).
|
|
35
64
|
*/
|
|
36
|
-
class KeychainVault {
|
|
65
|
+
export class KeychainVault {
|
|
66
|
+
deps;
|
|
67
|
+
/**
|
|
68
|
+
* @param deps - Injection seam for the `security` CLI and the
|
|
69
|
+
* platform/environment that decide the read path. Omitted in production;
|
|
70
|
+
* supplied by tests so the exact argv is assertable.
|
|
71
|
+
*/
|
|
72
|
+
constructor(deps = {}) {
|
|
73
|
+
this.deps = deps;
|
|
74
|
+
}
|
|
37
75
|
static detect() {
|
|
38
76
|
return process.platform === "darwin";
|
|
39
77
|
}
|
|
40
78
|
store(key, value) {
|
|
41
|
-
return storeStringInKeychain(AUTH_KEYCHAIN_SERVICE, key, value);
|
|
79
|
+
return storeStringInKeychain(AUTH_KEYCHAIN_SERVICE, key, value, this.deps);
|
|
42
80
|
}
|
|
43
81
|
retrieve(key) {
|
|
44
|
-
return getStringFromKeychain(AUTH_KEYCHAIN_SERVICE, key);
|
|
82
|
+
return getStringFromKeychain(AUTH_KEYCHAIN_SERVICE, key, this.deps);
|
|
45
83
|
}
|
|
46
84
|
delete(key) {
|
|
47
|
-
return deleteFromKeychain(AUTH_KEYCHAIN_SERVICE, key);
|
|
85
|
+
return deleteFromKeychain(AUTH_KEYCHAIN_SERVICE, key, this.deps);
|
|
48
86
|
}
|
|
49
87
|
async listKeys(prefix) {
|
|
50
|
-
return listAccountsInKeychain(AUTH_KEYCHAIN_SERVICE, prefix);
|
|
88
|
+
return listAccountsInKeychain(AUTH_KEYCHAIN_SERVICE, prefix, this.deps);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* The credential state probe: runs the SAME read {@link retrieve} would run
|
|
92
|
+
* in this context — same path, same explicit target — then discards the
|
|
93
|
+
* value and returns only the value-free {@link SecretState}.
|
|
94
|
+
*
|
|
95
|
+
* A metadata-only lookup would be cheaper and would leave the secret on
|
|
96
|
+
* disk, but it can only report presence: an item whose ACL does not
|
|
97
|
+
* preauthorize the reader, or that sits in a locked keychain, is present and
|
|
98
|
+
* unreadable, and calling that `found` hands a caller trusted state that is
|
|
99
|
+
* wrong in exactly the direction #188 exists to fix. `found` here means the
|
|
100
|
+
* reader will get bytes.
|
|
101
|
+
*/
|
|
102
|
+
probe(key) {
|
|
103
|
+
return probeKeychainCredentialState(AUTH_KEYCHAIN_SERVICE, key, this.deps);
|
|
51
104
|
}
|
|
52
105
|
}
|
|
53
106
|
// =============================================================================
|
|
54
107
|
// Cascade initialization
|
|
55
108
|
// =============================================================================
|
|
56
109
|
/**
|
|
57
|
-
*
|
|
110
|
+
* Read the explicitly-selected backend, env taking precedence over config —
|
|
111
|
+
* the same env > config order the key layer uses (ADR-001).
|
|
112
|
+
*
|
|
113
|
+
* Returns null when nothing is explicitly selected, which is the signal to run
|
|
114
|
+
* the auto-cascade unchanged.
|
|
115
|
+
*/
|
|
116
|
+
function resolveExplicitBackend() {
|
|
117
|
+
const envBackend = process.env.CENTIENT_SECRETS_BACKEND?.trim();
|
|
118
|
+
const config = loadConfig().secrets ?? {};
|
|
119
|
+
const selected = envBackend || config.backend;
|
|
120
|
+
if (!selected)
|
|
121
|
+
return null;
|
|
122
|
+
if (selected !== "1password") {
|
|
123
|
+
throw new Error(`Unknown secrets backend "${selected}". Supported explicit backends: 1password.`);
|
|
124
|
+
}
|
|
125
|
+
const envVault = process.env.CENTIENT_OP_VAULT?.trim();
|
|
126
|
+
const onePasswordBackend = {
|
|
127
|
+
...config.onePasswordBackend,
|
|
128
|
+
...(envVault ? { vault: envVault } : {}),
|
|
129
|
+
};
|
|
130
|
+
return { type: selected, onePasswordBackend };
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Selects the credential-storage backend.
|
|
134
|
+
*
|
|
135
|
+
* **Explicit selection wins and fails closed** (ADR-004 §1): if config or env
|
|
136
|
+
* names a backend that then turns out to be unusable — no vault configured, `op`
|
|
137
|
+
* missing or unauthenticated — this throws rather than quietly continuing down
|
|
138
|
+
* the auto-cascade. Falling through would silently store credentials somewhere
|
|
139
|
+
* other than where the operator said, which is the whole class of surprise the
|
|
140
|
+
* opt-in model exists to prevent (P2).
|
|
141
|
+
*
|
|
142
|
+
* With no explicit selection, the historical auto-cascade runs unchanged:
|
|
58
143
|
* Keychain -> Windows -> Libsecret -> GPG -> Env
|
|
144
|
+
* 1Password is **never** auto-selected — `op` being installed is not consent to
|
|
145
|
+
* route credentials into it.
|
|
59
146
|
*/
|
|
60
147
|
function initVaultBackend() {
|
|
148
|
+
const explicit = resolveExplicitBackend();
|
|
149
|
+
if (explicit !== null) {
|
|
150
|
+
// Constructor throws on a missing vault name — the fail-closed half of §1.
|
|
151
|
+
const backend = new OnePasswordVault(explicit.onePasswordBackend);
|
|
152
|
+
if (!OnePasswordVault.detect(true)) {
|
|
153
|
+
throw new Error('secrets backend "1password" was explicitly selected, but the 1Password CLI ' +
|
|
154
|
+
"(`op`) is unavailable or not authenticated. Install `op` and sign in, or set " +
|
|
155
|
+
"OP_SERVICE_ACCOUNT_TOKEN. Refusing to fall back to another backend — an " +
|
|
156
|
+
"explicit backend choice is never silently substituted.");
|
|
157
|
+
}
|
|
158
|
+
return { backend, type: "1password" };
|
|
159
|
+
}
|
|
61
160
|
if (KeychainVault.detect())
|
|
62
161
|
return { backend: new KeychainVault(), type: "keychain" };
|
|
63
162
|
if (WindowsVault.detect())
|
|
@@ -88,6 +187,59 @@ function touchSession() {
|
|
|
88
187
|
lastAccessAt = Date.now();
|
|
89
188
|
}
|
|
90
189
|
// =============================================================================
|
|
190
|
+
// Key validation (#168)
|
|
191
|
+
//
|
|
192
|
+
// The key grammar is enforced HERE, once, for every backend — not per backend.
|
|
193
|
+
// Before #168 it was documented on `listCredentials` and enforced nowhere on
|
|
194
|
+
// the shared path: `KeychainVault` (cascade position 1, and therefore the
|
|
195
|
+
// active backend on every Mac) and `EnvVault` (position 5, the always-available
|
|
196
|
+
// fallback) accepted anything, while GPG/libsecret/Windows/1Password refused
|
|
197
|
+
// it. A key such as `Auth_Token` consequently stored fine on darwin and was
|
|
198
|
+
// unreadable on every other backend — the silent write/read asymmetry the
|
|
199
|
+
// invariant exists to prevent. One rule enforced once at the boundary is the
|
|
200
|
+
// only shape in which that stays true as backends are added (P6/P2).
|
|
201
|
+
//
|
|
202
|
+
// Validation runs BEFORE the policy `before` hooks. A malformed key is a
|
|
203
|
+
// caller-contract violation, not a policy decision — there is no well-formed
|
|
204
|
+
// operation for a policy to allow or deny, and an access-control hook should
|
|
205
|
+
// never be handed a key the storage layer has already ruled out. The rejection
|
|
206
|
+
// is still audited: the `after` hooks fire with the same `*_rejected` event a
|
|
207
|
+
// policy denial produces, so a refused operation is never invisible to the
|
|
208
|
+
// audit trail. Unlike a policy denial, every policy's `after` hook fires —
|
|
209
|
+
// none was entered, so there is no partially-entered stack to respect.
|
|
210
|
+
// =============================================================================
|
|
211
|
+
/**
|
|
212
|
+
* Audit the rejection of `op` and hand `err` back for the caller to throw.
|
|
213
|
+
*
|
|
214
|
+
* Split out so the four public functions reject identically. It returns the
|
|
215
|
+
* error rather than throwing it so the call site reads `throw rejectKey(...)`
|
|
216
|
+
* — the `throw` stays visible where control flow actually leaves.
|
|
217
|
+
*/
|
|
218
|
+
function rejectKey(op, err, start) {
|
|
219
|
+
runAfterHooks({
|
|
220
|
+
type: rejectedEventType(op),
|
|
221
|
+
timestamp: new Date().toISOString(),
|
|
222
|
+
backend: activeVaultType,
|
|
223
|
+
...(op.key !== undefined ? { key: op.key } : {}),
|
|
224
|
+
...(op.prefix !== undefined ? { prefix: op.prefix } : {}),
|
|
225
|
+
error: err.message,
|
|
226
|
+
durationMs: performance.now() - start,
|
|
227
|
+
});
|
|
228
|
+
return err;
|
|
229
|
+
}
|
|
230
|
+
/** Reject a malformed key for a keyed operation, auditing the rejection. */
|
|
231
|
+
function guardKey(key, type, start) {
|
|
232
|
+
if (isValidKey(key))
|
|
233
|
+
return;
|
|
234
|
+
throw rejectKey({ type, key }, new InvalidCredentialKeyError(key, type, "key"), start);
|
|
235
|
+
}
|
|
236
|
+
/** Reject a malformed enumeration prefix, auditing the rejection. */
|
|
237
|
+
function guardPrefix(prefix, start) {
|
|
238
|
+
if (prefix === undefined || isValidKeyPrefix(prefix))
|
|
239
|
+
return;
|
|
240
|
+
throw rejectKey({ type: "enumerate", prefix }, new InvalidCredentialKeyError(prefix, "enumerate", "prefix"), start);
|
|
241
|
+
}
|
|
242
|
+
// =============================================================================
|
|
91
243
|
// Public API
|
|
92
244
|
//
|
|
93
245
|
// Policy-rejected operations are audited: when a `before` hook throws,
|
|
@@ -108,12 +260,16 @@ export function getActiveVaultType() {
|
|
|
108
260
|
/**
|
|
109
261
|
* Store a credential in the active vault backend.
|
|
110
262
|
*
|
|
111
|
-
* @param key - Logical key name (e.g. 'auth-token', 'refresh-token')
|
|
263
|
+
* @param key - Logical key name (e.g. 'auth-token', 'refresh-token').
|
|
264
|
+
* Must match the key grammar — see "Key validation" above.
|
|
112
265
|
* @param value - The credential value to store
|
|
113
266
|
* @returns true on success, false if the backend write fails
|
|
267
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
268
|
+
* Nothing is written and no backend is contacted.
|
|
114
269
|
*/
|
|
115
270
|
export async function storeCredential(key, value) {
|
|
116
271
|
const start = performance.now();
|
|
272
|
+
guardKey(key, "write", start);
|
|
117
273
|
await runBeforeHooks({ type: "write", key }, (error) => ({
|
|
118
274
|
type: "credential_write_rejected",
|
|
119
275
|
timestamp: new Date().toISOString(),
|
|
@@ -139,9 +295,14 @@ export async function storeCredential(key, value) {
|
|
|
139
295
|
*
|
|
140
296
|
* @param key - Logical key name (e.g. 'auth-token')
|
|
141
297
|
* @returns The stored value, or null if not found / backend unavailable
|
|
298
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
299
|
+
* Deliberately not `null`: "malformed" and "not stored" are different
|
|
300
|
+
* answers, and returning the not-found shape for the first is the silent
|
|
301
|
+
* degradation this path used to have.
|
|
142
302
|
*/
|
|
143
303
|
export async function getCredential(key) {
|
|
144
304
|
const start = performance.now();
|
|
305
|
+
guardKey(key, "read", start);
|
|
145
306
|
await runBeforeHooks({ type: "read", key }, (error) => ({
|
|
146
307
|
type: "credential_read_rejected",
|
|
147
308
|
timestamp: new Date().toISOString(),
|
|
@@ -181,9 +342,13 @@ export async function getCredential(key) {
|
|
|
181
342
|
*
|
|
182
343
|
* @param key - Logical key name (e.g. 'auth-token')
|
|
183
344
|
* @returns true on success (including "already deleted"), false on unexpected error
|
|
345
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar.
|
|
346
|
+
* Not reported as an idempotent success: such a key was never storable, so
|
|
347
|
+
* "already deleted" would be a claim the vault cannot make.
|
|
184
348
|
*/
|
|
185
349
|
export async function deleteCredential(key) {
|
|
186
350
|
const start = performance.now();
|
|
351
|
+
guardKey(key, "delete", start);
|
|
187
352
|
await runBeforeHooks({ type: "delete", key }, (error) => ({
|
|
188
353
|
type: "credential_delete_rejected",
|
|
189
354
|
timestamp: new Date().toISOString(),
|
|
@@ -216,7 +381,15 @@ export async function deleteCredential(key) {
|
|
|
216
381
|
* Note: credential keys must match `isValidKey` — lowercase alphanumeric
|
|
217
382
|
* plus hyphen and dot, first and last character alphanumeric, <=64 chars.
|
|
218
383
|
* Both `-` and `.` work as namespace separators; pick whichever convention
|
|
219
|
-
* reads best.
|
|
384
|
+
* reads best. **This is enforced, not merely documented** (#168): every
|
|
385
|
+
* function on this path rejects a non-conforming key before dispatching.
|
|
386
|
+
*
|
|
387
|
+
* A `prefix` is checked against `isValidKeyPrefix` rather than `isValidKey`,
|
|
388
|
+
* so it may end on a separator — `"soma.anthropic."` is the intended way to
|
|
389
|
+
* scope an enumeration to a namespace, and is not itself a valid key.
|
|
390
|
+
*
|
|
391
|
+
* @throws {InvalidCredentialKeyError} if `prefix` could not be the leading
|
|
392
|
+
* substring of any valid key.
|
|
220
393
|
*
|
|
221
394
|
* @example
|
|
222
395
|
* // Enumerate all soma-owned Anthropic credentials
|
|
@@ -228,6 +401,7 @@ export async function deleteCredential(key) {
|
|
|
228
401
|
*/
|
|
229
402
|
export async function listCredentials(prefix) {
|
|
230
403
|
const start = performance.now();
|
|
404
|
+
guardPrefix(prefix, start);
|
|
231
405
|
await runBeforeHooks({ type: "enumerate", prefix }, (error) => ({
|
|
232
406
|
type: "credential_enumerate_rejected",
|
|
233
407
|
timestamp: new Date().toISOString(),
|
|
@@ -263,4 +437,69 @@ export async function listCredentials(prefix) {
|
|
|
263
437
|
});
|
|
264
438
|
return keys;
|
|
265
439
|
}
|
|
440
|
+
/**
|
|
441
|
+
* Probe one credential's state in a specific backend.
|
|
442
|
+
*
|
|
443
|
+
* Backends that implement `probe()` answer directly. For the rest this falls
|
|
444
|
+
* back to a `retrieve()`-based mapping — the value is discarded immediately
|
|
445
|
+
* and never returned — which yields `found`/`absent` honestly and `failed`
|
|
446
|
+
* when the backend threw. It never invents `locked`, because a backend that
|
|
447
|
+
* did not report one cannot be assumed to have one, and it never converts a
|
|
448
|
+
* throw into `absent`.
|
|
449
|
+
*
|
|
450
|
+
* Both paths answer readability, not mere presence: the fallback runs the real
|
|
451
|
+
* `retrieve()`, and an implementing backend is required to exercise the same
|
|
452
|
+
* access path it would for a read (see `VaultBackend.probe`). `found`
|
|
453
|
+
* therefore means the reader will get bytes.
|
|
454
|
+
*
|
|
455
|
+
* @throws {InvalidCredentialKeyError} if `key` does not match the grammar —
|
|
456
|
+
* the same rule every other vault entry point enforces (#168). Policy hooks
|
|
457
|
+
* are deliberately NOT run: a probe reads no value, so there is nothing for
|
|
458
|
+
* an access-control hook to allow or deny.
|
|
459
|
+
*/
|
|
460
|
+
export async function probeVaultBackendState(backend, type, key) {
|
|
461
|
+
assertValidKey(key, "read");
|
|
462
|
+
if (typeof backend.probe === "function") {
|
|
463
|
+
try {
|
|
464
|
+
return { layer: "value", backend: type, state: await backend.probe(key) };
|
|
465
|
+
}
|
|
466
|
+
catch (err) {
|
|
467
|
+
return {
|
|
468
|
+
layer: "value",
|
|
469
|
+
backend: type,
|
|
470
|
+
state: {
|
|
471
|
+
kind: "failed",
|
|
472
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
473
|
+
},
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
try {
|
|
478
|
+
const value = backend.retrieve(key);
|
|
479
|
+
return {
|
|
480
|
+
layer: "value",
|
|
481
|
+
backend: type,
|
|
482
|
+
state: value !== null ? { kind: "found" } : { kind: "absent" },
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
catch (err) {
|
|
486
|
+
return {
|
|
487
|
+
layer: "value",
|
|
488
|
+
backend: type,
|
|
489
|
+
state: {
|
|
490
|
+
kind: "failed",
|
|
491
|
+
detail: err instanceof Error ? err.message : String(err),
|
|
492
|
+
},
|
|
493
|
+
};
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
/**
|
|
497
|
+
* Probe one credential's state in the backend this process actually uses.
|
|
498
|
+
*
|
|
499
|
+
* The value-layer half of the two-layer probe; see `probeKeyProviderState()`
|
|
500
|
+
* for the vault master key.
|
|
501
|
+
*/
|
|
502
|
+
export async function probeBackendState(key) {
|
|
503
|
+
return probeVaultBackendState(activeBackend, activeVaultType, key);
|
|
504
|
+
}
|
|
266
505
|
//# sourceMappingURL=vault.js.map
|
package/dist/vault/vault.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vault.js","sourceRoot":"","sources":["../../src/vault/vault.ts"],"names":[],"mappings":"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"}
|