@book.dev/sdk 3.8.0 → 3.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/dist/ai.d.ts +12 -2
- package/dist/ai.js.map +1 -1
- package/dist/blockCatalogue.d.ts +560 -0
- package/dist/blockCatalogue.js +336 -0
- package/dist/blockCatalogue.js.map +1 -0
- package/dist/bookFolder.d.ts +9 -1
- package/dist/bookFolder.js +64 -2
- package/dist/bookFolder.js.map +1 -1
- package/dist/client.d.ts +22 -2
- package/dist/client.js +6 -2
- package/dist/client.js.map +1 -1
- package/dist/content.d.ts +40 -1
- package/dist/content.js +29 -7
- package/dist/content.js.map +1 -1
- package/dist/forwarding/forwardingClient.d.ts +68 -2
- package/dist/forwarding/forwardingClient.js +126 -12
- package/dist/forwarding/forwardingClient.js.map +1 -1
- package/dist/forwarding/index.d.ts +2 -1
- package/dist/forwarding/index.js +2 -1
- package/dist/forwarding/index.js.map +1 -1
- package/dist/forwarding/namespacedKeyStore.d.ts +52 -0
- package/dist/forwarding/namespacedKeyStore.js +99 -0
- package/dist/forwarding/namespacedKeyStore.js.map +1 -0
- package/dist/index.d.ts +10 -5
- package/dist/index.js +10 -5
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +29 -0
- package/dist/ledger.js +43 -0
- package/dist/ledger.js.map +1 -1
- package/dist/ledgerExportSection.d.ts +160 -0
- package/dist/ledgerExportSection.js +594 -0
- package/dist/ledgerExportSection.js.map +1 -0
- package/dist/orderKeys.d.ts +36 -0
- package/dist/orderKeys.js +88 -0
- package/dist/orderKeys.js.map +1 -0
- package/dist/plugins.d.ts +79 -8
- package/dist/plugins.js +98 -16
- package/dist/plugins.js.map +1 -1
- package/dist/provenance.d.ts +13 -0
- package/dist/registryClient.d.ts +227 -0
- package/dist/registryClient.js +397 -0
- package/dist/registryClient.js.map +1 -0
- package/dist/routes.d.ts +9 -0
- package/dist/routes.js +9 -0
- package/dist/routes.js.map +1 -1
- package/dist/suggestions.d.ts +12 -2
- package/dist/tableSnapshot.d.ts +233 -0
- package/dist/tableSnapshot.js +680 -0
- package/dist/tableSnapshot.js.map +1 -0
- package/dist/templates.d.ts +8 -0
- package/dist/templates.js +7 -2
- package/dist/templates.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fractional order keys — pure, dependency-free (TBL-1).
|
|
3
|
+
*
|
|
4
|
+
* A key is a non-empty string over the base-62 alphabet `0-9A-Za-z` whose
|
|
5
|
+
* plain lexicographic order IS its numeric order: read it as a fraction in
|
|
6
|
+
* (0, 1) written in base 62 (`'V'` ≈ 0.5, `'0V'` ≈ 0.008…). The ASCII order
|
|
7
|
+
* of the alphabet matches its digit order, so `a < b` on the raw strings is
|
|
8
|
+
* the whole comparator — no parsing, ever.
|
|
9
|
+
*
|
|
10
|
+
* Invariant: a key never ends with the zero digit `'0'`. That guarantees any
|
|
11
|
+
* two distinct keys (and either open end) always have a midpoint, so a move
|
|
12
|
+
* only ever writes ONE small string — the mover's new key — and never has to
|
|
13
|
+
* renumber neighbours. Keys grow ~1 character per ~5 inserts into the same
|
|
14
|
+
* gap (worst case); callers that see a key longer than
|
|
15
|
+
* {@link ORDER_KEY_REBALANCE_LENGTH} should rewrite the whole axis with
|
|
16
|
+
* {@link keysBetween} (see `model.ts` table ops for the pattern).
|
|
17
|
+
*/
|
|
18
|
+
/** Keys longer than this ask the owning axis for a rebalance (rare). */
|
|
19
|
+
export declare const ORDER_KEY_REBALANCE_LENGTH = 48;
|
|
20
|
+
/** True for a well-formed order key (base-62, non-empty, no trailing zero). */
|
|
21
|
+
export declare function isOrderKey(value: unknown): value is string;
|
|
22
|
+
/** Lexicographic comparator (identical to `<` on the raw strings). */
|
|
23
|
+
export declare function compareOrderKeys(a: string, b: string): number;
|
|
24
|
+
/**
|
|
25
|
+
* A key strictly between `a` and `b` (`null` = the open end of the axis).
|
|
26
|
+
* Throws on malformed keys or `a >= b` — callers own their bounds (the table
|
|
27
|
+
* ops fall back to a full-axis rebalance instead of passing bad bounds).
|
|
28
|
+
*/
|
|
29
|
+
export declare function keyBetween(a: string | null, b: string | null): string;
|
|
30
|
+
/**
|
|
31
|
+
* `n` fresh keys strictly between `a` and `b`, in ascending order — balanced
|
|
32
|
+
* binary subdivision, so lengths stay ~log₆₂(n). Deterministic: the same
|
|
33
|
+
* bounds and count always produce the same keys (two peers migrating the same
|
|
34
|
+
* legacy table concurrently write identical values and converge trivially).
|
|
35
|
+
*/
|
|
36
|
+
export declare function keysBetween(a: string | null, b: string | null, n: number): string[];
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fractional order keys — pure, dependency-free (TBL-1).
|
|
3
|
+
*
|
|
4
|
+
* A key is a non-empty string over the base-62 alphabet `0-9A-Za-z` whose
|
|
5
|
+
* plain lexicographic order IS its numeric order: read it as a fraction in
|
|
6
|
+
* (0, 1) written in base 62 (`'V'` ≈ 0.5, `'0V'` ≈ 0.008…). The ASCII order
|
|
7
|
+
* of the alphabet matches its digit order, so `a < b` on the raw strings is
|
|
8
|
+
* the whole comparator — no parsing, ever.
|
|
9
|
+
*
|
|
10
|
+
* Invariant: a key never ends with the zero digit `'0'`. That guarantees any
|
|
11
|
+
* two distinct keys (and either open end) always have a midpoint, so a move
|
|
12
|
+
* only ever writes ONE small string — the mover's new key — and never has to
|
|
13
|
+
* renumber neighbours. Keys grow ~1 character per ~5 inserts into the same
|
|
14
|
+
* gap (worst case); callers that see a key longer than
|
|
15
|
+
* {@link ORDER_KEY_REBALANCE_LENGTH} should rewrite the whole axis with
|
|
16
|
+
* {@link keysBetween} (see `model.ts` table ops for the pattern).
|
|
17
|
+
*/
|
|
18
|
+
const DIGITS = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
|
|
19
|
+
const ZERO = DIGITS[0];
|
|
20
|
+
const BASE = DIGITS.length;
|
|
21
|
+
/** Keys longer than this ask the owning axis for a rebalance (rare). */
|
|
22
|
+
export const ORDER_KEY_REBALANCE_LENGTH = 48;
|
|
23
|
+
/** True for a well-formed order key (base-62, non-empty, no trailing zero). */
|
|
24
|
+
export function isOrderKey(value) {
|
|
25
|
+
return (typeof value === 'string' &&
|
|
26
|
+
value.length > 0 &&
|
|
27
|
+
!value.endsWith(ZERO) &&
|
|
28
|
+
[...value].every((ch) => DIGITS.includes(ch)));
|
|
29
|
+
}
|
|
30
|
+
/** Lexicographic comparator (identical to `<` on the raw strings). */
|
|
31
|
+
export function compareOrderKeys(a, b) {
|
|
32
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The midpoint of two fraction strings, `a < result < b`.
|
|
36
|
+
* `a === ''` means the lower bound 0; `b === null` means the upper bound 1.
|
|
37
|
+
* Neither input may have a trailing zero digit; the result never does.
|
|
38
|
+
*/
|
|
39
|
+
function midpoint(a, b) {
|
|
40
|
+
if (b !== null) {
|
|
41
|
+
// Shared prefix passes through untouched; recurse on the differing tail.
|
|
42
|
+
let n = 0;
|
|
43
|
+
while ((a[n] ?? ZERO) === b[n])
|
|
44
|
+
n += 1;
|
|
45
|
+
if (n > 0)
|
|
46
|
+
return b.slice(0, n) + midpoint(a.slice(n), b.slice(n));
|
|
47
|
+
}
|
|
48
|
+
const digitA = a ? DIGITS.indexOf(a[0]) : 0;
|
|
49
|
+
const digitB = b !== null && b.length > 0 ? DIGITS.indexOf(b[0]) : BASE;
|
|
50
|
+
if (digitB - digitA > 1) {
|
|
51
|
+
return DIGITS[Math.round((digitA + digitB) / 2)];
|
|
52
|
+
}
|
|
53
|
+
// Consecutive leading digits: either borrow b's head (when it has a tail to
|
|
54
|
+
// stay below), or extend a's head with a midpoint above a's tail.
|
|
55
|
+
if (b !== null && b.length > 1)
|
|
56
|
+
return b[0];
|
|
57
|
+
return DIGITS[digitA] + midpoint(a.slice(1), null);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* A key strictly between `a` and `b` (`null` = the open end of the axis).
|
|
61
|
+
* Throws on malformed keys or `a >= b` — callers own their bounds (the table
|
|
62
|
+
* ops fall back to a full-axis rebalance instead of passing bad bounds).
|
|
63
|
+
*/
|
|
64
|
+
export function keyBetween(a, b) {
|
|
65
|
+
if (a !== null && !isOrderKey(a))
|
|
66
|
+
throw new RangeError(`invalid order key: ${JSON.stringify(a)}`);
|
|
67
|
+
if (b !== null && !isOrderKey(b))
|
|
68
|
+
throw new RangeError(`invalid order key: ${JSON.stringify(b)}`);
|
|
69
|
+
if (a !== null && b !== null && a >= b)
|
|
70
|
+
throw new RangeError(`order keys out of order: ${a} >= ${b}`);
|
|
71
|
+
return midpoint(a ?? '', b);
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* `n` fresh keys strictly between `a` and `b`, in ascending order — balanced
|
|
75
|
+
* binary subdivision, so lengths stay ~log₆₂(n). Deterministic: the same
|
|
76
|
+
* bounds and count always produce the same keys (two peers migrating the same
|
|
77
|
+
* legacy table concurrently write identical values and converge trivially).
|
|
78
|
+
*/
|
|
79
|
+
export function keysBetween(a, b, n) {
|
|
80
|
+
if (n <= 0)
|
|
81
|
+
return [];
|
|
82
|
+
const mid = keyBetween(a, b);
|
|
83
|
+
if (n === 1)
|
|
84
|
+
return [mid];
|
|
85
|
+
const left = (n - 1) >> 1;
|
|
86
|
+
return [...keysBetween(a, mid, left), mid, ...keysBetween(mid, b, n - 1 - left)];
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=orderKeys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orderKeys.js","sourceRoot":"","sources":["../src/orderKeys.ts"],"names":[],"mappings":"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"}
|
package/dist/plugins.d.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* The plugin contract: what a plugin package IS (a manifest + TypeScript
|
|
3
3
|
* source files), and the signing scheme that lets a registry vouch for one.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Extensions run with the same access as your documents’ live code. A
|
|
6
|
+
* “Verified” badge means a registry you trust signed this exact content —
|
|
7
|
+
* provenance, not a sandbox. Unsigned plugins install fine and are labelled
|
|
8
|
+
* unverified.
|
|
9
9
|
*
|
|
10
10
|
* Signing: Ed25519 over a canonical SHA-256 digest of the manifest + every
|
|
11
11
|
* file (sorted paths, length-prefixed — byte-stable across platforms). The
|
|
@@ -66,6 +66,24 @@ export interface PluginManifest {
|
|
|
66
66
|
apiVersion?: number;
|
|
67
67
|
/** Agent tools this plugin contributes (read server-side from the manifest). */
|
|
68
68
|
agentTools?: PluginAgentTool[];
|
|
69
|
+
/**
|
|
70
|
+
* The block types this plugin registers at activation (WITHOUT the
|
|
71
|
+
* `<pluginId>/` prefix the host adds). Declared in the manifest so servers —
|
|
72
|
+
* which never run plugin code — can list a plugin's blocks (the agent/MCP
|
|
73
|
+
* `list_block_types` tool) straight from the stored manifest JSON. Optional:
|
|
74
|
+
* a plugin that declares none still works, its block types are simply not
|
|
75
|
+
* enumerable server-side. For bundled first-party plugins the declaration is
|
|
76
|
+
* verified against the source's `blocks.register` calls at bundle time
|
|
77
|
+
* (packages/ui/scripts/bundlePlugins.ts), so it cannot drift.
|
|
78
|
+
*/
|
|
79
|
+
blocks?: PluginBlockDeclaration[];
|
|
80
|
+
}
|
|
81
|
+
/** One manifest-declared plugin block (see {@link PluginManifest.blocks}). */
|
|
82
|
+
export interface PluginBlockDeclaration {
|
|
83
|
+
/** The unprefixed block type, e.g. `journal-entry`. */
|
|
84
|
+
type: string;
|
|
85
|
+
/** One-line description surfaced by `list_block_types`. */
|
|
86
|
+
description?: string;
|
|
69
87
|
}
|
|
70
88
|
/**
|
|
71
89
|
* The host-side activation gate for {@link PluginManifest.apiVersion}:
|
|
@@ -97,6 +115,21 @@ export interface StoredPlugin extends PluginPackage {
|
|
|
97
115
|
/** Set by the client after verification — never trusted from the wire. */
|
|
98
116
|
verified?: boolean;
|
|
99
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Canonical JSON for signing: objects emit ALL keys, sorted, at EVERY depth;
|
|
120
|
+
* arrays are positional; primitives follow JSON.stringify semantics.
|
|
121
|
+
* `undefined`, functions, and symbols are rejected outright (never silently
|
|
122
|
+
* dropped) — anything the signer skips is something an attacker can vary for
|
|
123
|
+
* free.
|
|
124
|
+
*
|
|
125
|
+
* Deliberately NOT `JSON.stringify(value, sortedKeysArray)`: a replacer ARRAY
|
|
126
|
+
* allowlists those keys at every depth, so nested keys absent from the top
|
|
127
|
+
* level (e.g. `agentTools[0].action`) silently vanish from the signed bytes.
|
|
128
|
+
*
|
|
129
|
+
* Mirrored byte-for-byte by the store's server-side port
|
|
130
|
+
* (open-book-pub `packages/store/lib/canonical.ts`) — change both together.
|
|
131
|
+
*/
|
|
132
|
+
export declare function canonicalJson(value: unknown): string;
|
|
100
133
|
/** SHA-256 of the canonical bytes (hex) — the thing a registry signs. */
|
|
101
134
|
export declare function canonicalDigest(manifest: PluginManifest, files: Record<string, string>): Promise<string>;
|
|
102
135
|
/** Generate a registry keypair (raw public / pkcs8 private, base64). */
|
|
@@ -109,6 +142,14 @@ export declare function signPlugin(pkg: {
|
|
|
109
142
|
manifest: PluginManifest;
|
|
110
143
|
files: Record<string, string>;
|
|
111
144
|
}, privateKeyBase64: string, registry: string, publicKeyBase64: string): Promise<PluginSignature>;
|
|
145
|
+
/**
|
|
146
|
+
* Verify an Ed25519 signature (base64, raw 64 bytes) over a UTF-8 message
|
|
147
|
+
* with a base64 RAW 32-byte public key. Returns false — never throws — on
|
|
148
|
+
* malformed inputs. The registry protocol signs the UTF-8 bytes of the
|
|
149
|
+
* lowercase hex canonical digest with exactly this scheme, for the publisher
|
|
150
|
+
* signature, the notary countersignature, and revocation entries alike.
|
|
151
|
+
*/
|
|
152
|
+
export declare function verifyEd25519Message(publicKeyBase64: string, message: string, signatureBase64: string): Promise<boolean>;
|
|
112
153
|
/**
|
|
113
154
|
* Verify a package against a set of trusted registry keys. Returns the
|
|
114
155
|
* matching trusted registry name, or null when unsigned, signed by an
|
|
@@ -121,10 +162,40 @@ export declare function verifyPlugin(pkg: PluginPackage, trustedKeys: Array<{
|
|
|
121
162
|
registry: string;
|
|
122
163
|
} | null>;
|
|
123
164
|
/**
|
|
124
|
-
* The pinned first-party registry
|
|
125
|
-
* additional registries are user-added keys on top (Settings →
|
|
126
|
-
*
|
|
127
|
-
*
|
|
165
|
+
* The pinned first-party registry keys. Every OpenBook build trusts ALL of
|
|
166
|
+
* these; additional registries are user-added keys on top (Settings →
|
|
167
|
+
* Extensions).
|
|
168
|
+
*
|
|
169
|
+
* THIS LIST IS THE ONE PLACE THE PRODUCTION KEY(S) LIVE. The key ceremony
|
|
170
|
+
* (docs/plugin-signing.md) is: run `node scripts/gen-registry-key.mjs`, commit
|
|
171
|
+
* the printed PUBLIC key here, and store the private half as the
|
|
172
|
+
* `OPENBOOK_REGISTRY_PRIVATE_KEY` GitHub Actions secret — the release build
|
|
173
|
+
* signs the bundled first-party plugins with it (packages/ui/scripts/
|
|
174
|
+
* bundlePlugins.ts).
|
|
175
|
+
*
|
|
176
|
+
* A LIST so rotation can overlap (add-then-remove): append the NEW key as a
|
|
177
|
+
* second entry and ship — clients of that build verify signatures from either
|
|
178
|
+
* key. Once the overlap build is broadly installed, cut signing over to the
|
|
179
|
+
* new key (swap the CI secret), and a later release removes the old entry.
|
|
180
|
+
* The signing key SHOULD be entry [0]; extra entries exist only during
|
|
181
|
+
* rotation windows. Full runbook: docs/plugin-signing.md.
|
|
182
|
+
*
|
|
183
|
+
* NOTE: currently a single production key, minted 2026-08-09. Its private
|
|
184
|
+
* half is held only in the GitHub Actions `publish` environment secret
|
|
185
|
+
* `OPENBOOK_REGISTRY_PRIVATE_KEY`. No entry may EVER match
|
|
186
|
+
* scripts/test-registry-key.json (its private half is public); CI guards
|
|
187
|
+
* enforce that for every entry (.github/workflows/release.yml).
|
|
188
|
+
*/
|
|
189
|
+
export declare const OPENBOOK_REGISTRY_KEYS: Array<{
|
|
190
|
+
name: string;
|
|
191
|
+
publicKey: string;
|
|
192
|
+
}>;
|
|
193
|
+
/**
|
|
194
|
+
* The primary pinned first-party key — entry [0] of
|
|
195
|
+
* {@link OPENBOOK_REGISTRY_KEYS}.
|
|
196
|
+
* @deprecated trust decisions must consume the whole list
|
|
197
|
+
* ({@link OPENBOOK_REGISTRY_KEYS}); this alias exists for display and
|
|
198
|
+
* back-compat only.
|
|
128
199
|
*/
|
|
129
200
|
export declare const OPENBOOK_REGISTRY: {
|
|
130
201
|
name: string;
|
package/dist/plugins.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* The plugin contract: what a plugin package IS (a manifest + TypeScript
|
|
3
3
|
* source files), and the signing scheme that lets a registry vouch for one.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
5
|
+
* Extensions run with the same access as your documents’ live code. A
|
|
6
|
+
* “Verified” badge means a registry you trust signed this exact content —
|
|
7
|
+
* provenance, not a sandbox. Unsigned plugins install fine and are labelled
|
|
8
|
+
* unverified.
|
|
9
9
|
*
|
|
10
10
|
* Signing: Ed25519 over a canonical SHA-256 digest of the manifest + every
|
|
11
11
|
* file (sorted paths, length-prefixed — byte-stable across platforms). The
|
|
@@ -36,9 +36,43 @@ export function pluginApiVersionError(manifest) {
|
|
|
36
36
|
}
|
|
37
37
|
const te = new TextEncoder();
|
|
38
38
|
/**
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
39
|
+
* Canonical JSON for signing: objects emit ALL keys, sorted, at EVERY depth;
|
|
40
|
+
* arrays are positional; primitives follow JSON.stringify semantics.
|
|
41
|
+
* `undefined`, functions, and symbols are rejected outright (never silently
|
|
42
|
+
* dropped) — anything the signer skips is something an attacker can vary for
|
|
43
|
+
* free.
|
|
44
|
+
*
|
|
45
|
+
* Deliberately NOT `JSON.stringify(value, sortedKeysArray)`: a replacer ARRAY
|
|
46
|
+
* allowlists those keys at every depth, so nested keys absent from the top
|
|
47
|
+
* level (e.g. `agentTools[0].action`) silently vanish from the signed bytes.
|
|
48
|
+
*
|
|
49
|
+
* Mirrored byte-for-byte by the store's server-side port
|
|
50
|
+
* (open-book-pub `packages/store/lib/canonical.ts`) — change both together.
|
|
51
|
+
*/
|
|
52
|
+
export function canonicalJson(value) {
|
|
53
|
+
if (value === undefined || typeof value === 'function' || typeof value === 'symbol') {
|
|
54
|
+
throw new TypeError(`canonical JSON cannot contain ${typeof value}`);
|
|
55
|
+
}
|
|
56
|
+
if (value === null || typeof value !== 'object')
|
|
57
|
+
return JSON.stringify(value);
|
|
58
|
+
if (Array.isArray(value))
|
|
59
|
+
return `[${value.map((v) => canonicalJson(v)).join(',')}]`;
|
|
60
|
+
const obj = value;
|
|
61
|
+
const members = Object.keys(obj)
|
|
62
|
+
.sort()
|
|
63
|
+
.map((k) => {
|
|
64
|
+
if (obj[k] === undefined || typeof obj[k] === 'function' || typeof obj[k] === 'symbol') {
|
|
65
|
+
throw new TypeError(`canonical JSON cannot contain ${typeof obj[k]} (at key "${k}")`);
|
|
66
|
+
}
|
|
67
|
+
return `${JSON.stringify(k)}:${canonicalJson(obj[k])}`;
|
|
68
|
+
});
|
|
69
|
+
return `{${members.join(',')}}`;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Deterministic bytes for signing: the manifest (canonical JSON — keys sorted
|
|
73
|
+
* recursively, see {@link canonicalJson}), then each file in sorted path
|
|
74
|
+
* order, every part length-prefixed so boundaries can't be confused
|
|
75
|
+
* (`a + bc` ≠ `ab + c`).
|
|
42
76
|
*/
|
|
43
77
|
function canonicalBytes(manifest, files) {
|
|
44
78
|
const parts = [];
|
|
@@ -48,7 +82,7 @@ function canonicalBytes(manifest, files) {
|
|
|
48
82
|
new DataView(len.buffer).setUint32(0, bytes.length);
|
|
49
83
|
parts.push(len, bytes);
|
|
50
84
|
};
|
|
51
|
-
push(
|
|
85
|
+
push(canonicalJson(manifest));
|
|
52
86
|
for (const path of Object.keys(files).sort()) {
|
|
53
87
|
push(path);
|
|
54
88
|
push(files[path]);
|
|
@@ -83,6 +117,25 @@ export async function signPlugin(pkg, privateKeyBase64, registry, publicKeyBase6
|
|
|
83
117
|
const sig = new Uint8Array(await crypto.subtle.sign('Ed25519', key, te.encode(digest)));
|
|
84
118
|
return { registry, publicKey: publicKeyBase64, signature: toBase64(sig), algorithm: 'ed25519' };
|
|
85
119
|
}
|
|
120
|
+
/**
|
|
121
|
+
* Verify an Ed25519 signature (base64, raw 64 bytes) over a UTF-8 message
|
|
122
|
+
* with a base64 RAW 32-byte public key. Returns false — never throws — on
|
|
123
|
+
* malformed inputs. The registry protocol signs the UTF-8 bytes of the
|
|
124
|
+
* lowercase hex canonical digest with exactly this scheme, for the publisher
|
|
125
|
+
* signature, the notary countersignature, and revocation entries alike.
|
|
126
|
+
*/
|
|
127
|
+
export async function verifyEd25519Message(publicKeyBase64, message, signatureBase64) {
|
|
128
|
+
try {
|
|
129
|
+
const raw = fromBase64(publicKeyBase64);
|
|
130
|
+
if (raw.length !== 32)
|
|
131
|
+
return false;
|
|
132
|
+
const key = await crypto.subtle.importKey('raw', raw, 'Ed25519', false, ['verify']);
|
|
133
|
+
return await crypto.subtle.verify('Ed25519', key, fromBase64(signatureBase64), te.encode(message));
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
return false;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
86
139
|
/**
|
|
87
140
|
* Verify a package against a set of trusted registry keys. Returns the
|
|
88
141
|
* matching trusted registry name, or null when unsigned, signed by an
|
|
@@ -106,15 +159,44 @@ export async function verifyPlugin(pkg, trustedKeys) {
|
|
|
106
159
|
}
|
|
107
160
|
}
|
|
108
161
|
/**
|
|
109
|
-
* The pinned first-party registry
|
|
110
|
-
* additional registries are user-added keys on top (Settings →
|
|
111
|
-
*
|
|
112
|
-
*
|
|
162
|
+
* The pinned first-party registry keys. Every OpenBook build trusts ALL of
|
|
163
|
+
* these; additional registries are user-added keys on top (Settings →
|
|
164
|
+
* Extensions).
|
|
165
|
+
*
|
|
166
|
+
* THIS LIST IS THE ONE PLACE THE PRODUCTION KEY(S) LIVE. The key ceremony
|
|
167
|
+
* (docs/plugin-signing.md) is: run `node scripts/gen-registry-key.mjs`, commit
|
|
168
|
+
* the printed PUBLIC key here, and store the private half as the
|
|
169
|
+
* `OPENBOOK_REGISTRY_PRIVATE_KEY` GitHub Actions secret — the release build
|
|
170
|
+
* signs the bundled first-party plugins with it (packages/ui/scripts/
|
|
171
|
+
* bundlePlugins.ts).
|
|
172
|
+
*
|
|
173
|
+
* A LIST so rotation can overlap (add-then-remove): append the NEW key as a
|
|
174
|
+
* second entry and ship — clients of that build verify signatures from either
|
|
175
|
+
* key. Once the overlap build is broadly installed, cut signing over to the
|
|
176
|
+
* new key (swap the CI secret), and a later release removes the old entry.
|
|
177
|
+
* The signing key SHOULD be entry [0]; extra entries exist only during
|
|
178
|
+
* rotation windows. Full runbook: docs/plugin-signing.md.
|
|
179
|
+
*
|
|
180
|
+
* NOTE: currently a single production key, minted 2026-08-09. Its private
|
|
181
|
+
* half is held only in the GitHub Actions `publish` environment secret
|
|
182
|
+
* `OPENBOOK_REGISTRY_PRIVATE_KEY`. No entry may EVER match
|
|
183
|
+
* scripts/test-registry-key.json (its private half is public); CI guards
|
|
184
|
+
* enforce that for every entry (.github/workflows/release.yml).
|
|
185
|
+
*/
|
|
186
|
+
export const OPENBOOK_REGISTRY_KEYS = [
|
|
187
|
+
{
|
|
188
|
+
name: 'OpenBook Registry',
|
|
189
|
+
publicKey: '62Gry7q0cRFZFgZNFXwuB4XyVHQhGxTXuR5oqZG4eVU=',
|
|
190
|
+
},
|
|
191
|
+
];
|
|
192
|
+
/**
|
|
193
|
+
* The primary pinned first-party key — entry [0] of
|
|
194
|
+
* {@link OPENBOOK_REGISTRY_KEYS}.
|
|
195
|
+
* @deprecated trust decisions must consume the whole list
|
|
196
|
+
* ({@link OPENBOOK_REGISTRY_KEYS}); this alias exists for display and
|
|
197
|
+
* back-compat only.
|
|
113
198
|
*/
|
|
114
|
-
export const OPENBOOK_REGISTRY =
|
|
115
|
-
name: 'OpenBook Registry',
|
|
116
|
-
publicKey: 'nI4eBQzqrIyVPEmJSEzGtqC9B0+kfWTXKyN5t8Yki/E=',
|
|
117
|
-
};
|
|
199
|
+
export const OPENBOOK_REGISTRY = OPENBOOK_REGISTRY_KEYS[0];
|
|
118
200
|
const PLUGIN_ID_RE = /^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)+$/;
|
|
119
201
|
/** Validate a manifest's shape; returns a human-readable problem or null. */
|
|
120
202
|
export function validateManifest(m) {
|
package/dist/plugins.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA2BH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"plugins.js","sourceRoot":"","sources":["../src/plugins.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AA2BH;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC;AA2CpC;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAwB;IAC5D,MAAM,MAAM,GAAG,QAAQ,CAAC,UAAU,CAAC;IACnC,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,IAAI,kBAAkB;QAAE,OAAO,IAAI,CAAC;IACtE,OAAO,WAAW,QAAQ,CAAC,EAAE,0BAA0B,MAAM,4BAA4B,kBAAkB,8BAA8B,CAAC;AAC5I,CAAC;AA4BD,MAAM,EAAE,GAAG,IAAI,WAAW,EAAE,CAAC;AAE7B;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,IAAI,KAAK,KAAK,SAAS,IAAI,OAAO,KAAK,KAAK,UAAU,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACpF,MAAM,IAAI,SAAS,CAAC,iCAAiC,OAAO,KAAK,EAAE,CAAC,CAAC;IACvE,CAAC;IACD,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC9E,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;IACrF,MAAM,GAAG,GAAG,KAAgC,CAAC;IAC7C,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC;SAC7B,IAAI,EAAE;SACN,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,UAAU,IAAI,OAAO,GAAG,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;YACvF,MAAM,IAAI,SAAS,CAAC,iCAAiC,OAAO,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QACxF,CAAC;QACD,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACzD,CAAC,CAAC,CAAC;IACL,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC;AAClC,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,QAAwB,EAAE,KAA6B;IAC7E,MAAM,KAAK,GAAiB,EAAE,CAAC;IAC/B,MAAM,IAAI,GAAG,CAAC,CAAS,EAAQ,EAAE;QAC/B,MAAM,KAAK,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACzB,CAAC,CAAC;IACF,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;QAC7C,IAAI,CAAC,IAAI,CAAC,CAAC;QACX,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IAClC,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACf,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC;IACjB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,yEAAyE;AACzE,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,QAAwB,EAAE,KAA6B;IAC3F,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,QAAQ,EAAE,KAAK,CAAiB,CAAC,CAAC;IACpG,OAAO,CAAC,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACxF,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,CAAS,EAAc,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AAC/F,MAAM,QAAQ,GAAG,CAAC,CAAa,EAAU,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAE5E,wEAAwE;AACxE,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,MAAM,IAAI,GAAG,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAkB,CAAC;IACrG,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IACjF,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC;IACrF,OAAO,EAAC,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAC,CAAC;AAChE,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,GAA8D,EAC9D,gBAAwB,EACxB,QAAgB,EAChB,eAAuB;IAEvB,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,CAAC,gBAAgB,CAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7H,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAiB,CAAC,CAAC,CAAC;IACxG,OAAO,EAAC,QAAQ,EAAE,SAAS,EAAE,eAAe,EAAE,SAAS,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,SAAS,EAAC,CAAC;AAChG,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,eAAuB,EAAE,OAAe,EAAE,eAAuB;IAC1G,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;QACxC,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE;YAAE,OAAO,KAAK,CAAC;QACpC,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,GAAmB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpG,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,eAAe,CAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAiB,CAAC,CAAC;IACrI,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,GAAkB,EAClB,WAAqD;IAErD,MAAM,GAAG,GAAG,GAAG,CAAC,SAAS,CAAC;IAC1B,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,SAAS,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,GAAG,CAAC,SAAS,CAAC,CAAC;IACvE,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAiB,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC1H,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC9D,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,UAAU,CAAC,GAAG,CAAC,SAAS,CAAiB,EAAE,EAAE,CAAC,MAAM,CAAC,MAAM,CAAiB,CAAC,CAAC;QACpI,OAAO,EAAE,CAAC,CAAC,CAAC,EAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAA6C;IAC9E;QACE,IAAI,EAAE,mBAAmB;QACzB,SAAS,EAAE,8CAA8C;KAC1D;CACF,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,sBAAsB,CAAC,CAAC,CAAC,CAAC;AAE3D,MAAM,YAAY,GAAG,6CAA6C,CAAC;AAEnE,6EAA6E;AAC7E,MAAM,UAAU,gBAAgB,CAAC,CAAU;IACzC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,2CAA2C,CAAC;IACpF,MAAM,GAAG,GAAG,CAA4B,CAAC;IACzC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAI,OAAO,GAAG,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;QACxE,OAAO,wEAAwE,CAAC;IAClF,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,kBAAkB,CAAC;IACzE,IAAI,CAAC,GAAG,CAAC,OAAO,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,qBAAqB,CAAC;IAClF,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,mCAAmC,CAAC;IAC1F,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS,IAAI,CAAC,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;QACpI,OAAO,sDAAsD,CAAC;IAChE,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/provenance.d.ts
CHANGED
|
@@ -173,6 +173,19 @@ export interface InstanceInfo {
|
|
|
173
173
|
* identity and falls back to a reachability-only probe. */
|
|
174
174
|
instanceId?: string | null;
|
|
175
175
|
ownerSubject: string | null;
|
|
176
|
+
/**
|
|
177
|
+
* Whether this instance has an owner at all — WITHOUT saying who (PUB-1 / Sasha
|
|
178
|
+
* M-1). {@link ownerSubject} cannot answer this: GATE-7 nulls it for an anonymous
|
|
179
|
+
* caller on a claimed instance, so `ownerSubject === null` means either "unclaimed"
|
|
180
|
+
* or "claimed, but you may not know the owner". A client that needs the CLAIM
|
|
181
|
+
* STATE — e.g. to warn that an unclaimed library ignores `defaultVisibility`
|
|
182
|
+
* entirely (authorize rule 0 short-circuits on the guest gate alone) — must read
|
|
183
|
+
* this instead. Deliberately non-sensitive: a boolean "someone owns this" leaks no
|
|
184
|
+
* identity and no recon surface beyond what the guest gate's own behaviour already
|
|
185
|
+
* reveals. Optional: absent on a pre-PUB-1 server / a test fixture — a client then
|
|
186
|
+
* knows nothing and should stay silent rather than guess a claim state.
|
|
187
|
+
*/
|
|
188
|
+
claimed?: boolean;
|
|
176
189
|
trustedIssuers: string[];
|
|
177
190
|
/** This server's audience identifier, so a client can request an `aud`-scoped
|
|
178
191
|
* identity token (OB-177). `null` for the single-server (unscoped) model. */
|