@ai-ecoverse/slicc-vault 1.7.0 → 1.7.2
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 +10 -9
- package/dist/types/contract.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,14 +16,14 @@ The build (`npm run build`) writes a flat static tree to `dist/site/`:
|
|
|
16
16
|
| `button.html`, `button.js` | the lock button. A popup can only open from a click inside a vault document, so bios and spectrum embed this wherever the lock is offered |
|
|
17
17
|
| `popup.html`, `popup.js` | the vault window, a top-level `vault.sliccy.ai` document, used only for the passkey or passphrase lock |
|
|
18
18
|
| `vault.css`, `fonts/` | Spectrum 2 from the CSS-only `@spectrum-css` packages, and Adobe Clean |
|
|
19
|
-
| `config.json` | `{ version, embedders }`. `embedders` is
|
|
19
|
+
| `config.json` | `{ version, embedders }`. `embedders` is `vault.sliccy.ai`'s fallback list, `["https://seven.sliccy.ai"]` |
|
|
20
20
|
|
|
21
21
|
The bundles hold this repo's code and `@ai-ecoverse/slicc-scrub`. The only third-party code is for KeePass imports: `kdbxweb` (with `@xmldom/xmldom` and `fflate`) and `hash-wasm`'s argon2, exact-pinned and bundled into a separate chunk under `chunks/` that the core frame loads only when a KeePass import starts; its wasm is inlined, never fetched. The sliccy-ai Worker serves the tree from the network on every load, never from OPFS, with:
|
|
22
22
|
- `Content-Security-Policy` with `script-src 'self'`, no inline scripts or styles, and `frame-ancestors` listing the seven origins;
|
|
23
23
|
- `Cross-Origin-Embedder-Policy: require-corp`, `Cross-Origin-Resource-Policy: same-site`, `Cross-Origin-Opener-Policy: same-origin`;
|
|
24
24
|
- `Origin-Agent-Cluster: ?1`, `nosniff`, `Referrer-Policy: no-referrer`, `no-cache` with an ETag.
|
|
25
25
|
|
|
26
|
-
`GET /embedders.json` is answered by the Worker, not by this tree. It returns `{ "embedders": [...] }`, the same sources as `frame-ancestors`. The vault reads it at start, falls back to `config.json`
|
|
26
|
+
`GET /embedders.json` is answered by the Worker, not by this tree. It returns `{ "embedders": [...] }`, the same sources as `frame-ancestors`. The vault reads it at start and accepts only those origins. When it's missing or malformed, only `vault.sliccy.ai` falls back to `config.json`; on every other host (`vault-preview.sliccy.ai`, branch previews, local) that means no embedders, so it fails closed. An embedder source is `http(s)://host`, optionally with `:port` or `:*`, matched exactly.
|
|
27
27
|
|
|
28
28
|
`main` is served at `vault.sliccy.ai`, and every other branch at `vault-<label>.sliccy.ai`. seven embeds only `vault.sliccy.ai`.
|
|
29
29
|
|
|
@@ -179,7 +179,7 @@ iframe.contentWindow.postMessage({ type: 'slicc-vault', v: 1, op: 'hello', role:
|
|
|
179
179
|
| `dismissBackupReminder` | — | `{ backupReminder }`; the reminder becomes `dismissed` for this namespace |
|
|
180
180
|
| `policy` | `files` | the attested policy files, below (Policy) |
|
|
181
181
|
| `forward` | `head`, `body?`, `owner`, `exit`, `rawTraits`, with a `MessagePort` transferred alongside | the injected head, below (Forward) |
|
|
182
|
-
| `materializeConsume` | `ticket`, `stamp`, `path`, `argv`, `cwd`, `interpreters`, `trusted` | the values for the child's environment, below (Exec) |
|
|
182
|
+
| `materializeConsume` | `ticket`, `stamp`, `path`, `resolved`, `argv`, `cwd`, `interpreters`, `trusted` | the values for the child's environment, below (Exec) |
|
|
183
183
|
| `import` | `kind`, `bytes`, `password?`, `pick?` | below (Import and export) |
|
|
184
184
|
| `export` | `passphrase` | `{ bundle, count }`, below |
|
|
185
185
|
| anything else | | `ENOTSUP` |
|
|
@@ -272,19 +272,20 @@ Values are checked as at `put` (at least 8 bytes, no CR, LF or NUL, no placehold
|
|
|
272
272
|
- Each real name is audited as `materialize { name, exec, path, argv, argvSha256, cwd, pid, ppid, uid, tag, ticket, consumed: false }`. `argv` is joined with spaces, scrubbed, and cut to 200 characters; `argvSha256` is the SHA-256 of each argument followed by a NUL byte.
|
|
273
273
|
- The reply never carries a value. The ticket is 32 hex characters and expires after 30 s.
|
|
274
274
|
|
|
275
|
-
**`materializeConsume`** (a page op, from bios for the kernel at exec) takes `{ ticket, stamp, path, argv, cwd, interpreters, trusted }`, all from the kernel and relayed unchanged:
|
|
275
|
+
**`materializeConsume`** (a page op, from bios for the kernel at exec) takes `{ ticket, stamp, path, resolved, argv, cwd, interpreters, trusted }`, all from the kernel and relayed unchanged:
|
|
276
276
|
- `stamp` is the exec'ing process.
|
|
277
|
+
- `resolved` is the kernel-normalised file that actually runs: `path` with every symlink resolved.
|
|
277
278
|
- `interpreters` is the absolute, symlink-resolved shebang/binfmt chain the kernel resolved for `path`, empty for a native binary. A plain `#!/usr/bin/env X` (or `env -S`) is reported as the resolved `X`; `env` with any other option or a `NAME=value` assignment is reported as `env` itself.
|
|
278
|
-
- `trusted` is true when
|
|
279
|
+
- `trusted` is true when the program and every chain entry are root-owned regular files, not group- or other-writable, under root-owned, non-writable parents (the attestation rule). Under users `off` it's always false.
|
|
279
280
|
|
|
280
281
|
The vault burns the ticket, then requires that:
|
|
281
282
|
- it's unexpired and from this namespace, `stamp.ppid` is the pid that asked, and `path`, `argv` (element by element) and `cwd` are exactly the ones it was issued for;
|
|
282
|
-
- `
|
|
283
|
+
- `resolved` is an absolute path (missing or malformed refuses), `interpreters` a list of absolute paths and `trusted` a boolean; a claimed `interpreter` from fnox equals `interpreters[0]` (without a claim, the kernel's chain is taken as it is);
|
|
283
284
|
- each real name is still granted by the policy as stored now (reloaded at materialize and at consume): a removed grant, or an `{ argv }` grant that no longer lists the command, refuses;
|
|
284
285
|
- under that name's mode, the chain passes:
|
|
285
|
-
- `true`: no entry of `path` and `interpreters` is on the refusal list, so a `#!/usr/bin/env node` script
|
|
286
|
-
- `{ argv }`: the listed program is `path`, and
|
|
287
|
-
- `{ shell = true }`: any chain;
|
|
286
|
+
- `true`: no entry of `path`, `resolved` and `interpreters` is on the refusal list, so neither a `#!/usr/bin/env node` script nor a symlink `/tmp/l → /bin/bash` passes, and `trusted` is true ("the program or its interpreter can be changed by a non-root user" otherwise), so a renamed copy of a shell, which its non-root maker owns, doesn't pass either;
|
|
287
|
+
- `{ argv }`: the listed program is `path`, and when `path` is a link to a refused program the rule must also list that `resolved` program by its real path ("list it in [exec] by its real path"), so a listed `/tmp/l` that is repointed to `/bin/bash` refuses. Whatever chain the kernel resolved for it is allowed, so a rule for `npm publish` allows `/usr/bin/npm`'s `node`. But when `resolved` or the chain is a refused program and `trusted` is false, it refuses ("the program or its interpreter can be changed by a non-root user"), and `env` and the other wrappers in the chain always refuse;
|
|
288
|
+
- `{ shell = true }`: any program and chain, the explicit exception;
|
|
288
289
|
- no real record has expired meanwhile.
|
|
289
290
|
|
|
290
291
|
Any failure is `EACCES: ticket refused: …`, and the ticket stays burned. It answers `{ values: { NAME: value }, placeholders: { NAME: placeholder } }` for the names that were real and still exist, and marks their audit entries `consumed`. The kernel swaps each env var whose value is exactly one of those placeholders, and compiles its own scrubber over these values for the child's output (S2).
|
package/dist/types/contract.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-vault",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "The separate-origin vault at vault.sliccy.ai: sealed secrets, OAuth tokens, and model and MCP credentials for SLICC seven, used only by its injector",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"hash-wasm": "4.12.0",
|
|
61
61
|
"kdbxweb": "2.1.1",
|
|
62
62
|
"lefthook": "2.1.17",
|
|
63
|
-
"monocart-coverage-reports": "2.13.
|
|
63
|
+
"monocart-coverage-reports": "2.13.1",
|
|
64
64
|
"playwright-core": "1.63.0",
|
|
65
65
|
"semantic-release": "25.0.9",
|
|
66
66
|
"typescript": "7.0.2"
|