@ai-ecoverse/slicc-vault 1.15.0 → 1.15.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 +5 -5
- package/package.json +14 -12
package/README.md
CHANGED
|
@@ -17,14 +17,14 @@ The build (`npm run build`) writes a flat static tree to `dist/site/`:
|
|
|
17
17
|
| `vault.css`, `fonts/` | Spectrum 2 from the CSS-only `@spectrum-css` packages, and Adobe Clean |
|
|
18
18
|
| `config.json` | `{ version, embedders }`. `embedders` is `vault.sliccy.ai`'s fallback list, `["https://seven.sliccy.ai"]` |
|
|
19
19
|
|
|
20
|
-
The bundles hold this repo's code, `@ai-ecoverse/slicc-scrub`, and `@ai-ecoverse/jerk-oauth` (
|
|
20
|
+
The bundles hold this repo's code, `@ai-ecoverse/slicc-scrub`, and `@ai-ecoverse/jerk-oauth` (exact-pinned, for token refresh): its wasm is inlined into a separate chunk under `chunks/` (about 970 KB) that loads only on the first refresh or MCP `grant`, never fetched. 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:
|
|
21
21
|
- `Content-Security-Policy` with `script-src 'self'`, no inline scripts or styles, and `frame-ancestors` listing the seven origins;
|
|
22
22
|
- `Cross-Origin-Embedder-Policy: require-corp`, `Cross-Origin-Resource-Policy: same-site`, `Cross-Origin-Opener-Policy: same-origin`;
|
|
23
23
|
- `Origin-Agent-Cluster: ?1`, `nosniff`, `Referrer-Policy: no-referrer`, `no-cache` with an ETag.
|
|
24
24
|
|
|
25
25
|
`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.
|
|
26
26
|
|
|
27
|
-
`main` is served at `vault.sliccy.ai`, and every other branch at `vault-<label>.sliccy.ai`.
|
|
27
|
+
`main` is served at `vault.sliccy.ai`, and every other branch at `vault-<label>.sliccy.ai`. CI is one caller workflow, `ci.yml`, that runs slicc-shared-web's `pipeline.yml` at the same v2 tag as the `@ai-ecoverse/slicc-shared-web` devDependency, with `secrets: inherit`, on pull requests, on the merge queue (`merge_group`) and on `main`: lint everywhere; on pull requests and in the merge queue the integration tests (`test/integration/*.test.mjs`, split by timings across the pipeline's shards, Chrome for Testing from `slicc-cdp install-browser`, headed on Xvfb); on pull requests a Claude and a Codex review; on `main` semantic-release, with no tests. `ci / integration` and `ci / review` are the checks to require. The pipeline picks its own runners (its self-hosted pool, a hosted runner for a fork's pull request and for the release), and a pull request from a fork gets no review. Releases run only on `main`: the pipeline's release job runs only on a push to it, in the `production` environment, and publishes `vault.sliccy.ai` there. The branch preview (`deploy.yml`) publishes nothing to npm, makes no tag or release, and skips the merge queue's `gh-readonly-queue/…` branches. No workflow names a self-hosted runner label. `workflows.test.mjs` keeps all of this so. seven embeds only `vault.sliccy.ai`.
|
|
28
28
|
|
|
29
29
|
## Storage and keys
|
|
30
30
|
|
|
@@ -352,7 +352,7 @@ It answers `{ values: { [placeholder]: value } }` for those, and leaves the othe
|
|
|
352
352
|
|
|
353
353
|
**pg SCRAM-SHA-256** (`position: 'scram-sha-256'`, §3.19.5). The program's pg client computes its `ClientProof` from the password it holds, a placeholder, so the kernel can't see which one it used; the vault finds it from the proof. The request carries `scram: { clientFirstBare, serverFirst, clientFinalBare, proof }` and no `placeholders` (`EINVAL` otherwise, and `scram` at any other position is `EINVAL` too):
|
|
354
354
|
- `clientFirstBare` is `n=<user>,r=<client nonce>` and `serverFirst` is `r=<nonce>,s=<salt>,i=<iterations>`, with no extensions; the server's nonce must extend the client's, and `i` must be 1 to 100000.
|
|
355
|
-
- `clientFinalBare` is `c
|
|
355
|
+
- `clientFinalBare` is `c=<base64>,r=<the server's nonce>`, without anything after. `c=` decodes to exactly one of three things: the GS2 header `n,,` (`biws`); `y,,` (`eSws`, the program supports binding but saw no `-PLUS`); or `p=tls-server-end-point,,` followed by binding data of a SHA-256, -384 or -512 digest's length (32, 48 or 64 bytes), when the kernel offered the program `SCRAM-SHA-256-PLUS`. The binding data is opaque: it's used only as part of the program's AuthMessage, exactly as sent, to match the placeholder's proof, and it is never returned, logged or audited. Any other `p=` type (`tls-unique`, `tls-exporter`), an authzid, another length, or a malformed or non-canonical `c=` (it must re-encode to itself) is `EINVAL` before the burn.
|
|
356
356
|
- `proof` is base64 of the program's 32-byte `ClientProof`. Each message is at most 1024 characters. Anything else is `EINVAL`, before the burn.
|
|
357
357
|
|
|
358
358
|
The candidates are the placeholders that would pass the per-placeholder checks above for this session (a live `secret` with a `scram-sha-256` session rule for this host and port, whose `[exits]` allow `exit`), never other records; more than 16 is `EACCES` "more than 16 session rules' placeholders to try for SCRAM", before any hashing. For each, the vault computes RFC 5802's `ClientProof` with the placeholder as the password (PBKDF2-SHA-256 over the salt and iterations, then the Client Key, Stored Key and signature over `clientFirstBare,serverFirst,clientFinalBare`) and compares it in constant time. Only placeholders are hashed, never values, so it reveals nothing the program doesn't hold. Exactly one match is handed out as above (re-checked at release, audited with `position: 'scram-sha-256'`); none is `EACCES` "no session rule's placeholder matches the SCRAM proof", and more than one is `EACCES` "more than one placeholder matches the SCRAM proof". The kernel computes the real proof from the value, checks the server's real `v=` before giving the program one made from the placeholder, never passes on a server `e=` derived from the value, and wipes the value and every derived key.
|
|
@@ -511,5 +511,5 @@ npm start # vault on http://vault.sliccy.localhost:8790, a test embedde
|
|
|
511
511
|
|
|
512
512
|
## Release and deploy
|
|
513
513
|
|
|
514
|
-
- **Releases:** semantic-release on `main` tags a version from the conventional commits
|
|
515
|
-
- **Deploy:**
|
|
514
|
+
- **Releases:** semantic-release on `main` (the pipeline's release job) tags a version from the conventional commits and publishes the types package to npm with trusted publishing, which names `ci.yml` (`fledgling.workflow`; `npm run trust` registers it).
|
|
515
|
+
- **Deploy:** when semantic-release tags a new version, the pipeline's `after-release` command (in `ci.yml`) builds with that version and publishes `dist/site/` to `vault.sliccy.ai` from the `production` environment; a push to `main` that releases nothing deploys nothing. The packages of ours that the site bundles (`@ai-ecoverse/slicc-scrub` and `@ai-ecoverse/jerk-oauth`) are `dependencies`, which Renovate's `config:recommended` commits as `fix(deps)`, so each bump releases and deploys; every other bump is `chore(deps)` and waits for the next release. `dependencies.test.mjs` keeps the `dependencies` to exactly the packages of ours that `src/` imports. Every push to another branch publishes it to `vault-<label>.sliccy.ai` from `deploy.yml`, on the push event: the publish route derives the host from the OIDC token's `refs/heads/` branch, which a pull request's token (`refs/pull/…`) doesn't have, so the pipeline's `deploy` input can't carry it. Both use GitHub's OIDC token against sliccy-ai's `/api/publish` route (`edge/publish.mjs`), with no stored secret. `edge/publish.mjs` ends with the verdict line `publish: PASS <url> <sha>`, and both publishes fail without it, so a script that exits without publishing can't read as a pass. It runs as the main module also through a symlinked checkout or workspace: both sides of that check are real paths. A `manifest` answer without an `https://` URL fails the publish.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-vault",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.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
|
"piAi": "1.3.0",
|
|
6
6
|
"type": "module",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"fledgling": {
|
|
16
16
|
"provider": "github",
|
|
17
|
-
"workflow": "
|
|
17
|
+
"workflow": "ci.yml",
|
|
18
18
|
"repo": "ai-ecoverse/slicc-vault",
|
|
19
19
|
"publish": true
|
|
20
20
|
},
|
|
@@ -32,11 +32,11 @@
|
|
|
32
32
|
"dist/types"
|
|
33
33
|
],
|
|
34
34
|
"scripts": {
|
|
35
|
-
"prepare": "node scripts/endpoints.mjs && node scripts/jerk-wasm.mjs &&
|
|
35
|
+
"prepare": "node scripts/endpoints.mjs && node scripts/jerk-wasm.mjs && slicc-install-hooks",
|
|
36
36
|
"build": "node scripts/endpoints.mjs && node scripts/jerk-wasm.mjs && node build.mjs && tsc -p tsconfig.build.json",
|
|
37
37
|
"prepack": "npm run build",
|
|
38
38
|
"start": "npm run build && node test/integration/serve.mjs",
|
|
39
|
-
"pretest": "npm run build &&
|
|
39
|
+
"pretest": "npm run build && slicc-cdp install-browser",
|
|
40
40
|
"test": "node --test --test-timeout=300000 --test-global-setup=node_modules/@ai-ecoverse/slicc-shared-web/harness/global.mjs 'test/integration/*.test.mjs'",
|
|
41
41
|
"test:unit": "node scripts/endpoints.mjs && node scripts/jerk-wasm.mjs && NODE_NO_WARNINGS=1 mcr -c node_modules/@ai-ecoverse/slicc-shared-web/mcr.config.mjs node --import fake-indexeddb/auto --test --test-force-exit 'test/unit/**/*.test.mjs'",
|
|
42
42
|
"typecheck": "tsc",
|
|
@@ -46,13 +46,16 @@
|
|
|
46
46
|
"trust:dry": "npx fledgling sync --dry-run -y --skip-publish",
|
|
47
47
|
"release": "semantic-release"
|
|
48
48
|
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@ai-ecoverse/jerk-oauth": "1.2.1",
|
|
51
|
+
"@ai-ecoverse/slicc-scrub": "1.0.0"
|
|
52
|
+
},
|
|
49
53
|
"devDependencies": {
|
|
50
|
-
"@ai-ecoverse/
|
|
51
|
-
"@ai-ecoverse/slicc-kernel": "1.
|
|
52
|
-
"@ai-ecoverse/slicc-
|
|
53
|
-
"@ai-ecoverse/
|
|
54
|
-
"@ai-ecoverse/wasm-
|
|
55
|
-
"@ai-ecoverse/wasm-coreutils": "9.12.0-10",
|
|
54
|
+
"@ai-ecoverse/slicc-cdp": "1.30.22",
|
|
55
|
+
"@ai-ecoverse/slicc-kernel": "1.142.2",
|
|
56
|
+
"@ai-ecoverse/slicc-shared-web": "2.4.2",
|
|
57
|
+
"@ai-ecoverse/wasm-bash": "5.3.0-22",
|
|
58
|
+
"@ai-ecoverse/wasm-coreutils": "9.12.0-12",
|
|
56
59
|
"@biomejs/biome": "2.5.15",
|
|
57
60
|
"@earendil-works/pi-ai": "1.3.0",
|
|
58
61
|
"@happy-dom/global-registrator": "20.14.6",
|
|
@@ -65,9 +68,8 @@
|
|
|
65
68
|
"hash-wasm": "4.12.0",
|
|
66
69
|
"js-yaml": "5.5.0",
|
|
67
70
|
"kdbxweb": "2.1.1",
|
|
68
|
-
"lefthook": "2.2.
|
|
71
|
+
"lefthook": "2.2.2",
|
|
69
72
|
"monocart-coverage-reports": "2.13.2",
|
|
70
|
-
"playwright-core": "1.64.0",
|
|
71
73
|
"semantic-release": "25.0.9",
|
|
72
74
|
"typescript": "7.0.2"
|
|
73
75
|
}
|