@the-ai-company/cbio-node-runtime 0.39.0 → 1.0.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 +116 -54
- package/dist/clients/agent/client.d.ts +9 -0
- package/dist/clients/agent/client.js +72 -0
- package/dist/clients/agent/client.js.map +1 -0
- package/dist/clients/agent/contracts.d.ts +34 -0
- package/dist/clients/agent/contracts.js +2 -0
- package/dist/clients/agent/contracts.js.map +1 -0
- package/dist/clients/agent/index.d.ts +3 -0
- package/dist/clients/agent/index.js +2 -0
- package/dist/clients/agent/index.js.map +1 -0
- package/dist/clients/owner/client.d.ts +18 -0
- package/dist/clients/owner/client.js +169 -0
- package/dist/clients/owner/client.js.map +1 -0
- package/dist/clients/owner/contracts.d.ts +34 -0
- package/dist/clients/owner/contracts.js +2 -0
- package/dist/clients/owner/contracts.js.map +1 -0
- package/dist/clients/owner/index.d.ts +3 -0
- package/dist/clients/owner/index.js +2 -0
- package/dist/clients/owner/index.js.map +1 -0
- package/dist/runtime/index.d.ts +8 -10
- package/dist/runtime/index.js +8 -7
- package/dist/runtime/index.js.map +1 -1
- package/dist/storage/fs.d.ts +1 -0
- package/dist/storage/fs.js +28 -0
- package/dist/storage/fs.js.map +1 -1
- package/dist/storage/memory.d.ts +1 -0
- package/dist/storage/memory.js +20 -0
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/provider.d.ts +2 -0
- package/dist/vault-core/contracts.d.ts +230 -0
- package/dist/vault-core/contracts.js +2 -0
- package/dist/vault-core/contracts.js.map +1 -0
- package/dist/vault-core/core.d.ts +21 -0
- package/dist/vault-core/core.js +335 -0
- package/dist/vault-core/core.js.map +1 -0
- package/dist/vault-core/defaults.d.ts +141 -0
- package/dist/vault-core/defaults.js +602 -0
- package/dist/vault-core/defaults.js.map +1 -0
- package/dist/vault-core/errors.d.ts +4 -0
- package/dist/vault-core/errors.js +9 -0
- package/dist/vault-core/errors.js.map +1 -0
- package/dist/vault-core/index.d.ts +6 -0
- package/dist/vault-core/index.js +5 -0
- package/dist/vault-core/index.js.map +1 -0
- package/dist/vault-core/persistence.d.ts +87 -0
- package/dist/vault-core/persistence.js +309 -0
- package/dist/vault-core/persistence.js.map +1 -0
- package/dist/vault-core/ports.d.ts +101 -0
- package/dist/vault-core/ports.js +2 -0
- package/dist/vault-core/ports.js.map +1 -0
- package/dist/vault-ingress/defaults.d.ts +14 -0
- package/dist/vault-ingress/defaults.js +41 -0
- package/dist/vault-ingress/defaults.js.map +1 -0
- package/dist/vault-ingress/flow-factories.d.ts +24 -0
- package/dist/vault-ingress/flow-factories.js +48 -0
- package/dist/vault-ingress/flow-factories.js.map +1 -0
- package/dist/vault-ingress/index.d.ts +81 -0
- package/dist/vault-ingress/index.js +357 -0
- package/dist/vault-ingress/index.js.map +1 -0
- package/docs/ARCHITECTURE.md +44 -76
- package/docs/REFERENCE.md +217 -218
- package/docs/WORKS_WITH_CUSTOM_FETCH.md +16 -191
- package/docs/es/README.md +8 -24
- package/docs/fr/README.md +8 -24
- package/docs/ja/README.md +8 -24
- package/docs/ko/README.md +8 -24
- package/docs/pt/README.md +8 -24
- package/docs/zh/README.md +21 -7
- package/package.json +2 -10
- package/dist/agent/agent.d.ts +0 -267
- package/dist/agent/agent.js +0 -689
- package/dist/agent/agent.js.map +0 -1
- package/dist/audit/ActivityLog.d.ts +0 -25
- package/dist/audit/ActivityLog.js +0 -71
- package/dist/audit/ActivityLog.js.map +0 -1
- package/dist/http/authClient.d.ts +0 -26
- package/dist/http/authClient.js +0 -132
- package/dist/http/authClient.js.map +0 -1
- package/dist/http/genericSecretValidator.d.ts +0 -11
- package/dist/http/genericSecretValidator.js +0 -42
- package/dist/http/genericSecretValidator.js.map +0 -1
- package/dist/http/localAuthProxy.d.ts +0 -33
- package/dist/http/localAuthProxy.js +0 -93
- package/dist/http/localAuthProxy.js.map +0 -1
- package/dist/http/localSecretIngress.d.ts +0 -33
- package/dist/http/localSecretIngress.js +0 -162
- package/dist/http/localSecretIngress.js.map +0 -1
- package/dist/http/secretAcquisition.d.ts +0 -54
- package/dist/http/secretAcquisition.js +0 -177
- package/dist/http/secretAcquisition.js.map +0 -1
- package/dist/protocol/childSecretNaming.d.ts +0 -7
- package/dist/protocol/childSecretNaming.js +0 -12
- package/dist/protocol/childSecretNaming.js.map +0 -1
- package/dist/protocol/identity.d.ts +0 -8
- package/dist/protocol/identity.js +0 -16
- package/dist/protocol/identity.js.map +0 -1
- package/dist/sealed/index.d.ts +0 -6
- package/dist/sealed/index.js +0 -6
- package/dist/sealed/index.js.map +0 -1
- package/dist/vault/secretPolicy.d.ts +0 -3
- package/dist/vault/secretPolicy.js +0 -14
- package/dist/vault/secretPolicy.js.map +0 -1
- package/dist/vault/vault.d.ts +0 -100
- package/dist/vault/vault.js +0 -603
- package/dist/vault/vault.js.map +0 -1
- package/docs/TODO-multi-vault.md +0 -29
- package/docs/spec/runtime/README.md +0 -44
- package/docs/spec/runtime/activity-log.md +0 -71
- package/docs/spec/runtime/exposure-surfaces.md +0 -99
- package/docs/spec/runtime/managed-agent-record.md +0 -52
- package/docs/spec/runtime/merge-rules.md +0 -52
- package/docs/spec/runtime/secret-origin-policy.md +0 -46
- package/docs/spec/runtime/secret-validation.md +0 -113
package/docs/REFERENCE.md
CHANGED
|
@@ -1,291 +1,290 @@
|
|
|
1
|
-
# CBIO
|
|
1
|
+
# CBIO Vault Runtime Reference
|
|
2
2
|
|
|
3
|
-
This document
|
|
3
|
+
This document describes the current implemented runtime surface.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This file is intentionally narrower: it documents what the shipped API does today.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
## Public Surface
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
The current top-level modules are:
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
- `vault-core`
|
|
12
|
+
- `vault-ingress`
|
|
13
|
+
- `clients/owner`
|
|
14
|
+
- `clients/agent`
|
|
12
15
|
|
|
13
|
-
|
|
14
|
-
- **`identity.admin.vault.mergeFrom(otherIdentity, options?)`**: Atomically merges secrets from another vault.
|
|
15
|
-
- `onConflict`: `'abort'` (default), `'skip'`, or `'overwrite'`.
|
|
16
|
-
- Throws `MERGE_IDENTITY_MISMATCH` if root identities differ.
|
|
16
|
+
The main constructors are:
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
18
|
+
- `createVaultCore(...)`
|
|
19
|
+
- `createVaultService(...)`
|
|
20
|
+
- `createOwnerClient(...)`
|
|
21
|
+
- `createAgentClient(...)`
|
|
22
|
+
- `LocalVaultTransport`
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## Secret-Flow Model
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
import { sealBlob, unsealBlob } from '@the-ai-company/cbio-node-runtime/sealed';
|
|
28
|
-
```
|
|
26
|
+
The current HTTP-facing API supports two explicit secret-flow classes:
|
|
29
27
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
- **`identity.admin.managedAgents.revokeManagedAgent(publicKey, reason?)`**: Permanently revokes a child identity.
|
|
33
|
-
- **`identity.admin.managedAgents.getManagedAgentCapabilities(publicKey)`**: Returns `{ status, capabilities }` for a managed agent, so callers can distinguish active, revoked, missing, and invalid records.
|
|
28
|
+
- `acquire_secret`
|
|
29
|
+
No secret leaves the vault. A response-derived secret is stored into the vault. Agent-visible output is limited to protocol metadata and a redacted response shape.
|
|
34
30
|
|
|
35
|
-
|
|
36
|
-
-
|
|
37
|
-
- **`getAgent({ permissions })`**: Returns a handle with explicitly provided runtime permissions.
|
|
38
|
-
- **`getAgent({ deriveFromIssuedIdentity: true })`**: Derives runtime permissions from the issued identity's protocol capabilities.
|
|
31
|
+
- `send_secret`
|
|
32
|
+
A stored secret is sent to an owner-approved target. The remote response is treated as normal business output and may be returned to the agent.
|
|
39
33
|
|
|
40
|
-
|
|
34
|
+
This is a deliberate protocol boundary:
|
|
41
35
|
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
- `vault:acquire` for acquisition, ingress, compare, proof, and validation operations
|
|
36
|
+
- acquisition responses are assumed sensitive and are therefore redacted on the way back to the agent
|
|
37
|
+
- dispatch responses are treated as ordinary HTTP results once the owner has authorized sending the secret to that target
|
|
45
38
|
|
|
46
|
-
|
|
47
|
-
When a child is registered via `registerChildIdentity(keys)`, its key material is stored in the parent vault. The method returns `{ publicKey }` (domain-level identifier). Treat the persisted child record as runtime-managed state rather than application-readable plaintext.
|
|
48
|
-
```ts
|
|
49
|
-
const { publicKey: childPublicKey } = await identity.registerChildIdentity(keys);
|
|
50
|
-
console.log(childPublicKey);
|
|
51
|
-
```
|
|
39
|
+
The runtime does not try to reinterpret every remote protocol. If an approved target returns sensitive values during a normal dispatch call, that is part of the target contract and owner authorization scope rather than a vault-side parsing obligation.
|
|
52
40
|
|
|
53
|
-
|
|
41
|
+
The runtime does not claim to understand arbitrary network protocols. The API communicates only the currently supported boundary:
|
|
54
42
|
|
|
55
|
-
|
|
43
|
+
- supported: explicit acquisition into vault through built-in standard flows
|
|
44
|
+
- supported: explicit secret-backed outbound dispatch
|
|
45
|
+
- supported: owner-defined `custom_http` flows for explicit exception cases
|
|
46
|
+
- unsupported: mixed bidirectional-secret flows as a first-class surface
|
|
47
|
+
- unsupported: no-secret operations as a first-class vault primitive
|
|
56
48
|
|
|
57
|
-
|
|
49
|
+
## Vault Service
|
|
58
50
|
|
|
59
|
-
|
|
60
|
-
```ts
|
|
61
|
-
export interface IStorageProvider {
|
|
62
|
-
read(key: string): Promise<Buffer | null>;
|
|
63
|
-
write(key: string, data: Buffer): Promise<void>;
|
|
64
|
-
delete(key: string): Promise<void>;
|
|
65
|
-
has(key: string): Promise<boolean>;
|
|
66
|
-
rename?(fromKey: string, toKey: string): Promise<void>; // Improves atomic writes
|
|
67
|
-
}
|
|
68
|
-
```
|
|
51
|
+
`vault-ingress` is the request-shaped boundary around the vault kernel.
|
|
69
52
|
|
|
70
|
-
|
|
71
|
-
- **`MemoryStorageProvider`**: Ephemeral storage for testing or in-memory caches.
|
|
72
|
-
- **Filesystem (Default)**: Persists to `~/.c-bio/`. Use `C_BIO_VAULT_DIR` environment variable to override.
|
|
53
|
+
Important methods:
|
|
73
54
|
|
|
74
|
-
|
|
55
|
+
- `bootstrapOwnerIdentity(...)`
|
|
56
|
+
- `registerAgentIdentity(...)`
|
|
57
|
+
- `registerOwnerIdentity(...)`
|
|
58
|
+
- `writeSecret(...)`
|
|
59
|
+
- `acquireSecret(...)`
|
|
60
|
+
- `dispatch(...)`
|
|
61
|
+
- `handleAgentDispatch(...)`
|
|
62
|
+
- `readAudit(...)`
|
|
75
63
|
|
|
76
|
-
|
|
64
|
+
### Owner Bootstrap
|
|
77
65
|
|
|
78
|
-
|
|
66
|
+
The very first owner is bootstrapped explicitly:
|
|
79
67
|
|
|
80
|
-
### 3.1 Custom Fetch for SDKs (OpenAI/Anthropic)
|
|
81
|
-
If a third-party SDK supports a custom `fetch` implementation, use `createFetchWithAuth`. This keeps the vault boundary while using the official client.
|
|
82
68
|
```ts
|
|
83
|
-
|
|
84
|
-
|
|
69
|
+
await vault.bootstrapOwnerIdentity({
|
|
70
|
+
vaultId: vault.vaultId,
|
|
71
|
+
ownerId: 'owner-1',
|
|
72
|
+
publicKey: ownerPublicKey,
|
|
85
73
|
});
|
|
86
74
|
```
|
|
87
75
|
|
|
88
|
-
|
|
89
|
-
|
|
76
|
+
After that, additional owner and agent identities should be registered through owner-signed commands rather than direct raw records.
|
|
77
|
+
|
|
78
|
+
## Owner Client
|
|
79
|
+
|
|
80
|
+
`clients/owner` is the owner-facing caller surface.
|
|
81
|
+
|
|
82
|
+
Current owner operations:
|
|
83
|
+
|
|
84
|
+
- `writeSecret(...)`
|
|
85
|
+
- `getAudit(...)`
|
|
86
|
+
- `registerAgentIdentity(...)`
|
|
87
|
+
- `registerOwnerIdentity(...)`
|
|
88
|
+
- `registerCustomFlow(...)`
|
|
89
|
+
|
|
90
|
+
Example:
|
|
91
|
+
|
|
90
92
|
```ts
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
withSignature: true, // Optional: adds X-CBIO-Signature
|
|
93
|
+
const owner = createOwnerClient(ownerIdentity, vault, ownerSigner, clock);
|
|
94
|
+
|
|
95
|
+
await owner.registerAgentIdentity({
|
|
96
|
+
agentId: 'agent-1',
|
|
97
|
+
publicKey: agentPublicKey,
|
|
97
98
|
});
|
|
98
|
-
```
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
await owner.registerCustomFlow({
|
|
101
|
+
flowId: 'custom-status-read',
|
|
102
|
+
mode: 'send_secret',
|
|
103
|
+
targetUrl: 'https://api.example.com/custom-status',
|
|
104
|
+
method: 'POST',
|
|
105
|
+
responseVisibility: 'shape_only',
|
|
106
|
+
});
|
|
102
107
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
await owner.writeSecret({
|
|
109
|
+
alias: 'api-token',
|
|
110
|
+
plaintext: 'secret-value',
|
|
111
|
+
targetBindings: [
|
|
112
|
+
{
|
|
113
|
+
kind: 'site',
|
|
114
|
+
targetId: 'api.example.com',
|
|
115
|
+
targetUrl: 'https://api.example.com/endpoint',
|
|
116
|
+
methods: ['POST'],
|
|
117
|
+
},
|
|
118
|
+
],
|
|
109
119
|
});
|
|
110
120
|
```
|
|
111
121
|
|
|
112
|
-
|
|
113
|
-
- request bodies are JSON-stringified
|
|
114
|
-
- responses are parsed with `response.json()`
|
|
115
|
-
- `extractKey(...)` receives the parsed JSON body
|
|
122
|
+
## Agent Client
|
|
116
123
|
|
|
117
|
-
|
|
118
|
-
Use `startLocalAuthProxy(...)` when a local process should forward requests to an upstream API while vault-backed auth is injected automatically.
|
|
124
|
+
`clients/agent` creates signed dispatch requests. It never receives plaintext secrets.
|
|
119
125
|
|
|
120
|
-
|
|
121
|
-
-
|
|
122
|
-
- `secretName`: vault secret to inject
|
|
123
|
-
- `upstreamBaseUrl`: upstream API base URL
|
|
126
|
+
Current dispatch capabilities use `dispatch_http` as the explicit secret-send operation.
|
|
127
|
+
It is intended for standard secret-backed resource access, not for token mint / refresh / exchange / registration-finalize style acquisition flows.
|
|
124
128
|
|
|
125
|
-
|
|
126
|
-
-
|
|
127
|
-
- `authPrefix`: defaults to `Bearer `
|
|
128
|
-
- `host`: defaults to `127.0.0.1`
|
|
129
|
-
- `port`: defaults to an ephemeral port
|
|
129
|
+
The runtime also supports `custom_http` as an owner-defined exception path. A `custom_http` capability must reference a registered `customFlowId`.
|
|
130
|
+
Owner-defined HTTP boundaries share one factory layer:
|
|
130
131
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
132
|
+
- `createOwnerHttpFlowBoundary(...)`
|
|
133
|
+
- `createStandardAcquireBoundary(...)`
|
|
134
|
+
- `createStandardDispatchBoundary(...)`
|
|
135
|
+
|
|
136
|
+
The owner-defined flow may use one of three modes:
|
|
137
|
+
|
|
138
|
+
- `acquire_secret`
|
|
139
|
+
- `send_secret`
|
|
140
|
+
- `bidirectional_secret`
|
|
141
|
+
|
|
142
|
+
Example:
|
|
139
143
|
|
|
140
|
-
Anthropic example:
|
|
141
144
|
```ts
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
const capability = {
|
|
146
|
+
vaultId: vault.vaultId,
|
|
147
|
+
capabilityId: 'cap-1',
|
|
148
|
+
agentId: 'agent-1',
|
|
149
|
+
secretAliases: ['api-token'],
|
|
150
|
+
operation: 'dispatch_http',
|
|
151
|
+
allowedTargets: ['https://api.example.com/endpoint'],
|
|
152
|
+
allowedMethods: ['POST'],
|
|
153
|
+
issuedAt: new Date().toISOString(),
|
|
154
|
+
};
|
|
149
155
|
```
|
|
150
156
|
|
|
151
|
-
|
|
157
|
+
Custom capability example:
|
|
158
|
+
|
|
152
159
|
```ts
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
160
|
+
const customCapability = {
|
|
161
|
+
vaultId: vault.vaultId,
|
|
162
|
+
capabilityId: 'cap-custom',
|
|
163
|
+
agentId: 'agent-1',
|
|
164
|
+
customFlowId: 'custom-status-read',
|
|
165
|
+
secretAliases: ['api-token'],
|
|
166
|
+
operation: 'custom_http',
|
|
167
|
+
allowedTargets: ['https://api.example.com/custom-status'],
|
|
168
|
+
allowedMethods: ['POST'],
|
|
169
|
+
issuedAt: new Date().toISOString(),
|
|
170
|
+
};
|
|
158
171
|
```
|
|
159
172
|
|
|
160
|
-
|
|
161
|
-
|
|
173
|
+
## Acquisition Result Shape
|
|
174
|
+
|
|
175
|
+
`acquireSecret(...)` is the explicit acquisition operation.
|
|
176
|
+
|
|
177
|
+
It no longer accepts an open-ended extractor callback. The current surface only supports built-in protocol flows:
|
|
178
|
+
|
|
179
|
+
- `oauth_token_response.access_token`
|
|
180
|
+
- `oauth_token_response.refresh_token`
|
|
181
|
+
- `openid_token_response.id_token`
|
|
182
|
+
|
|
183
|
+
Input:
|
|
162
184
|
|
|
163
185
|
```ts
|
|
164
|
-
const
|
|
165
|
-
|
|
186
|
+
const acquireBoundary = createStandardAcquireBoundary({
|
|
187
|
+
targetUrl: 'https://issuer.example.com/token',
|
|
188
|
+
responseField: 'access_token',
|
|
189
|
+
storeAlias: 'issuer-token',
|
|
166
190
|
});
|
|
167
191
|
|
|
168
|
-
await
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
body: 'new-secret-value',
|
|
192
|
+
const acquired = await vault.acquireSecret({
|
|
193
|
+
alias: acquireBoundary.responseSecret.storeAlias,
|
|
194
|
+
issuerId: 'issuer-1',
|
|
195
|
+
url: acquireBoundary.targetUrl,
|
|
196
|
+
flow: 'oauth_token_response.access_token',
|
|
197
|
+
method: acquireBoundary.method,
|
|
175
198
|
});
|
|
176
199
|
```
|
|
177
200
|
|
|
178
|
-
|
|
179
|
-
- `allowedOrigins`
|
|
180
|
-
- `overwrite`
|
|
181
|
-
- `host`
|
|
182
|
-
- `port`
|
|
183
|
-
- `path`
|
|
184
|
-
- `authToken`
|
|
185
|
-
- `once`
|
|
186
|
-
- `maxBodyBytes`
|
|
187
|
-
|
|
188
|
-
### 3.6 Local Compare / Proof
|
|
189
|
-
Use `compareSecret(...)` and `proveSecret(...)` when the application needs a local KMS-like operation without exporting the stored secret.
|
|
201
|
+
Output:
|
|
190
202
|
|
|
191
203
|
```ts
|
|
192
|
-
|
|
193
|
-
|
|
204
|
+
type VaultAcquireSecretResult = {
|
|
205
|
+
vaultId: VaultId;
|
|
206
|
+
alias: string;
|
|
207
|
+
status: 'stored';
|
|
208
|
+
responseStatus: number;
|
|
209
|
+
contentType: string | null;
|
|
210
|
+
responseShape: RedactedResponseShape;
|
|
211
|
+
};
|
|
194
212
|
```
|
|
195
213
|
|
|
196
|
-
|
|
197
|
-
- `sha256`
|
|
198
|
-
- `sha512`
|
|
199
|
-
|
|
200
|
-
`proveSecret(...)` returns a base64url-encoded HMAC proof for the active secret value and the provided challenge.
|
|
214
|
+
`responseShape` is flow-specific. It preserves only the protocol-defined non-sensitive fields that the runtime explicitly allows for that built-in flow.
|
|
201
215
|
|
|
202
|
-
|
|
203
|
-
Use `validateSecret(...)` when the application wants a structured validity result rather than exporting a secret and probing manually.
|
|
216
|
+
Example:
|
|
204
217
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
218
|
+
```ts
|
|
219
|
+
{
|
|
220
|
+
token_type: 'Bearer',
|
|
221
|
+
expires_in: 3600,
|
|
222
|
+
scope: 'read write',
|
|
223
|
+
}
|
|
224
|
+
```
|
|
209
225
|
|
|
210
|
-
|
|
226
|
+
## Dispatch Result Shape
|
|
211
227
|
|
|
212
|
-
|
|
228
|
+
`dispatch_http` returns normal remote output:
|
|
213
229
|
|
|
214
230
|
```ts
|
|
215
|
-
type
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
231
|
+
type DispatchResult = {
|
|
232
|
+
vaultId: VaultId;
|
|
233
|
+
requestId: string;
|
|
234
|
+
status: 'succeeded' | 'denied' | 'failed';
|
|
235
|
+
targetUrl: string;
|
|
236
|
+
method: string;
|
|
237
|
+
responseStatus?: number;
|
|
238
|
+
responseBody?: string;
|
|
239
|
+
error?: string;
|
|
223
240
|
};
|
|
224
241
|
```
|
|
225
242
|
|
|
226
|
-
|
|
243
|
+
This is an intentional current-surface choice: `dispatch_http` is treated as secret-out / non-secret-in.
|
|
244
|
+
|
|
245
|
+
In other words, the vault respects the standard HTTP response surface for normal dispatch. It does not attempt to retroactively sanitize every downstream response body, because doing so would shift responsibility away from the target protocol and the owner's authorization decision.
|
|
246
|
+
|
|
247
|
+
For `custom_http`, response visibility is chosen by the owner at flow registration time:
|
|
248
|
+
|
|
249
|
+
- `passthrough`: return the remote body
|
|
250
|
+
- `shape_only`: return a redacted shape-only body
|
|
251
|
+
|
|
252
|
+
If the custom flow mode includes secret acquisition, the owner also defines a response secret rule. The current built-in rule shape is:
|
|
227
253
|
|
|
228
254
|
```ts
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
status: response.ok ? 'valid' : 'invalid',
|
|
235
|
-
};
|
|
236
|
-
},
|
|
237
|
-
});
|
|
255
|
+
{
|
|
256
|
+
kind: 'json_field',
|
|
257
|
+
field: 'access_token',
|
|
258
|
+
storeAlias: 'new-token',
|
|
259
|
+
}
|
|
238
260
|
```
|
|
239
261
|
|
|
240
|
-
|
|
241
|
-
Use `genericHttpValidator(...)` when a remote service can be probed by a normal authenticated HTTP request and you want a reusable validator without writing custom validator boilerplate.
|
|
262
|
+
## Persistent Dependencies
|
|
242
263
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
`createPersistentVaultCoreDependencies(...)` builds a file-backed single-node profile with:
|
|
265
|
+
|
|
266
|
+
- persistent secret metadata
|
|
267
|
+
- sealed secret custody blobs
|
|
268
|
+
- append-only tamper-evident audit
|
|
269
|
+
- persistent replay guard
|
|
270
|
+
- persistent rate-limit state
|
|
271
|
+
- persistent capability revocation state
|
|
272
|
+
|
|
273
|
+
It still expects caller-provided identity registries unless you supply your own persistent registry adapters.
|
|
274
|
+
|
|
275
|
+
## Storage Provider
|
|
251
276
|
|
|
252
|
-
|
|
277
|
+
Any backend can be used by implementing `IStorageProvider`:
|
|
278
|
+
|
|
279
|
+
```ts
|
|
280
|
+
export interface IStorageProvider {
|
|
281
|
+
read(key: string): Promise<Buffer | null>;
|
|
282
|
+
write(key: string, data: Buffer): Promise<void>;
|
|
283
|
+
delete(key: string): Promise<void>;
|
|
284
|
+
has(key: string): Promise<boolean>;
|
|
285
|
+
rename?(fromKey: string, toKey: string): Promise<void>;
|
|
286
|
+
withLock?<T>(key: string, task: () => Promise<T>): Promise<T>;
|
|
287
|
+
}
|
|
253
288
|
```
|
|
254
289
|
|
|
255
|
-
|
|
256
|
-
- `url`
|
|
257
|
-
- `method`
|
|
258
|
-
- `headers`
|
|
259
|
-
- `body`
|
|
260
|
-
- `isValid(response, data)`
|
|
261
|
-
- `classifyStatus(response, data)`
|
|
262
|
-
- `extractResult(response, data)`
|
|
263
|
-
|
|
264
|
-
Default behavior:
|
|
265
|
-
- `2xx` -> `{ valid: true, status: 'valid' }`
|
|
266
|
-
- `401/403` -> `{ valid: false, status: 'invalid', reason: 'http_<status>' }`
|
|
267
|
-
- other non-`2xx` -> `{ valid: false, status: 'indeterminate', reason: 'http_<status>' }`
|
|
268
|
-
|
|
269
|
-
---
|
|
270
|
-
|
|
271
|
-
## 4. Error Code Dictionary
|
|
272
|
-
|
|
273
|
-
The SDK uses structured `IdentityError` objects with the following codes:
|
|
274
|
-
|
|
275
|
-
| Code | Meaning | Typical Fix / Recovery |
|
|
276
|
-
| :--- | :--- | :--- |
|
|
277
|
-
| `PERMISSION_DENIED` | Handle lacks the required runtime capability. | Check `agent.can()` before calling. |
|
|
278
|
-
| `SECRET_NOT_FOUND` | Secret name does not exist in the vault. | Add it first or check the naming. |
|
|
279
|
-
| `ISSUED_IDENTITY_INVALID` | Bound or persisted issued identity failed protocol or authority/subject validation. | Re-issue the managed identity or load with the correct authority context. |
|
|
280
|
-
| `SECRET_ALREADY_EXISTS` | `addSecret` used on an existing name. | Use a new name or `update`. |
|
|
281
|
-
| `SECRET_POLICY_REQUIRED` | Agent rotation attempted without allowed origins. | Set origins in identity code. |
|
|
282
|
-
| `SECRET_SOURCE_ORIGIN_MISMATCH` | Rotation came from a disallowed origin. | Check secret policy and rotation URL. |
|
|
283
|
-
| `SECRET_OPERATION_RATE_LIMITED` | Local compare/proof/validate operation exceeded the runtime limit window. | Back off, reduce probe frequency, or avoid low-entropy repeated guesses. |
|
|
284
|
-
| `VAULT_PERSISTENCE_FAILED` | Storage is not writable. | Fix permissions or check storage path. |
|
|
285
|
-
| `VAULT_FILE_NOT_FOUND` | Expected vault file does not exist. | Initialize identity or check storage key. |
|
|
286
|
-
| `VAULT_WRITE_INTEGRITY_FAILED` | Save verification failed. | Check disk space/integrity. |
|
|
287
|
-
| `VAULT_CORRUPTED` | Vault file is truncated or unreadable. | Restore from backup; do not overwrite. |
|
|
288
|
-
| `VAULT_DECRYPT_FAILED` | Decryption failed (wrong key or tampered). | Verify the correct Private Key was used. |
|
|
289
|
-
| `MERGE_IDENTITY_MISMATCH` | Tried to merge vaults of different identities. | Only merge vaults of the same identity. |
|
|
290
|
-
| `CHILD_IDENTITY_REQUIRES_PRIVATE_KEY` | Child keys were incomplete on registration. | Ensure child keys include Private Key. |
|
|
291
|
-
| `SIGNER_REQUIRES_PRIVATE_KEY` | Administrative action requires a full signer. | Load identity from a full private key. |
|
|
290
|
+
`withLock(...)` is used when present to serialize read-modify-write persistence sequences.
|