@byok-sdk/keys 0.1.0 → 0.2.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 CHANGED
@@ -3,16 +3,18 @@
3
3
  Key-based BYOK: a validated provider profile, credential-backed auth headers, and
4
4
  direct transports to OpenAI-compatible and Anthropic providers.
5
5
 
6
- Status: **K3 done** — the pure-function layer (K0), the `SecretStore` layer
6
+ Status: **P5 + Pi provider launcher done** — the pure-function layer (K0), the `SecretStore` layer
7
7
  backed by the macOS Keychain and the Windows Credential Manager (K1), and the
8
8
  configure/resolve registry with pluggable profile persistence (K2) have all
9
9
  landed. K3 settled the settings-page question, recorded under
10
- [Not in this package](#not-in-this-package). Next is K4, the aip-main-open swap.
10
+ [Not in this package](#not-in-this-package). P5 adds the tenant-bound
11
+ `TruthStoreProviderProfileStore` without moving provider secrets out of the OS
12
+ credential store.
11
13
 
12
14
  ## Security boundary
13
15
 
14
16
  `@byok-sdk/keys` is a separate package with a separate security model from
15
- `@byok/client` / `@byok/server` / `@byok/protocol`. Those three dispatch tasks to
17
+ `@byok-sdk/client` / `@byok-sdk/server` / `@byok-sdk/protocol`. Those three dispatch tasks to
16
18
  agent runtimes the user already authenticated, and their credential-isolation
17
19
  rule (`packages/client/src/types.ts:120-124`, audited in
18
20
  `docs/security-review-m5-pilot-entry.md`) promises the dispatch path never
@@ -20,12 +22,22 @@ touches credentials. This package's job *is* to hold a provider API key, so it
20
22
  lives on the other side of that line: `client`, `server`, and `protocol` must not
21
23
  depend on `keys`.
22
24
 
23
- Two consequences hold today and are the package's standing constraints:
25
+ Three consequences hold today and are the package's standing constraints:
24
26
 
25
27
  1. `client`, `server`, and `protocol` must not gain a dependency on `keys`.
26
28
  2. `@byok-sdk/keys` is outside the scope of the M5 credential-isolation claim.
27
29
  Installing it is opting into a package that holds a provider API key, and
28
30
  that choice is yours, not something the dispatch SDK does on your behalf.
31
+ 3. The optional `byok-pi-provider-launcher` is the only supported composition
32
+ with agent dispatch. It receives non-secret provider/model ids and paths,
33
+ opens the already-provisioned profile database read-only, reads the OS
34
+ credential only when the selected profile requires one, writes a private
35
+ process-scoped Pi projection, reconstructs the Pi child environment from a
36
+ closed platform/proxy baseline plus the exact key, and inherits stdio. It
37
+ opens no listener and never returns the key to the daemon.
38
+ 4. `@byok-sdk/keys` may depend on protocol-free `@byok-sdk/core` for
39
+ `TruthStore`; it must not depend on `protocol`, `client`, `server`, `cloud`,
40
+ or `cloud-dataplane`, and none of those packages may depend on `keys`.
29
41
 
30
42
  The full declaration of the boundary between the two security models is
31
43
  [`docs/security.md`](../../docs/security.md), section *Key management
@@ -71,9 +83,10 @@ guarantee that the key does not leave the machine.**
71
83
 
72
84
  With the page gone, `@byok-sdk/keys` guarantees only its own half: the key goes
73
85
  into the OS credential store, it is never written to the profile store, it is
74
- never present in any `ProviderStatus`, and it leaves the process only in the
75
- `authorization` / `x-api-key` header of a request to the provider base URL the
76
- profile declares. **Everything between the user's keystroke and
86
+ never present in any `ProviderStatus`, and it leaves custody only in the
87
+ `authorization` / `x-api-key` header of an explicit client request or in the
88
+ environment of the pinned Pi child launched for that exact profile.
89
+ **Everything between the user's keystroke and
77
90
  `configure(configuration, secret)` is now yours.** If your settings page posts
78
91
  the key to your own backend before handing it to this package, or renders it
79
92
  back into a response, or logs the request body, the key has left the machine —
@@ -82,13 +95,15 @@ path now.
82
95
 
83
96
  ## Node version and storage backends
84
97
 
85
- `engines.node` is `>=20`, and that floor is deliberate: the package is fully
86
- usable on Node 20.
98
+ `engines.node` is `>=22.22.0`, aligned with its `@byok-sdk/core` contract
99
+ dependency and the workspace release floor.
87
100
 
88
101
  | Backend | Requirement | Behaviour below it |
89
102
  | --- | --- | --- |
90
- | `InMemoryProviderProfileStore` | Node 20+ | — the whole configure/resolve lifecycle works |
103
+ | `InMemoryProviderProfileStore` | Node 22.22+ | — the whole configure/resolve lifecycle works |
91
104
  | `SqliteProviderProfileStore` | Node 22.5+ (`node:sqlite`) | fails closed with `PROVIDER_STORE_UNAVAILABLE` |
105
+ | `TruthStoreProviderProfileStore` | Node 22.22+ plus an injected tenant-bound `TruthStore` | stale CAS or malformed/hash-mismatched authority fails closed; never falls back to SQLite |
106
+ | `byok-pi-provider-launcher` | Node 22.5+ (`node:sqlite`) and macOS/Windows for authenticated profiles | fails closed; `auth_mode: none` does not require a credential backend |
92
107
 
93
108
  Only on-disk profile persistence needs the newer runtime. `node:sqlite` shipped
94
109
  in Node 22.5 and spent part of the 22.x line behind `--experimental-sqlite`, so
@@ -97,11 +112,11 @@ a version-number comparison would be wrong in both directions; call
97
112
  without it throws `ByokKeysError` with code `PROVIDER_STORE_UNAVAILABLE` rather
98
113
  than degrading to a plaintext file.
99
114
 
100
- The floor rises only when a consumer needs on-disk persistence as an
101
- install-time guarantee rather than a runtime capability — that is, when
102
- "`@byok-sdk/keys` installed successfully" must by itself imply
103
- `SqliteProviderProfileStore` will construct. Until then, raising it would drop
104
- Node 20 hosts that are served perfectly well by the in-memory store.
115
+ All profile-store methods are asynchronous. InMemory and SQLite remain
116
+ independently selected local authorities; the TruthStore adapter is another
117
+ authority selection, not a mirror, migration shim, cache, or dual-write path.
118
+ It stores the complete four-ID provider registry as one versioned deterministic
119
+ snapshot so delete and the one-enabled invariant share one CAS decision.
105
120
 
106
121
  ## Module inventory
107
122
 
@@ -126,8 +141,12 @@ whatever `index.ts` re-exports; nothing here is reachable by deep import.
126
141
  | `command-runner.ts` | The `CommandRunner` injection seam both OS backends are written against, so no unit test touches a real credential store |
127
142
  | `profile-store.ts` | The `ProviderProfileStore` persistence contract, plus the in-memory implementation |
128
143
  | `sqlite-profile-store.ts` | `SqliteProviderProfileStore` — on-disk profile persistence on `node:sqlite` |
144
+ | `truth-profile-store.ts` | `TruthStoreProviderProfileStore` — tenant-bound deterministic registry snapshot with CAS and integrity validation |
129
145
  | `sqlite-support.ts` | Runtime `node:sqlite` capability detection and owner-only database file/directory creation |
130
146
  | `registry.ts` | `ProviderRegistry` — the configure / list / resolve / delete lifecycle that binds a profile store to a secret store and hands back a ready client |
147
+ | `pi-provider-projection.ts` | Credential-blind Pi `models.json` projection for one validated profile/model |
148
+ | `pi-provider-launcher-core.ts` | Closed launcher argv contract and auth-mode-aware exact secret resolution |
149
+ | `bin/pi-provider-launcher.ts` | No-listener credential-custody executable that reads the OS store and spawns pinned Pi with a private projection |
131
150
 
132
151
  Auth modes map to headers as follows, and this mapping is the package's wire
133
152
  contract:
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};