usertrust 1.5.0 → 2.0.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 +17 -1
- package/dist/anomaly/detector.js.map +1 -1
- package/dist/anomaly/index.d.ts +2 -2
- package/dist/anomaly/index.d.ts.map +1 -1
- package/dist/anomaly/index.js +1 -1
- package/dist/anomaly/index.js.map +1 -1
- package/dist/audit/anchor-doctor.d.ts +42 -0
- package/dist/audit/anchor-doctor.d.ts.map +1 -0
- package/dist/audit/anchor-doctor.js +285 -0
- package/dist/audit/anchor-doctor.js.map +1 -0
- package/dist/audit/anchor-verify.d.ts +229 -0
- package/dist/audit/anchor-verify.d.ts.map +1 -0
- package/dist/audit/anchor-verify.js +809 -0
- package/dist/audit/anchor-verify.js.map +1 -0
- package/dist/audit/anchor.d.ts +177 -0
- package/dist/audit/anchor.d.ts.map +1 -0
- package/dist/audit/anchor.js +922 -0
- package/dist/audit/anchor.js.map +1 -0
- package/dist/audit/canonical.js +1 -1
- package/dist/audit/canonical.js.map +1 -1
- package/dist/audit/chain.d.ts.map +1 -1
- package/dist/audit/chain.js +21 -7
- package/dist/audit/chain.js.map +1 -1
- package/dist/audit/read.d.ts +19 -0
- package/dist/audit/read.d.ts.map +1 -0
- package/dist/audit/read.js +94 -0
- package/dist/audit/read.js.map +1 -0
- package/dist/audit/rekor-verify.d.ts +116 -0
- package/dist/audit/rekor-verify.d.ts.map +1 -0
- package/dist/audit/rekor-verify.js +533 -0
- package/dist/audit/rekor-verify.js.map +1 -0
- package/dist/audit/rekor.d.ts +71 -0
- package/dist/audit/rekor.d.ts.map +1 -0
- package/dist/audit/rekor.js +556 -0
- package/dist/audit/rekor.js.map +1 -0
- package/dist/audit/rotation.js +1 -1
- package/dist/audit/rotation.js.map +1 -1
- package/dist/audit/sigv4.d.ts +44 -0
- package/dist/audit/sigv4.d.ts.map +1 -0
- package/dist/audit/sigv4.js +134 -0
- package/dist/audit/sigv4.js.map +1 -0
- package/dist/audit/verify.d.ts +78 -0
- package/dist/audit/verify.d.ts.map +1 -1
- package/dist/audit/verify.js +195 -1
- package/dist/audit/verify.js.map +1 -1
- package/dist/cli/anchor.d.ts +3 -0
- package/dist/cli/anchor.d.ts.map +1 -0
- package/dist/cli/anchor.js +626 -0
- package/dist/cli/anchor.js.map +1 -0
- package/dist/cli/completions.js +1 -1
- package/dist/cli/export.d.ts +3 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +58 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/health.js.map +1 -1
- package/dist/cli/init.js +1 -1
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/inspect.d.ts.map +1 -1
- package/dist/cli/inspect.js +4 -34
- package/dist/cli/inspect.js.map +1 -1
- package/dist/cli/main.d.ts +2 -2
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +20 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/pricing.js +1 -1
- package/dist/cli/pricing.js.map +1 -1
- package/dist/cli/ui.d.ts +3 -0
- package/dist/cli/ui.d.ts.map +1 -0
- package/dist/cli/ui.js +35 -0
- package/dist/cli/ui.js.map +1 -0
- package/dist/cli/verify.d.ts.map +1 -1
- package/dist/cli/verify.js +342 -3
- package/dist/cli/verify.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js.map +1 -1
- package/dist/detect.d.ts +37 -15
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +17 -6
- package/dist/detect.js.map +1 -1
- package/dist/export/markdown.d.ts +12 -0
- package/dist/export/markdown.d.ts.map +1 -0
- package/dist/export/markdown.js +142 -0
- package/dist/export/markdown.js.map +1 -0
- package/dist/govern.d.ts +60 -3
- package/dist/govern.d.ts.map +1 -1
- package/dist/govern.js +842 -229
- package/dist/govern.js.map +1 -1
- package/dist/headless.d.ts.map +1 -1
- package/dist/headless.js +4 -4
- package/dist/headless.js.map +1 -1
- package/dist/index.d.ts +33 -26
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -25
- package/dist/index.js.map +1 -1
- package/dist/ledger/client.d.ts.map +1 -1
- package/dist/ledger/client.js +57 -46
- package/dist/ledger/client.js.map +1 -1
- package/dist/ledger/engine.d.ts.map +1 -1
- package/dist/ledger/engine.js +22 -13
- package/dist/ledger/engine.js.map +1 -1
- package/dist/shared/types.d.ts +114 -475
- package/dist/shared/types.d.ts.map +1 -1
- package/dist/shared/types.js +13 -13
- package/dist/shared/types.js.map +1 -1
- package/dist/snapshot/checkpoint.d.ts.map +1 -1
- package/dist/snapshot/checkpoint.js +20 -2
- package/dist/snapshot/checkpoint.js.map +1 -1
- package/dist/streaming.d.ts +9 -4
- package/dist/streaming.d.ts.map +1 -1
- package/dist/streaming.js +27 -0
- package/dist/streaming.js.map +1 -1
- package/dist/supply-chain/sign.d.ts.map +1 -1
- package/dist/supply-chain/sign.js +3 -0
- package/dist/supply-chain/sign.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,626 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2026 Usertools, Inc.
|
|
3
|
+
/**
|
|
4
|
+
* CLI: usertrust anchor — external audit anchoring
|
|
5
|
+
*
|
|
6
|
+
* init Mint the vault's anchor identity (Ed25519 key OUTSIDE the vault)
|
|
7
|
+
* now One snapshot → sign → mirror → publish cycle
|
|
8
|
+
* status Last anchor, unanchored tail, outbox depth
|
|
9
|
+
* export Print mirror records (JSONL) for pull-mode shipping
|
|
10
|
+
* export-bundle Records + transparency-log receipts as one auditor artifact
|
|
11
|
+
* doctor Probe what this identity can delete/overwrite in the store
|
|
12
|
+
* rotate Cross-signed key rotation (spec §6)
|
|
13
|
+
* resume Re-seed a lost mirror from the store's newest record
|
|
14
|
+
*
|
|
15
|
+
* Spec: docs/superpowers/specs/2026-07-26-external-anchoring-design.md
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readdirSync, readFileSync } from "node:fs";
|
|
18
|
+
import { join } from "node:path";
|
|
19
|
+
import pc from "picocolors";
|
|
20
|
+
import { anchorsDir, createAnchorEmitter, initAnchorIdentity, mintSuccessorKey, readAnchorIdentity, recordRotatedIdentity, resumeAnchorMirror, } from "../audit/anchor.js";
|
|
21
|
+
import { doctorFileSink, doctorS3Sink } from "../audit/anchor-doctor.js";
|
|
22
|
+
import { parseAnchorsContent } from "../audit/anchor-verify.js";
|
|
23
|
+
import { DEFAULT_REKOR_URL } from "../audit/rekor.js";
|
|
24
|
+
import { parseRekorReceipt } from "../audit/rekor-verify.js";
|
|
25
|
+
import { VAULT_DIR } from "../shared/constants.js";
|
|
26
|
+
const REKOR_FLAG = "--sink-rekor";
|
|
27
|
+
const S3_KEYS = new Set(["bucket", "region", "prefix", "endpoint"]);
|
|
28
|
+
/** Sink flags that take the following argv token as their operand. */
|
|
29
|
+
const VALUE_SINK_FLAGS = new Set(["--sink-file", "--sink-url", "--sink-s3"]);
|
|
30
|
+
/** Same cap the verify CLI enforces on `--bundle` — never export what it refuses. */
|
|
31
|
+
const MAX_BUNDLE_ITEMS = 10_000;
|
|
32
|
+
function sinksFromArgs(args) {
|
|
33
|
+
const sinks = [];
|
|
34
|
+
for (let i = 0; i < args.length; i++) {
|
|
35
|
+
const arg = args[i];
|
|
36
|
+
if (VALUE_SINK_FLAGS.has(arg)) {
|
|
37
|
+
// A missing operand used to drop the flag on the floor, so
|
|
38
|
+
// `anchor now --sink-s3` ran with ZERO sinks, published nowhere and
|
|
39
|
+
// still exited 0 — a skipped publication an operator would only
|
|
40
|
+
// discover at audit time. Refuse the run instead.
|
|
41
|
+
const value = args[i + 1];
|
|
42
|
+
if (value === undefined)
|
|
43
|
+
throw new Error(`${arg} requires a value`);
|
|
44
|
+
i++;
|
|
45
|
+
if (arg === "--sink-file") {
|
|
46
|
+
sinks.push({ type: "file", path: value });
|
|
47
|
+
}
|
|
48
|
+
else if (arg === "--sink-url") {
|
|
49
|
+
sinks.push({ type: "https", url: value });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
sinks.push(s3SinkFromSpec(value));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
else if (arg === REKOR_FLAG) {
|
|
56
|
+
// Delta D8: this flag never consumes the token after it, so
|
|
57
|
+
// `--sink-rekor --sink-file /mnt/worm/a.jsonl` keeps its file sink. A
|
|
58
|
+
// URL parked there was meant as the log address, and defaulting to
|
|
59
|
+
// the public log instead would publish somewhere the operator never
|
|
60
|
+
// named — refuse rather than reinterpret.
|
|
61
|
+
const stray = args[i + 1];
|
|
62
|
+
if (stray !== undefined && /^https?:\/\//.test(stray)) {
|
|
63
|
+
throw new Error(`${REKOR_FLAG} takes no separate value — use ${REKOR_FLAG}=<url>`);
|
|
64
|
+
}
|
|
65
|
+
sinks.push({ type: "rekor" });
|
|
66
|
+
}
|
|
67
|
+
else if (arg.startsWith(`${REKOR_FLAG}=`)) {
|
|
68
|
+
const url = arg.slice(REKOR_FLAG.length + 1);
|
|
69
|
+
if (url === "")
|
|
70
|
+
throw new Error(`${REKOR_FLAG}=<url> requires a URL`);
|
|
71
|
+
sinks.push({ type: "rekor", url });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return sinks;
|
|
75
|
+
}
|
|
76
|
+
/** `bucket=B,region=R[,prefix=P][,endpoint=E]` — every key is explicit, none inferred. */
|
|
77
|
+
function s3SinkFromSpec(spec) {
|
|
78
|
+
const fields = {};
|
|
79
|
+
for (const part of spec.split(",")) {
|
|
80
|
+
if (part.trim() === "")
|
|
81
|
+
continue;
|
|
82
|
+
const eq = part.indexOf("=");
|
|
83
|
+
if (eq <= 0) {
|
|
84
|
+
throw new Error(`--sink-s3: expected key=value, got "${part.slice(0, 60)}"`);
|
|
85
|
+
}
|
|
86
|
+
const key = part.slice(0, eq).trim();
|
|
87
|
+
const value = part.slice(eq + 1).trim();
|
|
88
|
+
if (!S3_KEYS.has(key)) {
|
|
89
|
+
throw new Error(`--sink-s3: unknown key "${key.slice(0, 40)}" (bucket, region, prefix, endpoint)`);
|
|
90
|
+
}
|
|
91
|
+
if (value === "")
|
|
92
|
+
throw new Error(`--sink-s3: ${key} requires a value`);
|
|
93
|
+
fields[key] = value;
|
|
94
|
+
}
|
|
95
|
+
const { bucket, region, prefix, endpoint } = fields;
|
|
96
|
+
if (bucket === undefined || region === undefined) {
|
|
97
|
+
throw new Error("--sink-s3 requires bucket=<name>,region=<region>");
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
type: "s3",
|
|
101
|
+
bucket,
|
|
102
|
+
region,
|
|
103
|
+
...(prefix !== undefined ? { prefix } : {}),
|
|
104
|
+
...(endpoint !== undefined ? { endpoint } : {}),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function flagValue(args, flag) {
|
|
108
|
+
const idx = args.indexOf(flag);
|
|
109
|
+
if (idx === -1 || args[idx + 1] === undefined)
|
|
110
|
+
return undefined;
|
|
111
|
+
return args[idx + 1];
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* `--since <anchorSeq>`, or null when the operand is not a non-negative
|
|
115
|
+
* integer. Both `export` and `export-bundle` validate here: a bare parseInt
|
|
116
|
+
* turns `--since abc` into NaN, every `anchorSeq > NaN` comparison is false,
|
|
117
|
+
* and the command prints nothing while exiting 0 — indistinguishable from a
|
|
118
|
+
* vault with nothing left to ship.
|
|
119
|
+
*/
|
|
120
|
+
function sinceFromArgs(args) {
|
|
121
|
+
const raw = flagValue(args, "--since") ?? "0";
|
|
122
|
+
return /^(0|[1-9][0-9]*)$/.test(raw) ? Number.parseInt(raw, 10) : null;
|
|
123
|
+
}
|
|
124
|
+
function emitterConfig(args) {
|
|
125
|
+
const keyFile = flagValue(args, "--key-file");
|
|
126
|
+
const retriesRaw = flagValue(args, "--publish-retries");
|
|
127
|
+
const retries = retriesRaw !== undefined ? Number.parseInt(retriesRaw, 10) : undefined;
|
|
128
|
+
if (retriesRaw !== undefined && (!Number.isSafeInteger(retries) || retries < 1)) {
|
|
129
|
+
// Silently ignoring a bad value would fall back to the default and
|
|
130
|
+
// mask the operator's intent — fail loudly instead.
|
|
131
|
+
throw new Error(`Invalid --publish-retries: ${retriesRaw} (integer >= 1 required)`);
|
|
132
|
+
}
|
|
133
|
+
return {
|
|
134
|
+
signer: { type: "pem", ...(keyFile !== undefined ? { file: keyFile } : {}) },
|
|
135
|
+
sinks: sinksFromArgs(args),
|
|
136
|
+
...(retries !== undefined ? { publishRetries: retries } : {}),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
// ── doctor ──
|
|
140
|
+
/** A sink the doctor cannot probe without writing to someone else's store. */
|
|
141
|
+
function notProbed(sink, detail) {
|
|
142
|
+
return { sink, checks: [{ name: "probe", status: "info", detail }], failed: false };
|
|
143
|
+
}
|
|
144
|
+
async function doctorReports(args) {
|
|
145
|
+
const sinks = sinksFromArgs(args);
|
|
146
|
+
if (sinks.length === 0) {
|
|
147
|
+
throw new Error("anchor doctor: no sink configured — pass --sink-file, --sink-s3, --sink-url or --sink-rekor");
|
|
148
|
+
}
|
|
149
|
+
const reports = [];
|
|
150
|
+
for (const sink of sinks) {
|
|
151
|
+
switch (sink.type) {
|
|
152
|
+
case "file":
|
|
153
|
+
reports.push(doctorFileSink(sink.path));
|
|
154
|
+
break;
|
|
155
|
+
case "s3":
|
|
156
|
+
reports.push(await doctorS3Sink({
|
|
157
|
+
bucket: sink.bucket,
|
|
158
|
+
region: sink.region,
|
|
159
|
+
...(sink.prefix !== undefined ? { prefix: sink.prefix } : {}),
|
|
160
|
+
...(sink.endpoint !== undefined ? { endpoint: sink.endpoint } : {}),
|
|
161
|
+
}));
|
|
162
|
+
break;
|
|
163
|
+
case "https":
|
|
164
|
+
reports.push(notProbed(`https:${sink.url}`, "not probed: an ingest endpoint is append-only for this credential by " +
|
|
165
|
+
"construction — probe the store BEHIND it with its own credentials"));
|
|
166
|
+
break;
|
|
167
|
+
case "rekor":
|
|
168
|
+
reports.push(notProbed(`rekor:${sink.url ?? DEFAULT_REKOR_URL}`, "not probed: a transparency log is append-only by construction — its " +
|
|
169
|
+
"inclusion receipts under audit/anchors/rekor/ are the evidence"));
|
|
170
|
+
break;
|
|
171
|
+
case "command":
|
|
172
|
+
reports.push(notProbed(`command:${sink.argv[0] ?? ""}`, "not probed: the store behind a command " +
|
|
173
|
+
"sink is opaque from here — probe it with its own tooling"));
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
return reports;
|
|
178
|
+
}
|
|
179
|
+
function printDoctor(reports) {
|
|
180
|
+
const paint = { pass: pc.green, fail: pc.red, info: pc.yellow };
|
|
181
|
+
console.log(pc.bold("anchor doctor — permission probe (NOT proof of immutability)"));
|
|
182
|
+
for (const report of reports) {
|
|
183
|
+
console.log("");
|
|
184
|
+
console.log(report.sink);
|
|
185
|
+
for (const check of report.checks) {
|
|
186
|
+
console.log(` ${paint[check.status](check.status.toUpperCase())} ${check.name}: ${check.detail}`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
console.log("");
|
|
190
|
+
console.log("Each verdict describes what these credentials could do at this location right now.");
|
|
191
|
+
console.log("Durable immutability comes from the store's own configuration (S3 Object Lock");
|
|
192
|
+
console.log("retention, POSIX directory permissions, an appliance's WORM mode).");
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Build the auditor bundle `{v:1, records, rekorReceipts}` consumed by
|
|
196
|
+
* `usertrust verify --bundle`.
|
|
197
|
+
*
|
|
198
|
+
* Fail-closed by construction (delta D9): a bundle is what an auditor receives
|
|
199
|
+
* INSTEAD of the vault, so a partial one — records present, a receipt quietly
|
|
200
|
+
* dropped because its file did not parse — is worse than no bundle at all. Every
|
|
201
|
+
* failure path returns `bundle: null`, and callers print diagnostics to stderr
|
|
202
|
+
* so stdout is either one complete bundle or empty.
|
|
203
|
+
*
|
|
204
|
+
* A receipt whose record is absent from the mirror is the one exception, and it
|
|
205
|
+
* is not a parse failure: `anchor resume` re-seeds the mirror from the store's
|
|
206
|
+
* newest record alone, leaving the receipts for every earlier anchor on disk
|
|
207
|
+
* with nothing to pair against. Shipping them would hard-fail the verifier
|
|
208
|
+
* ("receipt for unknown anchorSeq"), so they are excluded with a warning and
|
|
209
|
+
* the bundle stays valid.
|
|
210
|
+
*/
|
|
211
|
+
function buildBundle(root, args) {
|
|
212
|
+
const errors = [];
|
|
213
|
+
const warnings = [];
|
|
214
|
+
try {
|
|
215
|
+
const since = sinceFromArgs(args);
|
|
216
|
+
if (since === null) {
|
|
217
|
+
return {
|
|
218
|
+
bundle: null,
|
|
219
|
+
errors: ["export-bundle: --since must be an integer >= 0"],
|
|
220
|
+
warnings,
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
const mirrorPath = join(anchorsDir(root), "anchors.jsonl");
|
|
224
|
+
if (!existsSync(mirrorPath)) {
|
|
225
|
+
return { bundle: null, errors: ["export-bundle: no anchor mirror found"], warnings };
|
|
226
|
+
}
|
|
227
|
+
const mirror = parseAnchorsContent(readFileSync(mirrorPath, "utf-8"));
|
|
228
|
+
for (const err of mirror.errors)
|
|
229
|
+
errors.push(`export-bundle: mirror: ${err}`);
|
|
230
|
+
const records = mirror.records
|
|
231
|
+
.filter((r) => r.anchorSeq > since)
|
|
232
|
+
.sort((a, b) => a.anchorSeq - b.anchorSeq);
|
|
233
|
+
const found = readReceipts(root, errors)
|
|
234
|
+
.filter((r) => r.anchorSeq > since)
|
|
235
|
+
.sort((a, b) => a.anchorSeq - b.anchorSeq);
|
|
236
|
+
if (errors.length > 0)
|
|
237
|
+
return { bundle: null, errors, warnings };
|
|
238
|
+
const bundledSeqs = new Set(records.map((r) => r.anchorSeq));
|
|
239
|
+
const receipts = found.filter((r) => {
|
|
240
|
+
if (bundledSeqs.has(r.anchorSeq))
|
|
241
|
+
return true;
|
|
242
|
+
warnings.push(`export-bundle: excluding receipt for anchorSeq ${r.anchorSeq} (no matching record ` +
|
|
243
|
+
"in mirror — re-fetch the full history to include it)");
|
|
244
|
+
return false;
|
|
245
|
+
});
|
|
246
|
+
for (const [what, count] of [
|
|
247
|
+
["records", records.length],
|
|
248
|
+
["rekorReceipts", receipts.length],
|
|
249
|
+
]) {
|
|
250
|
+
if (count > MAX_BUNDLE_ITEMS) {
|
|
251
|
+
errors.push(`export-bundle: ${count} ${what} exceeds the ${MAX_BUNDLE_ITEMS} cap the verifier ` +
|
|
252
|
+
"accepts — export in slices with --since");
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (errors.length > 0)
|
|
256
|
+
return { bundle: null, errors, warnings };
|
|
257
|
+
return {
|
|
258
|
+
bundle: JSON.stringify({ v: 1, records, rekorReceipts: receipts }),
|
|
259
|
+
errors,
|
|
260
|
+
warnings,
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
catch (err) {
|
|
264
|
+
errors.push(`export-bundle: ${err instanceof Error ? err.message : String(err)}`);
|
|
265
|
+
return { bundle: null, errors, warnings };
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Every receipt the Rekor sink persisted; unparseable ones become errors, never
|
|
270
|
+
* gaps. Any `*.json` under the receipts directory is a candidate and each one is
|
|
271
|
+
* keyed by the `anchorSeq` INSIDE it — the filename is an index for humans, not
|
|
272
|
+
* a fact about the receipt.
|
|
273
|
+
*/
|
|
274
|
+
function readReceipts(root, errors) {
|
|
275
|
+
const dir = join(anchorsDir(root), "rekor");
|
|
276
|
+
if (!existsSync(dir))
|
|
277
|
+
return [];
|
|
278
|
+
const receipts = [];
|
|
279
|
+
for (const name of readdirSync(dir)
|
|
280
|
+
.filter((f) => f.endsWith(".json"))
|
|
281
|
+
.sort()) {
|
|
282
|
+
let raw;
|
|
283
|
+
try {
|
|
284
|
+
raw = readFileSync(join(dir, name), "utf-8");
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
errors.push(`export-bundle: ${name}: unreadable (${err instanceof Error ? err.message : String(err)})`);
|
|
288
|
+
continue;
|
|
289
|
+
}
|
|
290
|
+
const { receipt, error } = parseRekorReceipt(raw);
|
|
291
|
+
if (receipt === null) {
|
|
292
|
+
errors.push(`export-bundle: ${name}: ${error}`);
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
receipts.push(receipt);
|
|
296
|
+
}
|
|
297
|
+
return receipts;
|
|
298
|
+
}
|
|
299
|
+
export async function run(args = [], opts) {
|
|
300
|
+
const json = opts?.json === true;
|
|
301
|
+
const root = process.cwd();
|
|
302
|
+
const action = args[0];
|
|
303
|
+
try {
|
|
304
|
+
switch (action) {
|
|
305
|
+
case "init": {
|
|
306
|
+
const keyFile = flagValue(args, "--key-file");
|
|
307
|
+
const { identity, publicKeyPem, keyFile: writtenKeyFile, } = initAnchorIdentity(root, keyFile !== undefined ? { keyFile } : undefined);
|
|
308
|
+
if (json) {
|
|
309
|
+
console.log(JSON.stringify({
|
|
310
|
+
command: "anchor init",
|
|
311
|
+
success: true,
|
|
312
|
+
data: { vaultId: identity.vaultId, keyId: identity.keyId, keyFile: writtenKeyFile },
|
|
313
|
+
}));
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
console.log(pc.green("Anchor identity created."));
|
|
317
|
+
console.log(` vaultId: ${identity.vaultId}`);
|
|
318
|
+
console.log(` keyId: ${identity.keyId}`);
|
|
319
|
+
console.log(` private key: ${writtenKeyFile} (mode 0600 — NEVER inside the vault)`);
|
|
320
|
+
console.log("");
|
|
321
|
+
console.log("Public key (PEM) — PIN THIS OUT-OF-BAND:");
|
|
322
|
+
console.log(publicKeyPem.trim());
|
|
323
|
+
console.log("");
|
|
324
|
+
console.log(pc.bold("Next steps:"));
|
|
325
|
+
console.log(" 1. Give the PEM + keyId to whoever will audit this vault (their records,");
|
|
326
|
+
console.log(" not the vault). Verification: usertrust-verify <vault> --anchor <file> --pubkey pub.pem");
|
|
327
|
+
console.log(" 2. Configure an APPEND-ONLY store and publish anchors to it:");
|
|
328
|
+
console.log(" usertrust anchor now --sink-file /mnt/worm/anchors.jsonl");
|
|
329
|
+
console.log(" Deployment invariant: the identity that writes the vault has");
|
|
330
|
+
console.log(" append-only (no delete/overwrite) access to the store.");
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
case "now": {
|
|
334
|
+
const emitter = createAnchorEmitter(root, emitterConfig(args));
|
|
335
|
+
const result = await emitter.anchorNow();
|
|
336
|
+
await emitter.stop();
|
|
337
|
+
const status = emitter.status();
|
|
338
|
+
if (json) {
|
|
339
|
+
// Delivery-gated: emitted-but-undelivered (all sinks failed,
|
|
340
|
+
// outbox retained) is a FAILURE in the mode cron/CI consumes —
|
|
341
|
+
// mirror the non-JSON contract exactly (spec §5.3).
|
|
342
|
+
const delivered = status.outboxDepth === 0;
|
|
343
|
+
console.log(JSON.stringify({
|
|
344
|
+
command: "anchor now",
|
|
345
|
+
success: result.emitted && delivered,
|
|
346
|
+
data: { ...result, outboxDepth: status.outboxDepth, delivered },
|
|
347
|
+
}));
|
|
348
|
+
if ((!result.emitted && result.reason !== "no-new-events") ||
|
|
349
|
+
(result.emitted && !delivered)) {
|
|
350
|
+
process.exitCode = 1;
|
|
351
|
+
}
|
|
352
|
+
return;
|
|
353
|
+
}
|
|
354
|
+
if (result.emitted && result.record) {
|
|
355
|
+
console.log(pc.green(`Anchored: #${result.record.anchorSeq} treeSize ${result.record.treeSize} root ${result.record.merkleRoot.slice(0, 16)}…`));
|
|
356
|
+
if (status.outboxDepth > 0) {
|
|
357
|
+
console.log(pc.yellow(`Outbox: ${status.outboxDepth} record(s) not yet acknowledged by sinks.`));
|
|
358
|
+
process.exitCode = 1;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
else if (result.reason === "no-new-events") {
|
|
362
|
+
console.log("Nothing to anchor (no new events since the last anchor).");
|
|
363
|
+
}
|
|
364
|
+
else {
|
|
365
|
+
console.log(pc.red(`Anchor skipped: ${result.reason}`));
|
|
366
|
+
process.exitCode = 1;
|
|
367
|
+
}
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
case "status": {
|
|
371
|
+
const identity = readAnchorIdentity(root);
|
|
372
|
+
if (identity === null) {
|
|
373
|
+
console.log(json
|
|
374
|
+
? JSON.stringify({
|
|
375
|
+
command: "anchor status",
|
|
376
|
+
success: false,
|
|
377
|
+
data: { message: "no anchor identity" },
|
|
378
|
+
})
|
|
379
|
+
: "No anchor identity. Run `usertrust anchor init` first.");
|
|
380
|
+
process.exitCode = 1;
|
|
381
|
+
return;
|
|
382
|
+
}
|
|
383
|
+
const mirrorPath = join(anchorsDir(root), "anchors.jsonl");
|
|
384
|
+
const mirror = existsSync(mirrorPath)
|
|
385
|
+
? parseAnchorsContent(readFileSync(mirrorPath, "utf-8"))
|
|
386
|
+
: { records: [], errors: [] };
|
|
387
|
+
const tail = mirror.records.sort((a, b) => a.anchorSeq - b.anchorSeq).at(-1) ?? null;
|
|
388
|
+
const metaPath = join(root, VAULT_DIR, "audit", "events.jsonl.meta");
|
|
389
|
+
let headSeq = 0;
|
|
390
|
+
try {
|
|
391
|
+
headSeq = JSON.parse(readFileSync(metaPath, "utf-8")).sequence;
|
|
392
|
+
}
|
|
393
|
+
catch {
|
|
394
|
+
/* legacy / empty vault */
|
|
395
|
+
}
|
|
396
|
+
const tailEvents = Math.max(0, headSeq - (tail?.treeSize ?? 0));
|
|
397
|
+
const outboxDir = join(anchorsDir(root), "outbox");
|
|
398
|
+
let outboxDepth = 0;
|
|
399
|
+
try {
|
|
400
|
+
outboxDepth = existsSync(outboxDir)
|
|
401
|
+
? (await import("node:fs")).readdirSync(outboxDir).filter((f) => f.endsWith(".json"))
|
|
402
|
+
.length
|
|
403
|
+
: 0;
|
|
404
|
+
}
|
|
405
|
+
catch {
|
|
406
|
+
/* ignore */
|
|
407
|
+
}
|
|
408
|
+
if (json) {
|
|
409
|
+
console.log(JSON.stringify({
|
|
410
|
+
command: "anchor status",
|
|
411
|
+
success: true,
|
|
412
|
+
data: {
|
|
413
|
+
vaultId: identity.vaultId,
|
|
414
|
+
keyId: identity.keyId,
|
|
415
|
+
lastAnchor: tail,
|
|
416
|
+
eventsSinceLastAnchor: tailEvents,
|
|
417
|
+
outboxDepth,
|
|
418
|
+
mirrorErrors: mirror.errors,
|
|
419
|
+
},
|
|
420
|
+
}));
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
console.log(`vaultId: ${identity.vaultId}`);
|
|
424
|
+
console.log(`keyId: ${identity.keyId}`);
|
|
425
|
+
if (tail) {
|
|
426
|
+
console.log(`Last anchor: #${tail.anchorSeq} treeSize ${tail.treeSize} (${tail.timestamp})`);
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
console.log("Last anchor: none");
|
|
430
|
+
}
|
|
431
|
+
console.log(`Unanchored tail: ${tailEvents} event(s)`);
|
|
432
|
+
console.log(`Outbox: ${outboxDepth} pending`);
|
|
433
|
+
if (mirror.errors.length > 0) {
|
|
434
|
+
console.log(pc.red(`Mirror parse errors: ${mirror.errors.length}`));
|
|
435
|
+
process.exitCode = 1;
|
|
436
|
+
}
|
|
437
|
+
return;
|
|
438
|
+
}
|
|
439
|
+
case "export": {
|
|
440
|
+
const since = sinceFromArgs(args);
|
|
441
|
+
if (since === null) {
|
|
442
|
+
console.error("export: --since must be an integer >= 0");
|
|
443
|
+
process.exitCode = 1;
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
const mirrorPath = join(anchorsDir(root), "anchors.jsonl");
|
|
447
|
+
if (!existsSync(mirrorPath)) {
|
|
448
|
+
console.error("No anchor mirror found.");
|
|
449
|
+
process.exitCode = 1;
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
const { records, errors } = parseAnchorsContent(readFileSync(mirrorPath, "utf-8"));
|
|
453
|
+
for (const err of errors) {
|
|
454
|
+
console.error(`# ${err}`);
|
|
455
|
+
}
|
|
456
|
+
for (const r of records.filter((r) => r.anchorSeq > since)) {
|
|
457
|
+
// Records were persisted canonically; re-serialize the parsed
|
|
458
|
+
// object canonically for byte-stable output.
|
|
459
|
+
console.log(JSON.stringify(r));
|
|
460
|
+
}
|
|
461
|
+
if (errors.length > 0)
|
|
462
|
+
process.exitCode = 1;
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
case "export-bundle": {
|
|
466
|
+
const { bundle, errors, warnings } = buildBundle(root, args);
|
|
467
|
+
for (const warning of warnings) {
|
|
468
|
+
console.error(warning);
|
|
469
|
+
}
|
|
470
|
+
if (bundle === null) {
|
|
471
|
+
for (const err of errors) {
|
|
472
|
+
console.error(err);
|
|
473
|
+
}
|
|
474
|
+
console.error("export-bundle: refusing to emit a partial bundle");
|
|
475
|
+
process.exitCode = 1;
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
// Deliberately NOT wrapped in the {command, success, data} envelope
|
|
479
|
+
// under --json: a bundle is an interchange artifact fed straight to
|
|
480
|
+
// `usertrust verify --bundle -`, not a status report.
|
|
481
|
+
console.log(bundle);
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
case "doctor": {
|
|
485
|
+
const reports = await doctorReports(args);
|
|
486
|
+
const failed = reports.some((r) => r.failed);
|
|
487
|
+
if (json) {
|
|
488
|
+
console.log(JSON.stringify({
|
|
489
|
+
command: "anchor doctor",
|
|
490
|
+
success: !failed,
|
|
491
|
+
data: { failed, reports },
|
|
492
|
+
}));
|
|
493
|
+
}
|
|
494
|
+
else {
|
|
495
|
+
printDoctor(reports);
|
|
496
|
+
}
|
|
497
|
+
if (failed)
|
|
498
|
+
process.exitCode = 1;
|
|
499
|
+
return;
|
|
500
|
+
}
|
|
501
|
+
case "rotate": {
|
|
502
|
+
const identity = readAnchorIdentity(root);
|
|
503
|
+
if (identity === null) {
|
|
504
|
+
console.log("No anchor identity. Run `usertrust anchor init` first.");
|
|
505
|
+
process.exitCode = 1;
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
const successor = mintSuccessorKey(identity.vaultId);
|
|
509
|
+
const emitter = createAnchorEmitter(root, emitterConfig(args));
|
|
510
|
+
const result = await emitter.rotate({
|
|
511
|
+
keyId: successor.keyId,
|
|
512
|
+
publicKeySpki: successor.publicKeySpki,
|
|
513
|
+
});
|
|
514
|
+
await emitter.stop();
|
|
515
|
+
const rotateStatus = emitter.status();
|
|
516
|
+
if (!result.emitted) {
|
|
517
|
+
if (json) {
|
|
518
|
+
console.log(JSON.stringify({
|
|
519
|
+
command: "anchor rotate",
|
|
520
|
+
success: false,
|
|
521
|
+
data: { reason: result.reason },
|
|
522
|
+
}));
|
|
523
|
+
}
|
|
524
|
+
else {
|
|
525
|
+
console.log(pc.red(`Rotation not emitted: ${result.reason}`));
|
|
526
|
+
}
|
|
527
|
+
process.exitCode = 1;
|
|
528
|
+
return;
|
|
529
|
+
}
|
|
530
|
+
// The cross-signed record is already fsync'd into the local mirror,
|
|
531
|
+
// so identity.json MUST advance in lockstep — rolling it back would
|
|
532
|
+
// desync mirror vs identity. Undelivered-to-sink is surfaced loudly
|
|
533
|
+
// (exit 1 + recovery path) instead.
|
|
534
|
+
recordRotatedIdentity(root, {
|
|
535
|
+
keyId: successor.keyId,
|
|
536
|
+
publicKeySpki: successor.publicKeySpki,
|
|
537
|
+
});
|
|
538
|
+
const rotateDelivered = rotateStatus.outboxDepth === 0;
|
|
539
|
+
if (json) {
|
|
540
|
+
console.log(JSON.stringify({
|
|
541
|
+
command: "anchor rotate",
|
|
542
|
+
success: rotateDelivered,
|
|
543
|
+
data: {
|
|
544
|
+
newKeyId: successor.keyId,
|
|
545
|
+
keyFile: successor.keyFile,
|
|
546
|
+
outboxDepth: rotateStatus.outboxDepth,
|
|
547
|
+
delivered: rotateDelivered,
|
|
548
|
+
},
|
|
549
|
+
}));
|
|
550
|
+
if (!rotateDelivered)
|
|
551
|
+
process.exitCode = 1;
|
|
552
|
+
return;
|
|
553
|
+
}
|
|
554
|
+
console.log(pc.green(`Rotation anchored (#${result.record?.anchorSeq}).`));
|
|
555
|
+
console.log(` new keyId: ${successor.keyId}`);
|
|
556
|
+
console.log(` new private key: ${successor.keyFile}`);
|
|
557
|
+
console.log("");
|
|
558
|
+
console.log("New public key (PEM) — distribute the fingerprint OUT-OF-BAND:");
|
|
559
|
+
console.log(successor.publicKeyPem.trim());
|
|
560
|
+
console.log("");
|
|
561
|
+
console.log(pc.bold("IMPORTANT:"));
|
|
562
|
+
console.log(" - Point USERTRUST_ANCHOR_KEY (or --key-file) at the NEW private key.");
|
|
563
|
+
console.log(" - Auditors keep pinning the ORIGINAL root key; give them this new");
|
|
564
|
+
console.log(" fingerprint as a --successor-pin so a hijacked rotation cannot pass.");
|
|
565
|
+
if (!rotateDelivered) {
|
|
566
|
+
console.log("");
|
|
567
|
+
console.log(pc.yellow(`WARNING: the rotation record was NOT delivered to any sink (outbox: ${rotateStatus.outboxDepth} pending).`));
|
|
568
|
+
console.log(pc.yellow(" The store lacks the trust-chain handoff — anchors signed by the new key will not verify until it ships."));
|
|
569
|
+
console.log(pc.yellow(` Ship it: usertrust anchor export --since ${(result.record?.anchorSeq ?? 1) - 1} (then re-run with a reachable sink)`));
|
|
570
|
+
process.exitCode = 1;
|
|
571
|
+
}
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
case "resume": {
|
|
575
|
+
const latest = flagValue(args, "--latest");
|
|
576
|
+
if (latest === undefined) {
|
|
577
|
+
console.log("Usage: usertrust anchor resume --latest <record.json|->");
|
|
578
|
+
process.exitCode = 1;
|
|
579
|
+
return;
|
|
580
|
+
}
|
|
581
|
+
const raw = latest === "-" ? readFileSync(0, "utf-8") : readFileSync(latest, "utf-8");
|
|
582
|
+
const record = resumeAnchorMirror(root, raw);
|
|
583
|
+
console.log(json
|
|
584
|
+
? JSON.stringify({
|
|
585
|
+
command: "anchor resume",
|
|
586
|
+
success: true,
|
|
587
|
+
data: { anchorSeq: record.anchorSeq },
|
|
588
|
+
})
|
|
589
|
+
: pc.green(`Mirror re-seeded at anchorSeq ${record.anchorSeq}.`));
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
default: {
|
|
593
|
+
console.log(`Usage: usertrust anchor <init|now|status|export|export-bundle|doctor|rotate|resume>
|
|
594
|
+
|
|
595
|
+
init [--key-file <path>] Mint identity + Ed25519 key (outside the vault)
|
|
596
|
+
now [sink flags] Snapshot, sign, mirror, publish
|
|
597
|
+
status Last anchor, unanchored tail, outbox
|
|
598
|
+
export [--since <anchorSeq>] Print mirror records (pull-mode shipping)
|
|
599
|
+
export-bundle [--since <anchorSeq>] Records + Rekor receipts for \`verify --bundle\`
|
|
600
|
+
doctor [sink flags] What can this identity delete/overwrite in the store?
|
|
601
|
+
rotate [--key-file <path>] Cross-signed key rotation
|
|
602
|
+
resume --latest <record|-> Re-seed a lost mirror from the store
|
|
603
|
+
|
|
604
|
+
Sink flags:
|
|
605
|
+
--sink-file <path> Append-only file store
|
|
606
|
+
--sink-url <url> Ingest endpoint (POST per record)
|
|
607
|
+
--sink-s3 bucket=B,region=R[,prefix=P][,endpoint=E]
|
|
608
|
+
--sink-rekor[=<url>] Rekor transparency log (default ${DEFAULT_REKOR_URL})`);
|
|
609
|
+
if (action !== undefined)
|
|
610
|
+
process.exitCode = 1;
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
catch (err) {
|
|
616
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
617
|
+
if (json) {
|
|
618
|
+
console.log(JSON.stringify({ command: `anchor ${action ?? ""}`, success: false, data: { message } }));
|
|
619
|
+
}
|
|
620
|
+
else {
|
|
621
|
+
console.log(pc.red(message));
|
|
622
|
+
}
|
|
623
|
+
process.exitCode = 1;
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
//# sourceMappingURL=anchor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anchor.js","sourceRoot":"","sources":["../../src/cli/anchor.ts"],"names":[],"mappings":"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"}
|