@braidlabs/core 0.1.1 → 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.
Files changed (77) hide show
  1. package/package.json +2 -2
  2. package/src/adapters/adapter.d.ts +13 -0
  3. package/src/adapters/adapter.js.map +1 -1
  4. package/src/adapters/compat-adapter.d.ts +7 -0
  5. package/src/adapters/compat-adapter.js +24 -16
  6. package/src/adapters/compat-adapter.js.map +1 -1
  7. package/src/adapters/contract-adapter.d.ts +21 -0
  8. package/src/adapters/contract-adapter.js +71 -0
  9. package/src/adapters/contract-adapter.js.map +1 -0
  10. package/src/config.d.ts +29 -0
  11. package/src/config.js +16 -0
  12. package/src/config.js.map +1 -1
  13. package/src/context/context-bus.d.ts +63 -3
  14. package/src/context/context-bus.js +147 -61
  15. package/src/context/context-bus.js.map +1 -1
  16. package/src/elements/fragment-slot.d.ts +114 -1
  17. package/src/elements/fragment-slot.js +743 -60
  18. package/src/elements/fragment-slot.js.map +1 -1
  19. package/src/env/create-env.d.ts +20 -8
  20. package/src/env/create-env.js +48 -16
  21. package/src/env/create-env.js.map +1 -1
  22. package/src/env/define-fragment.d.ts +43 -0
  23. package/src/env/define-fragment.js +23 -0
  24. package/src/env/define-fragment.js.map +1 -0
  25. package/src/env/fragment-env.d.ts +20 -1
  26. package/src/env/fragment-env.js +0 -12
  27. package/src/env/fragment-env.js.map +1 -1
  28. package/src/errors.d.ts +1 -1
  29. package/src/errors.js.map +1 -1
  30. package/src/index.d.ts +14 -1
  31. package/src/index.js +7 -1
  32. package/src/index.js.map +1 -1
  33. package/src/protocol.d.ts +20 -4
  34. package/src/protocol.js +23 -7
  35. package/src/protocol.js.map +1 -1
  36. package/src/realm/realm-manager.d.ts +19 -2
  37. package/src/realm/realm-manager.js +32 -7
  38. package/src/realm/realm-manager.js.map +1 -1
  39. package/src/realm/sandbox-realm.d.ts +95 -0
  40. package/src/realm/sandbox-realm.js +194 -0
  41. package/src/realm/sandbox-realm.js.map +1 -0
  42. package/src/weave/capabilities.d.ts +71 -0
  43. package/src/weave/capabilities.js +61 -0
  44. package/src/weave/capabilities.js.map +1 -0
  45. package/src/weave/channel.d.ts +63 -0
  46. package/src/weave/channel.js +189 -0
  47. package/src/weave/channel.js.map +1 -0
  48. package/src/weave/closing.d.ts +99 -0
  49. package/src/weave/closing.js +130 -0
  50. package/src/weave/closing.js.map +1 -0
  51. package/src/weave/context-bridge.d.ts +81 -0
  52. package/src/weave/context-bridge.js +145 -0
  53. package/src/weave/context-bridge.js.map +1 -0
  54. package/src/weave/contract.d.ts +89 -0
  55. package/src/weave/contract.js +143 -0
  56. package/src/weave/contract.js.map +1 -0
  57. package/src/weave/envelope.d.ts +80 -0
  58. package/src/weave/envelope.js +49 -0
  59. package/src/weave/envelope.js.map +1 -0
  60. package/src/weave/guest.d.ts +59 -0
  61. package/src/weave/guest.js +120 -0
  62. package/src/weave/guest.js.map +1 -0
  63. package/src/weave/handshake.d.ts +124 -0
  64. package/src/weave/handshake.js +109 -0
  65. package/src/weave/handshake.js.map +1 -0
  66. package/src/weave/liveness.d.ts +90 -0
  67. package/src/weave/liveness.js +189 -0
  68. package/src/weave/liveness.js.map +1 -0
  69. package/src/weave/messages.d.ts +27 -0
  70. package/src/weave/messages.js +13 -0
  71. package/src/weave/messages.js.map +1 -0
  72. package/src/weave/port-backing.d.ts +19 -0
  73. package/src/weave/port-backing.js +54 -0
  74. package/src/weave/port-backing.js.map +1 -0
  75. package/src/weave/same-realm-backing.d.ts +21 -0
  76. package/src/weave/same-realm-backing.js +44 -0
  77. package/src/weave/same-realm-backing.js.map +1 -0
@@ -1,5 +1,5 @@
1
1
  import { BraidError } from '../errors.js';
2
- import { isDevMode } from '../config.js';
2
+ import { getBraidConfig, isDevMode } from '../config.js';
3
3
  import { BRAID_ADAPTER_META, BRAID_ADAPTER_OPTIONS_META, BRAID_PROTOCOL_META, BRAID_PROTOCOL_VERSION, braidFragmentUrl, braidRealmUrl, } from '../protocol.js';
4
4
  export async function createRealm(kind, init) {
5
5
  switch (kind) {
@@ -8,10 +8,16 @@ export async function createRealm(kind, init) {
8
8
  case 'contract-blob':
9
9
  return createContractBlobRealm(init);
10
10
  case 'sandbox':
11
- throw new BraidError('the sandbox realm kind (untrusted tier) is not available in this build', {
11
+ /**
12
+ * Not a failure any more — a redirection. The untrusted tier is built, but it is not a
13
+ * `RealmHandle`: `window`, `document` and `evaluate()` are same-origin capabilities that a
14
+ * cross-origin frame cannot offer, and faking them is the illusion that tier exists to
15
+ * refuse. See `createSandboxRealm`.
16
+ */
17
+ throw new BraidError('untrusted fragments are not created through createRealm()', {
12
18
  fragmentId: init.fragmentId,
13
19
  stage: 'realm-boot',
14
- fixHint: 'this build ships the trusted tier only — trusted realms are namespace isolation, not a security boundary',
20
+ fixHint: 'mount it as <fragment-slot trust="untrusted" src="https://…">, or call createSandboxRealm() directly',
15
21
  });
16
22
  default:
17
23
  throw new BraidError(`unknown realm kind "${kind}"`, {
@@ -38,7 +44,7 @@ async function createContractBlobRealm(init) {
38
44
  const { fragmentId, importMap } = init;
39
45
  // The base href must be absolute: a blob: URL has an opaque path, so a root-relative href
40
46
  // has nothing meaningful to resolve against.
41
- const baseHref = new URL(braidFragmentUrl(fragmentId, '/'), location.origin).href;
47
+ const baseHref = init.baseHref ?? new URL(braidFragmentUrl(fragmentId, '/', '', getBraidConfig().basePath), location.origin).href;
42
48
  const realmDocumentHtml = `<!doctype html><meta charset="utf-8"><title>Braid realm: ${escapeHtml(fragmentId)}</title>` +
43
49
  `<meta name="${BRAID_PROTOCOL_META}" content="${BRAID_PROTOCOL_VERSION}">` +
44
50
  `<base href="${escapeHtml(baseHref)}">` +
@@ -216,8 +222,11 @@ async function createCompatHttpRealm(init) {
216
222
  */
217
223
  const iframe = document.createElement('iframe');
218
224
  iframe.hidden = true;
219
- // the realm stub has its own namespace, so the fragment's asset URLs carry no header variance
220
- iframe.src = braidRealmUrl(fragmentId, routeSrcUrl.pathname, routeSrcUrl.search);
225
+ // The realm stub has its own namespace, so the fragment's asset URLs carry no header variance.
226
+ // One stub per fragment, whatever the route: its only route-dependent part is `<base>`, which is
227
+ // set below. A stub per route and query was a cold request on every new page or `?utm=` — and a
228
+ // URL no precache could name in advance.
229
+ iframe.src = braidRealmUrl(fragmentId, '/', '', getBraidConfig().basePath);
221
230
  iframe.name = `braid:${fragmentId}`;
222
231
  const { promise: loaded, resolve: resolveLoaded, reject: rejectLoaded } = Promise.withResolvers();
223
232
  let alreadyLoaded = false;
@@ -246,6 +255,7 @@ async function createCompatHttpRealm(init) {
246
255
  alreadyLoaded = true;
247
256
  try {
248
257
  verifyRealmStub(iframe, fragmentId);
258
+ pointStubAtRoute(iframe.contentDocument, braidFragmentUrl(fragmentId, routeSrcUrl.pathname, '', getBraidConfig().basePath));
249
259
  // Restore the fragment's route-url illusion: the iframe was loaded from the gateway
250
260
  // namespace, but the fragment's JS context must observe the route url as its location.
251
261
  // The stub's <base> element is unaffected by replaceState and keeps relative url
@@ -266,6 +276,20 @@ async function createCompatHttpRealm(init) {
266
276
  init.signal.addEventListener('abort', () => handle.dispose(), { once: true });
267
277
  return handle;
268
278
  }
279
+ /**
280
+ * Points a realm stub's relative urls at the route's directory in the fragment namespace, exactly
281
+ * as a stub fetched at the route would have. Nothing in the stub has resolved a url yet, so this is
282
+ * indistinguishable from the gateway having written it. A stub without a `<base>` — a hand-rolled
283
+ * one, say — gets one, rather than resolving everything against the stub's own url.
284
+ */
285
+ export function pointStubAtRoute(stubDocument, href) {
286
+ let base = stubDocument.querySelector('base');
287
+ if (!base) {
288
+ base = stubDocument.createElement('base');
289
+ stubDocument.head.append(base);
290
+ }
291
+ base.setAttribute('href', href);
292
+ }
269
293
  /**
270
294
  * Verifies the loaded iframe document is the gateway's realm stub for this protocol version.
271
295
  * This replaces title-check heuristics with explicit version negotiation: mismatches and
@@ -289,7 +313,8 @@ function verifyRealmStub(iframe, fragmentId) {
289
313
  stage: 'realm-boot',
290
314
  fixHint: protocol
291
315
  ? 'upgrade @braidlabs/core and @braidlabs/gateway to the same package version'
292
- : `ensure the braid gateway is mounted in front of this app and has a manifest registered for fragment id "${fragmentId}"`,
316
+ : `ensure the braid gateway is mounted in front of this app and has a manifest registered for fragment id "${fragmentId}", ` +
317
+ `and that initBraid({ basePath }) matches the gateway's basePath`,
293
318
  });
294
319
  }
295
320
  }
@@ -1 +1 @@
1
- {"version":3,"file":"realm-manager.js","sourceRoot":"","sources":["../../../../../libs/core/src/realm/realm-manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"realm-manager.js","sourceRoot":"","sources":["../../../../../libs/core/src/realm/realm-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * The untrusted tier: a real cross-origin iframe, with a good protocol on it.
3
+ *
4
+ * That sentence is the honest description and it is worth leading with, because Braid's own
5
+ * documentation has been quietly implying otherwise. The trusted tier's advantages — one document,
6
+ * one layout, one accessibility tree, SSR piercing, printing, DOM projection — are consequences of
7
+ * *sharing a document*, and none of them survive a boundary the browser enforces. This tier gives
8
+ * up every one of them. In exchange it gives the only thing the trusted tier cannot: separation
9
+ * that holds when the code on the other side has gone bad rather than merely gone wrong.
10
+ *
11
+ * So this is not a better realm. It is a different bet, and the architecture is explicit about
12
+ * which one you are making:
13
+ *
14
+ * | | trusted (`compat-http`, `contract-blob`) | untrusted (`sandbox`) |
15
+ * | --- | --- | --- |
16
+ * | isolation | namespace, not security | browser-enforced |
17
+ * | DOM | projected into the host document | stays in its own document |
18
+ * | cookies/storage | the host's | its own, partitioned |
19
+ * | composition | gateway namespaces, piercing, compat facade | none of it applies |
20
+ *
21
+ * **Why this is not a `RealmHandle`.** That interface exposes `window`, `document`, `evaluate()`
22
+ * and `evaluateModule()` — every one of which is a same-origin capability. Making a cross-origin
23
+ * realm implement it would mean either throwing from four members or faking them, and faking them
24
+ * is precisely the "manufacture the illusion that two documents are one" move this tier exists to
25
+ * refuse. A different thing gets a different type.
26
+ */
27
+ /** The connect message the host posts into the frame, carrying the port. */
28
+ export declare const SANDBOX_CONNECT = "braid:connect";
29
+ /** The announcement a guest posts to its parent when it is ready to receive one. */
30
+ export declare const SANDBOX_READY = "braid:ready";
31
+ export interface SandboxConnectMessage {
32
+ braid: typeof SANDBOX_CONNECT;
33
+ v: 1;
34
+ fragmentId: string;
35
+ instance: string;
36
+ }
37
+ export interface SandboxReadyMessage {
38
+ braid: typeof SANDBOX_READY;
39
+ v: 1;
40
+ }
41
+ /**
42
+ * Sandbox tokens granted to every untrusted fragment.
43
+ *
44
+ * `allow-scripts` because a fragment that cannot run scripts is not an application. `allow-forms`
45
+ * because a form post is the least surprising thing a page does. Everything else is an opt-in the
46
+ * host records in the registry, so the grant lives with the person who decided to make it.
47
+ */
48
+ export declare const DEFAULT_SANDBOX_TOKENS: readonly ["allow-scripts", "allow-forms"];
49
+ export interface SandboxRealmInit {
50
+ fragmentId: string;
51
+ /** The fragment's URL. Must be cross-origin to the host — see `assertCrossOrigin`. */
52
+ src: string;
53
+ /** Where the frame is mounted. The untrusted tier renders visibly; it projects nothing. */
54
+ container: ShadowRoot | HTMLElement;
55
+ signal: AbortSignal;
56
+ /** Additional sandbox tokens from the fragment's manifest. */
57
+ sandboxTokens?: readonly string[];
58
+ /** Permissions-Policy features to delegate, e.g. `['clipboard-write']`. */
59
+ permissions?: readonly string[];
60
+ /** How long to wait for the frame to load before failing. */
61
+ loadTimeoutMs?: number;
62
+ }
63
+ export interface SandboxRealm {
64
+ readonly kind: 'sandbox';
65
+ readonly fragmentId: string;
66
+ /** The frame element, so a host can size it. Its contents are not reachable from here. */
67
+ readonly frame: HTMLIFrameElement;
68
+ /** The fragment's origin, for pinning every message that crosses. */
69
+ readonly origin: string;
70
+ /** The host end of the message channel. */
71
+ readonly port: MessagePort;
72
+ dispose(): void;
73
+ }
74
+ /**
75
+ * Refuses a same-origin URL for the untrusted tier.
76
+ *
77
+ * This is the single most important check in the file. `sandbox="allow-scripts allow-same-origin"`
78
+ * on a **same-origin** frame is a sandbox that isn't one — the frame can reach into the host
79
+ * document and remove its own sandbox attribute — and the mistake is easy to make because the
80
+ * markup looks locked down. Refusing at the source, rather than trusting the token list, means the
81
+ * dangerous combination cannot be assembled from a manifest edit.
82
+ */
83
+ export declare function assertCrossOrigin(src: string, fragmentId: string): string;
84
+ /** Resolves the sandbox token list, refusing the ones that would undo the sandbox. */
85
+ export declare function resolveSandboxTokens(requested: readonly string[] | undefined, fragmentId: string): string[];
86
+ /**
87
+ * Creates the frame, waits for it to load, and establishes the message channel.
88
+ *
89
+ * The connect handshake is deliberately tolerant of ordering. The frame's `load` event and the
90
+ * guest's own script registering its listener race, and which wins depends on cache state — so the
91
+ * host posts on load *and* answers a guest that announces itself, and the guest announces itself
92
+ * whether or not it has already been posted to. Either order converges; neither has to be the fast
93
+ * one.
94
+ */
95
+ export declare function createSandboxRealm(init: SandboxRealmInit): Promise<SandboxRealm>;
@@ -0,0 +1,194 @@
1
+ import { BraidError } from '../errors.js';
2
+ /**
3
+ * The untrusted tier: a real cross-origin iframe, with a good protocol on it.
4
+ *
5
+ * That sentence is the honest description and it is worth leading with, because Braid's own
6
+ * documentation has been quietly implying otherwise. The trusted tier's advantages — one document,
7
+ * one layout, one accessibility tree, SSR piercing, printing, DOM projection — are consequences of
8
+ * *sharing a document*, and none of them survive a boundary the browser enforces. This tier gives
9
+ * up every one of them. In exchange it gives the only thing the trusted tier cannot: separation
10
+ * that holds when the code on the other side has gone bad rather than merely gone wrong.
11
+ *
12
+ * So this is not a better realm. It is a different bet, and the architecture is explicit about
13
+ * which one you are making:
14
+ *
15
+ * | | trusted (`compat-http`, `contract-blob`) | untrusted (`sandbox`) |
16
+ * | --- | --- | --- |
17
+ * | isolation | namespace, not security | browser-enforced |
18
+ * | DOM | projected into the host document | stays in its own document |
19
+ * | cookies/storage | the host's | its own, partitioned |
20
+ * | composition | gateway namespaces, piercing, compat facade | none of it applies |
21
+ *
22
+ * **Why this is not a `RealmHandle`.** That interface exposes `window`, `document`, `evaluate()`
23
+ * and `evaluateModule()` — every one of which is a same-origin capability. Making a cross-origin
24
+ * realm implement it would mean either throwing from four members or faking them, and faking them
25
+ * is precisely the "manufacture the illusion that two documents are one" move this tier exists to
26
+ * refuse. A different thing gets a different type.
27
+ */
28
+ /** The connect message the host posts into the frame, carrying the port. */
29
+ export const SANDBOX_CONNECT = 'braid:connect';
30
+ /** The announcement a guest posts to its parent when it is ready to receive one. */
31
+ export const SANDBOX_READY = 'braid:ready';
32
+ /**
33
+ * Sandbox tokens granted to every untrusted fragment.
34
+ *
35
+ * `allow-scripts` because a fragment that cannot run scripts is not an application. `allow-forms`
36
+ * because a form post is the least surprising thing a page does. Everything else is an opt-in the
37
+ * host records in the registry, so the grant lives with the person who decided to make it.
38
+ */
39
+ export const DEFAULT_SANDBOX_TOKENS = ['allow-scripts', 'allow-forms'];
40
+ /**
41
+ * Tokens that are never granted, whatever the manifest says.
42
+ *
43
+ * `allow-top-navigation` lets an embedded frame navigate the whole page — the classic way an
44
+ * embedded advert becomes a phishing redirect. The `-by-user-activation` variant is the one to
45
+ * grant if you need it, and it must be granted deliberately rather than inherited from a broad
46
+ * "let this fragment navigate" instinct.
47
+ */
48
+ const REFUSED_SANDBOX_TOKENS = new Set(['allow-top-navigation']);
49
+ const LOAD_TIMEOUT_MS = 15_000;
50
+ /**
51
+ * Refuses a same-origin URL for the untrusted tier.
52
+ *
53
+ * This is the single most important check in the file. `sandbox="allow-scripts allow-same-origin"`
54
+ * on a **same-origin** frame is a sandbox that isn't one — the frame can reach into the host
55
+ * document and remove its own sandbox attribute — and the mistake is easy to make because the
56
+ * markup looks locked down. Refusing at the source, rather than trusting the token list, means the
57
+ * dangerous combination cannot be assembled from a manifest edit.
58
+ */
59
+ export function assertCrossOrigin(src, fragmentId) {
60
+ let url;
61
+ try {
62
+ url = new URL(src, location.href);
63
+ }
64
+ catch (cause) {
65
+ throw new BraidError(`"${src}" is not a valid url for an untrusted fragment`, {
66
+ fragmentId,
67
+ stage: 'slot-config',
68
+ cause,
69
+ fixHint: 'untrusted fragments are addressed by absolute url, e.g. src="https://vendor.example.com/widget"',
70
+ });
71
+ }
72
+ if (url.origin === location.origin) {
73
+ throw new BraidError(`the untrusted tier requires a cross-origin url, and "${url.origin}" is this host's origin`, {
74
+ fragmentId,
75
+ stage: 'slot-config',
76
+ fixHint: 'serve the fragment from a different origin — a same-origin sandbox is not a security ' +
77
+ 'boundary, because the framed document can reach the host and clear its own sandbox attribute',
78
+ });
79
+ }
80
+ return url.origin;
81
+ }
82
+ /** Resolves the sandbox token list, refusing the ones that would undo the sandbox. */
83
+ export function resolveSandboxTokens(requested = [], fragmentId) {
84
+ const tokens = new Set(DEFAULT_SANDBOX_TOKENS);
85
+ for (const token of requested) {
86
+ if (REFUSED_SANDBOX_TOKENS.has(token)) {
87
+ throw new BraidError(`the sandbox token "${token}" is never granted to an untrusted fragment`, {
88
+ fragmentId,
89
+ stage: 'slot-config',
90
+ fixHint: `use "${token}-by-user-activation" if the fragment genuinely needs to navigate the page`,
91
+ });
92
+ }
93
+ tokens.add(token);
94
+ }
95
+ return [...tokens];
96
+ }
97
+ /**
98
+ * Creates the frame, waits for it to load, and establishes the message channel.
99
+ *
100
+ * The connect handshake is deliberately tolerant of ordering. The frame's `load` event and the
101
+ * guest's own script registering its listener race, and which wins depends on cache state — so the
102
+ * host posts on load *and* answers a guest that announces itself, and the guest announces itself
103
+ * whether or not it has already been posted to. Either order converges; neither has to be the fast
104
+ * one.
105
+ */
106
+ export async function createSandboxRealm(init) {
107
+ const { fragmentId, src, container, signal } = init;
108
+ const origin = assertCrossOrigin(src, fragmentId);
109
+ const tokens = resolveSandboxTokens(init.sandboxTokens, fragmentId);
110
+ const instance = `${fragmentId}:${Date.now().toString(36)}`;
111
+ const frame = document.createElement('iframe');
112
+ frame.src = src;
113
+ frame.setAttribute('sandbox', tokens.join(' '));
114
+ frame.setAttribute('part', 'frame');
115
+ frame.style.cssText = 'display:block;border:0;width:100%;height:100%';
116
+ /**
117
+ * Permissions-Policy delegation is a *deny* list by default: an unlisted feature is unavailable
118
+ * inside the frame regardless of what the fragment's own origin allows. Setting `allow` to the
119
+ * empty string when nothing is granted is not redundant — it makes the denial explicit in the
120
+ * markup, where someone auditing the page will see it.
121
+ */
122
+ frame.setAttribute('allow', (init.permissions ?? []).join('; '));
123
+ // Progressive: where supported, the frame gets an ephemeral, per-page storage and cookie jar, so
124
+ // an untrusted fragment cannot correlate this user with the same fragment on another site.
125
+ if ('credentialless' in HTMLIFrameElement.prototype) {
126
+ frame.setAttribute('credentialless', '');
127
+ }
128
+ container.append(frame);
129
+ const channel = new MessageChannel();
130
+ const dispose = () => {
131
+ channel.port1.close();
132
+ frame.remove();
133
+ };
134
+ signal.addEventListener('abort', dispose, { once: true });
135
+ const post = () => {
136
+ const message = { braid: SANDBOX_CONNECT, v: 1, fragmentId, instance };
137
+ /**
138
+ * The target origin is the fragment's exact origin, never `'*'`.
139
+ *
140
+ * With `'*'` the port would be delivered to whatever document happens to occupy the frame — and
141
+ * an untrusted fragment that navigated itself elsewhere between load and this call would hand a
142
+ * live channel into the host to a document nobody vetted.
143
+ */
144
+ frame.contentWindow?.postMessage(message, origin, [channel.port2]);
145
+ };
146
+ const { promise, resolve, reject } = Promise.withResolvers();
147
+ let connected = false;
148
+ const onWindowMessage = (event) => {
149
+ // Origin-pinned inbound as well as outbound: a `braid:ready` from any other origin is some
150
+ // other page on the tab talking, and must not cause the host to hand out a port.
151
+ if (event.origin !== origin)
152
+ return;
153
+ if (event.data?.braid !== SANDBOX_READY)
154
+ return;
155
+ if (connected)
156
+ return;
157
+ connected = true;
158
+ post();
159
+ resolve();
160
+ };
161
+ window.addEventListener('message', onWindowMessage);
162
+ const onLoad = () => {
163
+ if (connected)
164
+ return;
165
+ connected = true;
166
+ post();
167
+ resolve();
168
+ };
169
+ frame.addEventListener('load', onLoad, { once: true });
170
+ const timeout = setTimeout(() => {
171
+ reject(new BraidError(`the untrusted fragment at "${src}" did not load within ${init.loadTimeoutMs ?? LOAD_TIMEOUT_MS}ms`, {
172
+ fragmentId,
173
+ stage: 'realm-boot',
174
+ fixHint: 'check the url, and that the fragment origin does not refuse framing via X-Frame-Options or CSP frame-ancestors',
175
+ }));
176
+ }, init.loadTimeoutMs ?? LOAD_TIMEOUT_MS);
177
+ try {
178
+ await promise;
179
+ }
180
+ finally {
181
+ clearTimeout(timeout);
182
+ window.removeEventListener('message', onWindowMessage);
183
+ frame.removeEventListener('load', onLoad);
184
+ }
185
+ return {
186
+ kind: 'sandbox',
187
+ fragmentId,
188
+ frame,
189
+ origin,
190
+ port: channel.port1,
191
+ dispose,
192
+ };
193
+ }
194
+ //# sourceMappingURL=sandbox-realm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-realm.js","sourceRoot":"","sources":["../../../../../libs/core/src/realm/sandbox-realm.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * What a fragment is allowed to do, declared by the host and enforced where enforcement is possible.
3
+ *
4
+ * The organising principle is that **every grant names who enforces it**, because they are not all
5
+ * enforced by the same thing and pretending otherwise is how a capability system becomes theatre:
6
+ *
7
+ * | Grant | Enforced by | Trusted tier | Untrusted tier |
8
+ * | --- | --- | --- | --- |
9
+ * | `context` | **Braid** — the bus is ours | yes | yes |
10
+ * | `sandbox` | the browser | n/a — no frame to sandbox | yes |
11
+ * | `permissions` | the browser (Permissions-Policy) | n/a | yes |
12
+ * | `network` | the browser (CSP), or nobody | **advisory only** | CSP on the fragment's own origin |
13
+ *
14
+ * `context` is the one that matters most on the trusted tier, and the one Braid can actually
15
+ * enforce there — because Phase 1 turned the context bus into a message, so "what may this fragment
16
+ * read" became a question asked in exactly one place instead of a check to remember at every read.
17
+ *
18
+ * `network` is listed as advisory on the trusted tier rather than omitted. A trusted fragment runs
19
+ * in a same-origin realm with the host's `fetch`; Braid does not patch host globals and will not
20
+ * start, so this grant documents intent and feeds the registry's analysis. Recording that honestly
21
+ * is better than either enforcing it badly or leaving people to assume it works.
22
+ */
23
+ export interface ContextGrants {
24
+ /**
25
+ * Context keys this fragment may read. Absent means **every key** — the pre-grant behaviour, kept
26
+ * as the default so that adding capabilities to one fragment does not silently starve the rest.
27
+ */
28
+ read?: string[];
29
+ /** Reserved: context keys this fragment may publish. No fragment can publish today. */
30
+ write?: string[];
31
+ }
32
+ export interface FragmentCapabilities {
33
+ context?: ContextGrants;
34
+ /** Additive `sandbox` tokens for an untrusted frame. */
35
+ sandbox?: string[];
36
+ /** Permissions-Policy features delegated into an untrusted frame. */
37
+ permissions?: string[];
38
+ /** Origins the fragment is expected to talk to. Advisory on the trusted tier — see above. */
39
+ network?: string[];
40
+ /** Reserved for the storage-partitioning work. */
41
+ storage?: 'partitioned' | 'shared';
42
+ }
43
+ /**
44
+ * Decides whether a context key may cross to a fragment, and says so once when it may not.
45
+ *
46
+ * Returning `undefined` rather than throwing is deliberate: an ungranted key must look to the
47
+ * fragment exactly like a key nobody has published, because those two cases are genuinely the same
48
+ * from inside the fragment and a distinct error would leak the shape of the host's context to code
49
+ * that was specifically not given it.
50
+ *
51
+ * The dev-mode warning is the other half. Silence would be correct for production and miserable for
52
+ * whoever is wondering why `user` is undefined, so the *host's* console names the missing grant —
53
+ * host-side, because the host is where the grant is written.
54
+ */
55
+ export declare function createContextGate(capabilities: FragmentCapabilities | undefined, fragmentId: string): (key: string) => boolean;
56
+ /**
57
+ * Resolves capabilities from the three places a host can write them, most authoritative first:
58
+ *
59
+ * 1. **the realm stub** — stamped by the gateway from the registry manifest (trusted tier only);
60
+ * 2. **`initBraid({ capabilities })`** — the registry stand-in for gateway-free composition, which
61
+ * is the only source the untrusted tier has;
62
+ * 3. **slot attributes** — `sandbox=`, `allow=` on the element itself.
63
+ *
64
+ * All three are host-controlled, so this is a precedence rule rather than a trust ranking: every
65
+ * source is equally unable to be influenced by the fragment. The order reflects how centrally
66
+ * managed each one is, so that a grant written once in the registry is not quietly widened by markup
67
+ * on one page.
68
+ */
69
+ export declare function resolveCapabilities(sources: Array<FragmentCapabilities | undefined>): FragmentCapabilities | undefined;
70
+ /** Reads a capabilities block off a realm stub's adapter options, or off `initBraid` config. */
71
+ export declare function readCapabilities(source: unknown): FragmentCapabilities | undefined;
@@ -0,0 +1,61 @@
1
+ import { isDevMode } from '../config.js';
2
+ /**
3
+ * Decides whether a context key may cross to a fragment, and says so once when it may not.
4
+ *
5
+ * Returning `undefined` rather than throwing is deliberate: an ungranted key must look to the
6
+ * fragment exactly like a key nobody has published, because those two cases are genuinely the same
7
+ * from inside the fragment and a distinct error would leak the shape of the host's context to code
8
+ * that was specifically not given it.
9
+ *
10
+ * The dev-mode warning is the other half. Silence would be correct for production and miserable for
11
+ * whoever is wondering why `user` is undefined, so the *host's* console names the missing grant —
12
+ * host-side, because the host is where the grant is written.
13
+ */
14
+ export function createContextGate(capabilities, fragmentId) {
15
+ const read = capabilities?.context?.read;
16
+ if (!read)
17
+ return () => true;
18
+ const granted = new Set(read);
19
+ const warned = new Set();
20
+ return (key) => {
21
+ if (granted.has(key))
22
+ return true;
23
+ if (isDevMode() && !warned.has(key)) {
24
+ warned.add(key);
25
+ console.warn(`[braid:${fragmentId}] context "${key}" was not delivered: it is not in this fragment's ` +
26
+ `context.read grant (${[...granted].join(', ') || 'none'}). Add it to the fragment's ` +
27
+ `capabilities if it should be.`);
28
+ }
29
+ return false;
30
+ };
31
+ }
32
+ /**
33
+ * Resolves capabilities from the three places a host can write them, most authoritative first:
34
+ *
35
+ * 1. **the realm stub** — stamped by the gateway from the registry manifest (trusted tier only);
36
+ * 2. **`initBraid({ capabilities })`** — the registry stand-in for gateway-free composition, which
37
+ * is the only source the untrusted tier has;
38
+ * 3. **slot attributes** — `sandbox=`, `allow=` on the element itself.
39
+ *
40
+ * All three are host-controlled, so this is a precedence rule rather than a trust ranking: every
41
+ * source is equally unable to be influenced by the fragment. The order reflects how centrally
42
+ * managed each one is, so that a grant written once in the registry is not quietly widened by markup
43
+ * on one page.
44
+ */
45
+ export function resolveCapabilities(sources) {
46
+ const present = sources.filter((source) => Boolean(source));
47
+ if (present.length === 0)
48
+ return undefined;
49
+ // Later sources are less authoritative, so earlier ones are spread last and win.
50
+ return present.reduceRight((merged, source) => ({ ...merged, ...source }), {});
51
+ }
52
+ /** Reads a capabilities block off a realm stub's adapter options, or off `initBraid` config. */
53
+ export function readCapabilities(source) {
54
+ if (!source || typeof source !== 'object')
55
+ return undefined;
56
+ const capabilities = source.capabilities;
57
+ if (!capabilities || typeof capabilities !== 'object')
58
+ return undefined;
59
+ return capabilities;
60
+ }
61
+ //# sourceMappingURL=capabilities.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../../../../libs/core/src/weave/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA+CzC;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,YAA8C,EAC9C,UAAkB;IAElB,MAAM,IAAI,GAAG,YAAY,EAAE,OAAO,EAAE,IAAI,CAAC;IACzC,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC;IAE7B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IAEjC,OAAO,CAAC,GAAW,EAAE,EAAE;QACrB,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QAElC,IAAI,SAAS,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChB,OAAO,CAAC,IAAI,CACV,UAAU,UAAU,cAAc,GAAG,oDAAoD;gBACvF,uBAAuB,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,MAAM,8BAA8B;gBACtF,+BAA+B,CAClC,CAAC;QACJ,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAgD;IAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAkC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAC5F,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC3C,iFAAiF;IACjF,OAAO,OAAO,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,EAAE,EAA0B,CAAC,CAAC;AACzG,CAAC;AAED,gGAAgG;AAChG,MAAM,UAAU,gBAAgB,CAAC,MAAe;IAC9C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC5D,MAAM,YAAY,GAAI,MAAqC,CAAC,YAAY,CAAC;IACzE,IAAI,CAAC,YAAY,IAAI,OAAO,YAAY,KAAK,QAAQ;QAAE,OAAO,SAAS,CAAC;IACxE,OAAO,YAAoC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { Envelope } from './envelope.js';
2
+ /**
3
+ * The transport a channel runs over. Two exist: `same-realm` for trusted realms (direct dispatch,
4
+ * no serialization) and `port` for the cross-origin tier (`MessagePort` + structured clone).
5
+ *
6
+ * The interface is this small on purpose. Everything interesting — correlation, deadlines, replies,
7
+ * error propagation, close — lives in the channel above it, so that adding a transport is not an
8
+ * occasion to re-implement any of it slightly differently.
9
+ */
10
+ export interface ChannelBacking {
11
+ post(envelope: Envelope): void;
12
+ /** Registers the sole inbound handler. Returns a detach function. */
13
+ receive(handler: (envelope: Envelope) => void): () => void;
14
+ close(): void;
15
+ }
16
+ /** Context handed to a message handler alongside its payload. */
17
+ export interface MessageMeta {
18
+ readonly fragmentId: string;
19
+ readonly instance: string;
20
+ readonly scope: string | undefined;
21
+ readonly type: string;
22
+ }
23
+ export type MessageHandler = (payload: unknown, meta: MessageMeta) => unknown;
24
+ export interface RequestOptions {
25
+ timeoutMs?: number;
26
+ scope?: string;
27
+ }
28
+ export interface BoundaryChannel {
29
+ /** Fire and forget. No reply is expected and none will be delivered. */
30
+ send(type: string, payload?: unknown, options?: {
31
+ scope?: string;
32
+ }): void;
33
+ /** Sends and awaits a reply. Rejects on timeout, on a remote throw, or if the channel closes. */
34
+ request<T = unknown>(type: string, payload?: unknown, options?: RequestOptions): Promise<T>;
35
+ /**
36
+ * Handles one message type, optionally on one scope.
37
+ *
38
+ * One handler per **(type, scope)** pair — a second registration for the same pair replaces the
39
+ * first, which keeps a duplicate registration a visible bug rather than a silent double-reply.
40
+ *
41
+ * Scope is part of the address rather than a filter the handler applies itself, and that
42
+ * distinction is load-bearing: a fragment reading both its own bus and the page bus registers
43
+ * `ctx/changed` twice, and with scope as a mere filter the second registration would silently
44
+ * displace the first and one of the two buses would go quiet.
45
+ */
46
+ on(type: string, handler: MessageHandler, options?: {
47
+ scope?: string;
48
+ }): () => void;
49
+ readonly fragmentId: string;
50
+ readonly instance: string;
51
+ readonly closed: AbortSignal;
52
+ close(): void;
53
+ }
54
+ export interface CreateChannelOptions {
55
+ backing: ChannelBacking;
56
+ fragmentId: string;
57
+ instance: string;
58
+ /** Closing the channel when the fragment instance is disposed. */
59
+ signal?: AbortSignal;
60
+ /** Default deadline for `request`. */
61
+ defaultTimeoutMs?: number;
62
+ }
63
+ export declare function createBoundaryChannel(options: CreateChannelOptions): BoundaryChannel;