@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 +34 -15
- package/dist/bin/pi-provider-launcher.d.ts +2 -0
- package/dist/bin/pi-provider-launcher.js +1137 -0
- package/dist/bin/pi-provider-launcher.js.map +1 -0
- package/dist/errors.d.ts +4 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +340 -40
- package/dist/index.js.map +1 -1
- package/dist/pi-provider-launcher-core.d.ts +34 -0
- package/dist/pi-provider-projection.d.ts +11 -0
- package/dist/profile-store.d.ts +16 -16
- package/dist/registry.d.ts +1 -1
- package/dist/sqlite-profile-store.d.ts +11 -9
- package/dist/sqlite-support.d.ts +11 -3
- package/dist/truth-profile-store.d.ts +27 -0
- package/package.json +14 -7
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { type ModelProviderId, type ModelProviderProfile } from './provider-profile';
|
|
2
|
+
import { type SecretStore } from './secret-store';
|
|
3
|
+
export interface PiProviderLauncherOptions {
|
|
4
|
+
piBin: string;
|
|
5
|
+
profileDbPath: string;
|
|
6
|
+
providerId: ModelProviderId;
|
|
7
|
+
modelId: string;
|
|
8
|
+
sessionDir: string;
|
|
9
|
+
secretServicePrefix?: string;
|
|
10
|
+
piArgs: string[];
|
|
11
|
+
}
|
|
12
|
+
export declare function parsePiProviderLauncherOptions(args: string[]): PiProviderLauncherOptions;
|
|
13
|
+
/**
|
|
14
|
+
* Resolve only the credential the validated profile requires. In particular,
|
|
15
|
+
* an auth-free local provider must remain usable on hosts without an OS
|
|
16
|
+
* credential backend; constructing a keychain there would invent a false
|
|
17
|
+
* dependency and turn an explicit `auth_mode: none` into a hidden fallback.
|
|
18
|
+
*/
|
|
19
|
+
export declare function resolvePiProviderSecret(profile: ModelProviderProfile, createStore: () => SecretStore): Promise<string | undefined>;
|
|
20
|
+
/** Build Pi's child environment from a closed platform baseline plus one exact key. */
|
|
21
|
+
export declare function buildPiProviderChildEnvironment(options: {
|
|
22
|
+
ambient: NodeJS.ProcessEnv;
|
|
23
|
+
projectionDir: string;
|
|
24
|
+
sessionDir: string;
|
|
25
|
+
secret: string | undefined;
|
|
26
|
+
platform?: NodeJS.Platform;
|
|
27
|
+
}): Record<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Create the configured session directory owner-only without mutating the
|
|
30
|
+
* mode of an existing host-owned directory. The path is operator config, so
|
|
31
|
+
* an accidental `/`, home, or shared-directory value must never become a
|
|
32
|
+
* recursive chmod sink.
|
|
33
|
+
*/
|
|
34
|
+
export declare function ensurePiSessionDirectory(sessionDir: string): Promise<void>;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ModelProviderProfile } from './provider-profile';
|
|
2
|
+
export declare const PI_PROJECTED_KEY_ENV = "PI_PROVIDER_API_KEY";
|
|
3
|
+
/** Keep projected providers disjoint from Pi built-ins so composition can never fall back to one. */
|
|
4
|
+
export declare function piProjectionProviderId(profileProviderId: string): string;
|
|
5
|
+
/** Credential-blind Pi configuration derived from one validated local profile. */
|
|
6
|
+
export declare function buildPiProviderProjection(profile: ModelProviderProfile): object;
|
|
7
|
+
/**
|
|
8
|
+
* Validate the credential-blind RPC argv the client may delegate, then bind
|
|
9
|
+
* the Pi child to the namespaced projection and exact configured model.
|
|
10
|
+
*/
|
|
11
|
+
export declare function buildPiProviderArgs(profile: ModelProviderProfile, delegatedArgs: readonly string[]): string[];
|
package/dist/profile-store.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { type ModelProviderId, type ModelProviderProfile } from './provider-prof
|
|
|
4
4
|
* Storage contract for provider profiles — everything needed to address a
|
|
5
5
|
* provider except the API key, which lives in a {@link SecretStore}.
|
|
6
6
|
*
|
|
7
|
-
* Shaped after `@byok/server`'s `TaskStore` (`packages/server/src/task-store.ts`)
|
|
7
|
+
* Shaped after `@byok-sdk/server`'s `TaskStore` (`packages/server/src/task-store.ts`)
|
|
8
8
|
* as a *pattern*, not a dependency: `keys` must not import `server`, and
|
|
9
9
|
* `server` must not import `keys` (the plan's Security Boundary keeps the
|
|
10
10
|
* agent-dispatch packages free of any credential-adjacent code).
|
|
@@ -22,22 +22,22 @@ import { type ModelProviderId, type ModelProviderProfile } from './provider-prof
|
|
|
22
22
|
*/
|
|
23
23
|
export interface ProviderProfileStore {
|
|
24
24
|
/** Release the underlying resource. Safe to call more than once. */
|
|
25
|
-
close(): void
|
|
25
|
+
close(): Promise<void>;
|
|
26
26
|
/** Remove `providerId`; `false` when it was not configured. */
|
|
27
|
-
delete(providerId: ModelProviderId): boolean
|
|
27
|
+
delete(providerId: ModelProviderId): Promise<boolean>;
|
|
28
28
|
/** Read one provider's profile, configured or not enabled alike. */
|
|
29
|
-
get(providerId: ModelProviderId): ModelProviderProfile | undefined
|
|
29
|
+
get(providerId: ModelProviderId): Promise<ModelProviderProfile | undefined>;
|
|
30
30
|
/** The single enabled profile, or `undefined` when none is enabled. */
|
|
31
|
-
getEnabled(): ModelProviderProfile | undefined
|
|
31
|
+
getEnabled(): Promise<ModelProviderProfile | undefined>;
|
|
32
32
|
/** Every configured profile, ordered by provider id. */
|
|
33
|
-
list(): ModelProviderProfile[]
|
|
33
|
+
list(): Promise<ModelProviderProfile[]>;
|
|
34
34
|
/** Insert or update `profile`, enforcing both invariants above. */
|
|
35
|
-
save(profile: ModelProviderProfile): ModelProviderProfile
|
|
35
|
+
save(profile: ModelProviderProfile): Promise<ModelProviderProfile>;
|
|
36
36
|
/**
|
|
37
37
|
* Make `providerId` the enabled profile. Throws `PROVIDER_NOT_CONFIGURED`
|
|
38
38
|
* when it has no profile — a fail-closed port of `providers.ts:1243-1250`.
|
|
39
39
|
*/
|
|
40
|
-
setEnabled(providerId: ModelProviderId): ModelProviderProfile
|
|
40
|
+
setEnabled(providerId: ModelProviderId): Promise<ModelProviderProfile>;
|
|
41
41
|
}
|
|
42
42
|
/** Shared by both implementations so their error text cannot drift apart. */
|
|
43
43
|
export declare function providerNotConfigured(providerId: ModelProviderId): ByokKeysError;
|
|
@@ -45,17 +45,17 @@ export declare function providerNotConfigured(providerId: ModelProviderId): Byok
|
|
|
45
45
|
* Profile store held in process memory: the default, and the one every test
|
|
46
46
|
* that does not specifically exercise SQLite should use.
|
|
47
47
|
*
|
|
48
|
-
* Mirrors `InMemoryTaskStore`'s role in `@byok/server` — a real implementation
|
|
48
|
+
* Mirrors `InMemoryTaskStore`'s role in `@byok-sdk/server` — a real implementation
|
|
49
49
|
* of the contract, not a stub, so behaviour proven here is the behaviour the
|
|
50
50
|
* SQLite store must match (`profile-store.test.ts` runs one suite against both).
|
|
51
51
|
*/
|
|
52
52
|
export declare class InMemoryProviderProfileStore implements ProviderProfileStore {
|
|
53
53
|
#private;
|
|
54
|
-
close(): void
|
|
55
|
-
delete(providerId: ModelProviderId): boolean
|
|
56
|
-
get(providerId: ModelProviderId): ModelProviderProfile | undefined
|
|
57
|
-
getEnabled(): ModelProviderProfile | undefined
|
|
58
|
-
list(): ModelProviderProfile[]
|
|
59
|
-
save(profile: ModelProviderProfile): ModelProviderProfile
|
|
60
|
-
setEnabled(providerId: ModelProviderId): ModelProviderProfile
|
|
54
|
+
close(): Promise<void>;
|
|
55
|
+
delete(providerId: ModelProviderId): Promise<boolean>;
|
|
56
|
+
get(providerId: ModelProviderId): Promise<ModelProviderProfile | undefined>;
|
|
57
|
+
getEnabled(): Promise<ModelProviderProfile | undefined>;
|
|
58
|
+
list(): Promise<ModelProviderProfile[]>;
|
|
59
|
+
save(profile: ModelProviderProfile): Promise<ModelProviderProfile>;
|
|
60
|
+
setEnabled(providerId: ModelProviderId): Promise<ModelProviderProfile>;
|
|
61
61
|
}
|
package/dist/registry.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export interface ProviderRegistryOptions {
|
|
|
75
75
|
export declare class ProviderRegistry {
|
|
76
76
|
#private;
|
|
77
77
|
constructor(options: ProviderRegistryOptions);
|
|
78
|
-
close(): void
|
|
78
|
+
close(): Promise<void>;
|
|
79
79
|
/**
|
|
80
80
|
* Persist a provider's profile and, when supplied, its secret
|
|
81
81
|
* (`providers.ts:1180-1229`).
|
|
@@ -4,12 +4,14 @@ export interface SqliteProviderProfileStoreOptions {
|
|
|
4
4
|
/**
|
|
5
5
|
* Database file path. `:memory:` exercises the SQLite code path without a
|
|
6
6
|
* temp file, but defeats the point of this store (restart-safety) exactly as
|
|
7
|
-
* it does for `@byok/server`'s `SqliteTaskStore`.
|
|
7
|
+
* it does for `@byok-sdk/server`'s `SqliteTaskStore`.
|
|
8
8
|
*/
|
|
9
9
|
path: string;
|
|
10
|
+
/** Open an existing profile database without creating or mutating it. */
|
|
11
|
+
readOnly?: boolean;
|
|
10
12
|
}
|
|
11
13
|
/**
|
|
12
|
-
* SQLite-backed {@link ProviderProfileStore}, following `@byok/server`'s
|
|
14
|
+
* SQLite-backed {@link ProviderProfileStore}, following `@byok-sdk/server`'s
|
|
13
15
|
* `SqliteTaskStore` shape. Holds no secret: the API key lives in the injected
|
|
14
16
|
* `SecretStore`, and `registry.golden.test.ts` asserts the plaintext key never
|
|
15
17
|
* appears in this file's bytes.
|
|
@@ -23,13 +25,13 @@ export declare class SqliteProviderProfileStore implements ProviderProfileStore
|
|
|
23
25
|
* routinely closed both by the code that finished with it and by a test's
|
|
24
26
|
* teardown.
|
|
25
27
|
*/
|
|
26
|
-
close(): void
|
|
27
|
-
delete(providerId: ModelProviderId): boolean
|
|
28
|
-
get(providerId: ModelProviderId): ModelProviderProfile | undefined
|
|
29
|
-
getEnabled(): ModelProviderProfile | undefined
|
|
30
|
-
list(): ModelProviderProfile[]
|
|
31
|
-
save(profile: ModelProviderProfile): ModelProviderProfile
|
|
32
|
-
setEnabled(providerId: ModelProviderId): ModelProviderProfile
|
|
28
|
+
close(): Promise<void>;
|
|
29
|
+
delete(providerId: ModelProviderId): Promise<boolean>;
|
|
30
|
+
get(providerId: ModelProviderId): Promise<ModelProviderProfile | undefined>;
|
|
31
|
+
getEnabled(): Promise<ModelProviderProfile | undefined>;
|
|
32
|
+
list(): Promise<ModelProviderProfile[]>;
|
|
33
|
+
save(profile: ModelProviderProfile): Promise<ModelProviderProfile>;
|
|
34
|
+
setEnabled(providerId: ModelProviderId): Promise<ModelProviderProfile>;
|
|
33
35
|
}
|
|
34
36
|
/** Exported for the store's own tests to enumerate the CHECK-constrained ids. */
|
|
35
37
|
export declare const SQLITE_PROFILE_PROVIDER_IDS: readonly ["openai", "deepseek", "anthropic", "custom"];
|
package/dist/sqlite-support.d.ts
CHANGED
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import type { DatabaseSync, DatabaseSyncOptions } from 'node:sqlite';
|
|
2
|
+
export type SqliteOpenStep = 'after-open' | 'after-wal' | 'after-synchronous';
|
|
3
|
+
/** Test-only seam for proving that post-open initialization failures release the native handle. */
|
|
4
|
+
export interface SqliteOpenFaultSeam {
|
|
5
|
+
onStep?(step: SqliteOpenStep): void;
|
|
6
|
+
close?(database: DatabaseSync): void;
|
|
7
|
+
}
|
|
8
|
+
/** Release an opened handle before propagating an initialization failure. */
|
|
9
|
+
export declare function closeSqliteDatabaseAfterInitializationFailure(database: DatabaseSync, initializationError: unknown, message: string, close?: (database: DatabaseSync) => void): never;
|
|
2
10
|
interface SqliteModule {
|
|
3
11
|
DatabaseSync: new (path: string, options?: DatabaseSyncOptions) => DatabaseSync;
|
|
4
12
|
}
|
|
@@ -7,7 +15,7 @@ interface SqliteModule {
|
|
|
7
15
|
*
|
|
8
16
|
* `node:sqlite` shipped in Node.js 22.5.0 and stays marked experimental (an
|
|
9
17
|
* `ExperimentalWarning` on stderr is expected and harmless). Following
|
|
10
|
-
* `@byok/server`'s `sqlite-support.ts`, the SQLite-backed store here depends on
|
|
18
|
+
* `@byok-sdk/server`'s `sqlite-support.ts`, the SQLite-backed store here depends on
|
|
11
19
|
* nothing else — no `better-sqlite3`, no native module — because zero native
|
|
12
20
|
* dependencies is what keeps this package trivially packageable. The tradeoff
|
|
13
21
|
* is that {@link SqliteProviderProfileStore} does not work below Node 22.5, and
|
|
@@ -18,7 +26,7 @@ export declare function loadSqliteModule(): SqliteModule;
|
|
|
18
26
|
/**
|
|
19
27
|
* Whether `node:sqlite` can ACTUALLY be loaded right now.
|
|
20
28
|
*
|
|
21
|
-
* Same predicate as `@byok/server`'s `sqlite-support.ts`, and it exists for the
|
|
29
|
+
* Same predicate as `@byok-sdk/server`'s `sqlite-support.ts`, and it exists for the
|
|
22
30
|
* same reason: this package's `engines.node` is `>=20` and CI runs the matrix
|
|
23
31
|
* on 20 and 22, but `node:sqlite` shipped in 22.5 and stayed behind
|
|
24
32
|
* `--experimental-sqlite` for part of the 22.x line. A version-number
|
|
@@ -35,7 +43,7 @@ export declare function isSqliteAvailable(): boolean;
|
|
|
35
43
|
* skips every filesystem step, which is how the shared contract suite exercises
|
|
36
44
|
* the SQLite code path without leaving anything on disk.
|
|
37
45
|
*/
|
|
38
|
-
export declare function openSqliteDatabase(path: string, options?: DatabaseSyncOptions): DatabaseSync;
|
|
46
|
+
export declare function openSqliteDatabase(path: string, options?: DatabaseSyncOptions, faults?: SqliteOpenFaultSeam): DatabaseSync;
|
|
39
47
|
/**
|
|
40
48
|
* Restrict `databasePath` and its WAL/SHM siblings to owner-only read/write.
|
|
41
49
|
*
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type TenantId, type TruthStore } from '@byok-sdk/core';
|
|
2
|
+
import { type ProviderProfileStore } from './profile-store';
|
|
3
|
+
import { type ModelProviderId, type ModelProviderProfile } from './provider-profile';
|
|
4
|
+
export declare const PROVIDER_PROFILE_TRUTH_RECORD_KEY = "byok-sdk.keys/model-provider-registry-v1";
|
|
5
|
+
export interface TruthStoreProviderProfileStoreOptions {
|
|
6
|
+
tenant: TenantId;
|
|
7
|
+
truthStore: TruthStore;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Tenant-bound profile persistence over the core TruthStore snapshot contract.
|
|
11
|
+
*
|
|
12
|
+
* The complete, closed provider registry is one CAS unit. That is what makes a
|
|
13
|
+
* delete and the "at most one enabled profile" transition atomic without
|
|
14
|
+
* adding a second transaction authority. The body is metadata only; provider
|
|
15
|
+
* credentials remain exclusively in the independently injected SecretStore.
|
|
16
|
+
*/
|
|
17
|
+
export declare class TruthStoreProviderProfileStore implements ProviderProfileStore {
|
|
18
|
+
#private;
|
|
19
|
+
constructor(options: TruthStoreProviderProfileStoreOptions);
|
|
20
|
+
close(): Promise<void>;
|
|
21
|
+
delete(providerId: ModelProviderId): Promise<boolean>;
|
|
22
|
+
get(providerId: ModelProviderId): Promise<ModelProviderProfile | undefined>;
|
|
23
|
+
getEnabled(): Promise<ModelProviderProfile | undefined>;
|
|
24
|
+
list(): Promise<ModelProviderProfile[]>;
|
|
25
|
+
save(profile: ModelProviderProfile): Promise<ModelProviderProfile>;
|
|
26
|
+
setEnabled(providerId: ModelProviderId): Promise<ModelProviderProfile>;
|
|
27
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@byok-sdk/keys",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "BYOK SDK key management: provider profiles, credential-backed auth headers, and direct provider transports",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,12 +14,15 @@
|
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://github.com/Ancienttwo/byok-sdk#readme",
|
|
16
16
|
"engines": {
|
|
17
|
-
"node": ">=
|
|
17
|
+
"node": ">=22.22.0"
|
|
18
18
|
},
|
|
19
19
|
"sideEffects": false,
|
|
20
20
|
"main": "./dist/index.js",
|
|
21
21
|
"module": "./dist/index.js",
|
|
22
22
|
"types": "./dist/index.d.ts",
|
|
23
|
+
"bin": {
|
|
24
|
+
"byok-pi-provider-launcher": "./dist/bin/pi-provider-launcher.js"
|
|
25
|
+
},
|
|
23
26
|
"exports": {
|
|
24
27
|
".": {
|
|
25
28
|
"types": "./dist/index.d.ts",
|
|
@@ -28,20 +31,24 @@
|
|
|
28
31
|
"./package.json": "./package.json"
|
|
29
32
|
},
|
|
30
33
|
"files": [
|
|
31
|
-
"dist"
|
|
34
|
+
"dist",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE"
|
|
32
37
|
],
|
|
33
38
|
"publishConfig": {
|
|
34
39
|
"access": "public"
|
|
35
40
|
},
|
|
36
|
-
"dependencies": {
|
|
37
|
-
"zod": "^4.4.3"
|
|
38
|
-
},
|
|
39
41
|
"scripts": {
|
|
42
|
+
"prepublishOnly": "bun run build",
|
|
40
43
|
"build": "tsup && tsc -p tsconfig.build.json",
|
|
41
44
|
"dev": "tsup --watch",
|
|
42
45
|
"test": "vitest run",
|
|
43
46
|
"test:watch": "vitest",
|
|
44
47
|
"typecheck": "tsc --noEmit",
|
|
45
48
|
"clean": "rm -rf dist"
|
|
49
|
+
},
|
|
50
|
+
"dependencies": {
|
|
51
|
+
"@byok-sdk/core": "0.4.2",
|
|
52
|
+
"zod": "^4.4.3"
|
|
46
53
|
}
|
|
47
|
-
}
|
|
54
|
+
}
|