run402 4.24.1 → 4.26.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/cli.mjs +6 -6
- package/git-remote-run402.mjs +328 -0
- package/lib/command-manifest.mjs +13 -1
- package/lib/credentials.mjs +4 -0
- package/lib/deploy-v2.mjs +78 -1
- package/lib/doctor.mjs +80 -1
- package/lib/domains.mjs +0 -14
- package/lib/gitvault.mjs +582 -0
- package/lib/init.mjs +153 -5
- package/lib/org-context.mjs +44 -1
- package/lib/pay.test.mjs +0 -4
- package/package.json +8 -2
- package/sdk/dist/index.d.ts +20 -3
- package/sdk/dist/index.d.ts.map +1 -1
- package/sdk/dist/index.js +22 -3
- package/sdk/dist/index.js.map +1 -1
- package/sdk/dist/namespaces/admin.d.ts +0 -5
- package/sdk/dist/namespaces/admin.d.ts.map +1 -1
- package/sdk/dist/namespaces/admin.js +0 -9
- package/sdk/dist/namespaces/admin.js.map +1 -1
- package/sdk/dist/namespaces/assets.d.ts +1 -20
- package/sdk/dist/namespaces/assets.d.ts.map +1 -1
- package/sdk/dist/namespaces/assets.js +0 -27
- package/sdk/dist/namespaces/assets.js.map +1 -1
- package/sdk/dist/namespaces/domains.d.ts +0 -19
- package/sdk/dist/namespaces/domains.d.ts.map +1 -1
- package/sdk/dist/namespaces/domains.js +0 -19
- package/sdk/dist/namespaces/domains.js.map +1 -1
- package/sdk/dist/namespaces/gitvault.crypto.d.ts +319 -0
- package/sdk/dist/namespaces/gitvault.crypto.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.crypto.js +690 -0
- package/sdk/dist/namespaces/gitvault.crypto.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.d.ts +521 -0
- package/sdk/dist/namespaces/gitvault.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.js +786 -0
- package/sdk/dist/namespaces/gitvault.js.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts +481 -0
- package/sdk/dist/namespaces/gitvault.types.d.ts.map +1 -0
- package/sdk/dist/namespaces/gitvault.types.js +19 -0
- package/sdk/dist/namespaces/gitvault.types.js.map +1 -0
- package/sdk/dist/namespaces/org.d.ts +1 -3
- package/sdk/dist/namespaces/org.d.ts.map +1 -1
- package/sdk/dist/namespaces/org.js +6 -10
- package/sdk/dist/namespaces/org.js.map +1 -1
- package/sdk/dist/namespaces/pay.d.ts +0 -8
- package/sdk/dist/namespaces/pay.d.ts.map +1 -1
- package/sdk/dist/namespaces/pay.js.map +1 -1
- package/sdk/dist/namespaces/projects.d.ts +2 -2
- package/sdk/dist/namespaces/projects.d.ts.map +1 -1
- package/sdk/dist/namespaces/projects.js +4 -12
- package/sdk/dist/namespaces/projects.js.map +1 -1
- package/sdk/dist/namespaces/secrets.d.ts +0 -2
- package/sdk/dist/namespaces/secrets.d.ts.map +1 -1
- package/sdk/dist/namespaces/secrets.js +3 -10
- package/sdk/dist/namespaces/secrets.js.map +1 -1
- package/sdk/dist/namespaces/subdomains.d.ts +0 -2
- package/sdk/dist/namespaces/subdomains.d.ts.map +1 -1
- package/sdk/dist/namespaces/subdomains.js +5 -16
- package/sdk/dist/namespaces/subdomains.js.map +1 -1
- package/sdk/dist/namespaces/transfers.d.ts +0 -2
- package/sdk/dist/namespaces/transfers.d.ts.map +1 -1
- package/sdk/dist/namespaces/transfers.js +8 -10
- package/sdk/dist/namespaces/transfers.js.map +1 -1
- package/sdk/dist/namespaces/wallets.d.ts +0 -12
- package/sdk/dist/namespaces/wallets.d.ts.map +1 -1
- package/sdk/dist/namespaces/wallets.js +0 -14
- package/sdk/dist/namespaces/wallets.js.map +1 -1
- package/sdk/dist/node/gitvault-creation-journal.d.ts +222 -0
- package/sdk/dist/node/gitvault-creation-journal.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-creation-journal.js +365 -0
- package/sdk/dist/node/gitvault-creation-journal.js.map +1 -0
- package/sdk/dist/node/gitvault-deploy.d.ts +211 -0
- package/sdk/dist/node/gitvault-deploy.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-deploy.js +292 -0
- package/sdk/dist/node/gitvault-deploy.js.map +1 -0
- package/sdk/dist/node/gitvault-keystore.d.ts +207 -0
- package/sdk/dist/node/gitvault-keystore.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-keystore.js +529 -0
- package/sdk/dist/node/gitvault-keystore.js.map +1 -0
- package/sdk/dist/node/gitvault-prune.d.ts +341 -0
- package/sdk/dist/node/gitvault-prune.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-prune.js +410 -0
- package/sdk/dist/node/gitvault-prune.js.map +1 -0
- package/sdk/dist/node/gitvault-publication.d.ts +730 -0
- package/sdk/dist/node/gitvault-publication.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-publication.js +1475 -0
- package/sdk/dist/node/gitvault-publication.js.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts +227 -0
- package/sdk/dist/node/gitvault-snapshot.d.ts.map +1 -0
- package/sdk/dist/node/gitvault-snapshot.js +556 -0
- package/sdk/dist/node/gitvault-snapshot.js.map +1 -0
- package/sdk/dist/node/index.d.ts +11 -0
- package/sdk/dist/node/index.d.ts.map +1 -1
- package/sdk/dist/node/index.js +9 -0
- package/sdk/dist/node/index.js.map +1 -1
- package/sdk/dist/node/paid-fetch.d.ts.map +1 -1
- package/sdk/dist/node/paid-fetch.js +0 -4
- package/sdk/dist/node/paid-fetch.js.map +1 -1
- package/sdk/dist/node/sites-node.d.ts +1 -8
- package/sdk/dist/node/sites-node.d.ts.map +1 -1
- package/sdk/dist/node/sites-node.js +1 -7
- package/sdk/dist/node/sites-node.js.map +1 -1
- package/sdk/dist/scoped.d.ts +4 -35
- package/sdk/dist/scoped.d.ts.map +1 -1
- package/sdk/dist/scoped.js +9 -74
- package/sdk/dist/scoped.js.map +1 -1
- package/lib/sender-domain.mjs +0 -36
- package/sdk/dist/deprecate.d.ts +0 -23
- package/sdk/dist/deprecate.d.ts.map +0 -1
- package/sdk/dist/deprecate.js +0 -42
- package/sdk/dist/deprecate.js.map +0 -1
- package/sdk/dist/namespaces/sender-domain.d.ts +0 -47
- package/sdk/dist/namespaces/sender-domain.d.ts.map +0 -1
- package/sdk/dist/namespaces/sender-domain.js +0 -45
- package/sdk/dist/namespaces/sender-domain.js.map +0 -1
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* gitvault — the principal keystore (protocol rev 40 §5.1; task 5.2).
|
|
3
|
+
*
|
|
4
|
+
* Layout (under the active profile's config dir, beside the project-key cache
|
|
5
|
+
* `core/src/keystore.ts` manages — `RUN402_CONFIG_DIR` / `RUN402_WALLET` aware):
|
|
6
|
+
*
|
|
7
|
+
* <config>/gitvault/
|
|
8
|
+
* identity.json Ed25519 seed + X25519 private key (0600)
|
|
9
|
+
* repos/<repo_id>.json K_repo, trust pin, dual pins, last ref transaction (0600)
|
|
10
|
+
* repos/<repo_id>.lock/ per-repo lock (mkdir-atomic, 0700)
|
|
11
|
+
* receipts/<repo_id>.recovery_receipt.json the recovery receipt (NOT a secret; more copies better)
|
|
12
|
+
* journal/<client_creation_id>.json six-stage creation journals (task 5.3)
|
|
13
|
+
* audit.log append-only JSON lines (0600)
|
|
14
|
+
*
|
|
15
|
+
* Discipline (spec: "Writes SHALL be atomic with per-repo locks, no-follow
|
|
16
|
+
* creation, and permission audits"): directories 0700, files 0600, every
|
|
17
|
+
* write = temp file (O_NOFOLLOW|O_EXCL) + fsync + rename + directory fsync,
|
|
18
|
+
* and `auditKeystorePermissions()` runs at open so a world-readable identity
|
|
19
|
+
* is a named finding, never silent.
|
|
20
|
+
*
|
|
21
|
+
* Transitions (protocol §5.1 partial-loss table) are DERIVED by
|
|
22
|
+
* {@link GitvaultKeystore.assess} and acted on by explicit methods — the
|
|
23
|
+
* keystore never guesses:
|
|
24
|
+
* - repo file lost + identity intact → `restoreRepoFromEnvelope` (own envelope)
|
|
25
|
+
* - signing key lost, K_repo held → `read_only` (clear report)
|
|
26
|
+
* - stale pin → `stale_pin` (re-verify from genesis; 5.4)
|
|
27
|
+
* - whole keystore lost → `VAULT_UNRECOVERABLE` (§0, verbatim)
|
|
28
|
+
*/
|
|
29
|
+
import { closeSync, constants, existsSync, fsyncSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmdirSync, statSync, unlinkSync, writeSync } from "node:fs";
|
|
30
|
+
import { dirname, join } from "node:path";
|
|
31
|
+
import { getConfigDir } from "../../core-dist/config.js";
|
|
32
|
+
import { LocalError } from "../errors.js";
|
|
33
|
+
import { GITVAULT_EK_RE, GITVAULT_SRC_RE, GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, GITVAULT_TERMINAL_LOSS_STATEMENT, GITVAULT_VK_RE, bytesToHex, checkGenesisKeyBindings, checkRecoveryReceipt, ekFingerprint, formatGitvaultTimestamp, generateEncryptionKeypair, generateSigningKeypair, hexToBytes, openKeyEnvelope, storedBytesSha256, toBase64url, verifyGitvaultObject, vkFingerprint, } from "../namespaces/gitvault.crypto.js";
|
|
34
|
+
function fail(code, message, context, details) {
|
|
35
|
+
throw new LocalError(message, context, { code, details });
|
|
36
|
+
}
|
|
37
|
+
const O_NOFOLLOW = constants.O_NOFOLLOW ?? 0;
|
|
38
|
+
const DIR_MODE = 0o700;
|
|
39
|
+
const FILE_MODE = 0o600;
|
|
40
|
+
/** Default keystore root: `<active profile config dir>/gitvault`. */
|
|
41
|
+
export function getGitvaultKeystoreRoot() {
|
|
42
|
+
return join(getConfigDir(), "gitvault");
|
|
43
|
+
}
|
|
44
|
+
function mkdir0700(path) {
|
|
45
|
+
mkdirSync(path, { recursive: true, mode: DIR_MODE });
|
|
46
|
+
}
|
|
47
|
+
function fsyncDir(path) {
|
|
48
|
+
try {
|
|
49
|
+
const fd = openSync(path, constants.O_RDONLY);
|
|
50
|
+
try {
|
|
51
|
+
fsyncSync(fd);
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
closeSync(fd);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch {
|
|
58
|
+
/* some filesystems refuse directory fsync; the rename is still atomic */
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Atomic, no-follow, fsynced write: `O_WRONLY|O_CREAT|O_EXCL|O_NOFOLLOW` on a
|
|
63
|
+
* temp sibling, fsync, rename over the target, fsync the directory.
|
|
64
|
+
*/
|
|
65
|
+
export function writeFileAtomic0600(path, text) {
|
|
66
|
+
const dir = dirname(path);
|
|
67
|
+
mkdir0700(dir);
|
|
68
|
+
if (existsSync(path) && lstatSync(path).isSymbolicLink()) {
|
|
69
|
+
fail("GITVAULT_KEYSTORE_SYMLINK", `refusing to write through a symlink: ${path}`, "writing gitvault keystore file", { path });
|
|
70
|
+
}
|
|
71
|
+
const tmp = join(dir, `.${String(process.pid)}.${bytesToHex(globalThis.crypto.getRandomValues(new Uint8Array(6)))}.tmp`);
|
|
72
|
+
const fd = openSync(tmp, constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | O_NOFOLLOW, FILE_MODE);
|
|
73
|
+
try {
|
|
74
|
+
writeSync(fd, text);
|
|
75
|
+
fsyncSync(fd);
|
|
76
|
+
}
|
|
77
|
+
finally {
|
|
78
|
+
closeSync(fd);
|
|
79
|
+
}
|
|
80
|
+
renameSync(tmp, path);
|
|
81
|
+
fsyncDir(dir);
|
|
82
|
+
}
|
|
83
|
+
/** No-follow read: a symlinked keystore file is a refusal, not a read. */
|
|
84
|
+
export function readFileNoFollow(path) {
|
|
85
|
+
let st;
|
|
86
|
+
try {
|
|
87
|
+
st = lstatSync(path);
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
if (st.isSymbolicLink()) {
|
|
93
|
+
fail("GITVAULT_KEYSTORE_SYMLINK", `refusing to read through a symlink: ${path}`, "reading gitvault keystore file", { path });
|
|
94
|
+
}
|
|
95
|
+
const fd = openSync(path, constants.O_RDONLY | O_NOFOLLOW);
|
|
96
|
+
try {
|
|
97
|
+
return readFileSync(fd, "utf8");
|
|
98
|
+
}
|
|
99
|
+
finally {
|
|
100
|
+
closeSync(fd);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
function auditPath(path, expectDir) {
|
|
104
|
+
const findings = [];
|
|
105
|
+
let st;
|
|
106
|
+
try {
|
|
107
|
+
st = lstatSync(path);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return [{ path, problem: "missing" }];
|
|
111
|
+
}
|
|
112
|
+
if (st.isSymbolicLink())
|
|
113
|
+
findings.push({ path, problem: "symlink" });
|
|
114
|
+
if (process.platform !== "win32") {
|
|
115
|
+
const mode = st.mode & 0o777;
|
|
116
|
+
const allowed = expectDir ? DIR_MODE : FILE_MODE;
|
|
117
|
+
if ((mode & ~allowed) !== 0)
|
|
118
|
+
findings.push({ path, problem: "world_or_group_accessible", mode: mode.toString(8) });
|
|
119
|
+
if (typeof process.getuid === "function" && st.uid !== process.getuid())
|
|
120
|
+
findings.push({ path, problem: "not_owned_by_user" });
|
|
121
|
+
}
|
|
122
|
+
return findings;
|
|
123
|
+
}
|
|
124
|
+
// ─── The keystore ────────────────────────────────────────────────────────────
|
|
125
|
+
export class GitvaultKeystore {
|
|
126
|
+
rootDir;
|
|
127
|
+
now;
|
|
128
|
+
strictPermissions;
|
|
129
|
+
constructor(options = {}) {
|
|
130
|
+
this.rootDir = options.rootDir ?? getGitvaultKeystoreRoot();
|
|
131
|
+
this.now = options.now ?? (() => new Date());
|
|
132
|
+
this.strictPermissions = options.strictPermissions ?? false;
|
|
133
|
+
}
|
|
134
|
+
/** Open (creating the directory skeleton) and run the permission audit. */
|
|
135
|
+
static open(options = {}) {
|
|
136
|
+
const ks = new GitvaultKeystore(options);
|
|
137
|
+
for (const dir of [ks.rootDir, ks.reposDir, ks.receiptsDir, ks.journalDir])
|
|
138
|
+
mkdir0700(dir);
|
|
139
|
+
const findings = ks.auditPermissions();
|
|
140
|
+
ks.audit("keystore_opened", undefined, { findings: findings.length });
|
|
141
|
+
if (findings.length > 0 && ks.strictPermissions) {
|
|
142
|
+
fail("GITVAULT_KEYSTORE_PERMISSIONS", "gitvault keystore permission audit failed", "opening gitvault keystore", { findings });
|
|
143
|
+
}
|
|
144
|
+
return ks;
|
|
145
|
+
}
|
|
146
|
+
get identityPath() { return join(this.rootDir, "identity.json"); }
|
|
147
|
+
get reposDir() { return join(this.rootDir, "repos"); }
|
|
148
|
+
get receiptsDir() { return join(this.rootDir, "receipts"); }
|
|
149
|
+
get journalDir() { return join(this.rootDir, "journal"); }
|
|
150
|
+
get auditLogPath() { return join(this.rootDir, "audit.log"); }
|
|
151
|
+
repoPath(repoId) {
|
|
152
|
+
if (!GITVAULT_SRC_RE.test(repoId))
|
|
153
|
+
fail("GITVAULT_BAD_REPO_ID", `not a src_ id: ${repoId}`, "resolving gitvault repo path");
|
|
154
|
+
return join(this.reposDir, `${repoId}.json`);
|
|
155
|
+
}
|
|
156
|
+
recoveryReceiptPath(repoId) {
|
|
157
|
+
if (!GITVAULT_SRC_RE.test(repoId))
|
|
158
|
+
fail("GITVAULT_BAD_REPO_ID", `not a src_ id: ${repoId}`, "resolving gitvault receipt path");
|
|
159
|
+
return join(this.receiptsDir, `${repoId}.recovery_receipt.json`);
|
|
160
|
+
}
|
|
161
|
+
// ── permission audit ──
|
|
162
|
+
/** Audit every keystore path that exists; findings are recorded in `audit.log` and returned. */
|
|
163
|
+
auditPermissions() {
|
|
164
|
+
const findings = [];
|
|
165
|
+
const check = (path, dir) => {
|
|
166
|
+
if (!existsSync(path) && !isSymlink(path))
|
|
167
|
+
return;
|
|
168
|
+
findings.push(...auditPath(path, dir));
|
|
169
|
+
};
|
|
170
|
+
check(this.rootDir, true);
|
|
171
|
+
check(this.identityPath, false);
|
|
172
|
+
check(this.auditLogPath, false);
|
|
173
|
+
for (const dir of [this.reposDir, this.journalDir]) {
|
|
174
|
+
check(dir, true);
|
|
175
|
+
if (existsSync(dir)) {
|
|
176
|
+
for (const entry of readdirSync(dir)) {
|
|
177
|
+
const p = join(dir, entry);
|
|
178
|
+
if (entry.endsWith(".lock"))
|
|
179
|
+
continue;
|
|
180
|
+
check(p, statSafe(p)?.isDirectory() ?? false);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
for (const f of findings)
|
|
185
|
+
this.audit("permission_finding", undefined, { ...f });
|
|
186
|
+
return findings;
|
|
187
|
+
}
|
|
188
|
+
// ── audit log ──
|
|
189
|
+
/** Append one JSON line to `audit.log` (0600, created no-follow). */
|
|
190
|
+
audit(event, repoId, details) {
|
|
191
|
+
const entry = { at: formatGitvaultTimestamp(this.now()), event, ...(repoId ? { repo_id: repoId } : {}), ...(details ? { details } : {}) };
|
|
192
|
+
mkdir0700(this.rootDir);
|
|
193
|
+
if (isSymlink(this.auditLogPath)) {
|
|
194
|
+
fail("GITVAULT_KEYSTORE_SYMLINK", "refusing to append through a symlinked audit.log", "appending gitvault audit log");
|
|
195
|
+
}
|
|
196
|
+
const fd = openSync(this.auditLogPath, constants.O_WRONLY | constants.O_CREAT | constants.O_APPEND | O_NOFOLLOW, FILE_MODE);
|
|
197
|
+
try {
|
|
198
|
+
writeSync(fd, `${JSON.stringify(entry)}\n`);
|
|
199
|
+
fsyncSync(fd);
|
|
200
|
+
}
|
|
201
|
+
finally {
|
|
202
|
+
closeSync(fd);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/** Read the audit log (newest last). */
|
|
206
|
+
readAuditLog() {
|
|
207
|
+
const text = readFileNoFollow(this.auditLogPath);
|
|
208
|
+
if (!text)
|
|
209
|
+
return [];
|
|
210
|
+
return text.split("\n").filter((l) => l.length > 0).map((l) => JSON.parse(l));
|
|
211
|
+
}
|
|
212
|
+
// ── identity ──
|
|
213
|
+
readIdentity() {
|
|
214
|
+
const text = readFileNoFollow(this.identityPath);
|
|
215
|
+
if (!text)
|
|
216
|
+
return null;
|
|
217
|
+
const parsed = JSON.parse(text);
|
|
218
|
+
if (parsed.version !== 1 || typeof parsed.signing_pubkey !== "string" || typeof parsed.encryption_pubkey !== "string") {
|
|
219
|
+
fail("GITVAULT_KEYSTORE_CORRUPT", "identity.json is not a version-1 gitvault identity", "reading gitvault identity");
|
|
220
|
+
}
|
|
221
|
+
return parsed;
|
|
222
|
+
}
|
|
223
|
+
/** Create the identity if absent; never overwrites an existing one. */
|
|
224
|
+
ensureIdentity() {
|
|
225
|
+
const existing = this.readIdentity();
|
|
226
|
+
if (existing)
|
|
227
|
+
return existing;
|
|
228
|
+
const signing = generateSigningKeypair();
|
|
229
|
+
const encryption = generateEncryptionKeypair();
|
|
230
|
+
const identity = {
|
|
231
|
+
version: 1,
|
|
232
|
+
signing_seed_hex: bytesToHex(signing.seed),
|
|
233
|
+
signing_pubkey: toBase64url(signing.public_key),
|
|
234
|
+
signing_fingerprint: vkFingerprint(signing.public_key),
|
|
235
|
+
encryption_private_key_hex: bytesToHex(encryption.private_key),
|
|
236
|
+
encryption_pubkey: toBase64url(encryption.public_key),
|
|
237
|
+
encryption_fingerprint: ekFingerprint(encryption.public_key),
|
|
238
|
+
created_at: formatGitvaultTimestamp(this.now()),
|
|
239
|
+
};
|
|
240
|
+
if (existsSync(this.identityPath)) {
|
|
241
|
+
fail("GITVAULT_KEYSTORE_CONFLICT", "identity.json appeared concurrently; refusing to overwrite", "creating gitvault identity");
|
|
242
|
+
}
|
|
243
|
+
writeFileAtomic0600(this.identityPath, JSON.stringify(identity, null, 2));
|
|
244
|
+
this.audit("identity_created", undefined, { signing_fingerprint: identity.signing_fingerprint, encryption_fingerprint: identity.encryption_fingerprint });
|
|
245
|
+
return identity;
|
|
246
|
+
}
|
|
247
|
+
/** The signing keypair, or `null` when the signing seed is lost (read-only principal). */
|
|
248
|
+
signingKeypair(identity = this.requireIdentity()) {
|
|
249
|
+
if (!identity.signing_seed_hex)
|
|
250
|
+
return null;
|
|
251
|
+
const kp = generateSigningKeypair(hexToBytes(identity.signing_seed_hex));
|
|
252
|
+
if (vkFingerprint(kp.public_key) !== identity.signing_fingerprint) {
|
|
253
|
+
fail("GITVAULT_KEYSTORE_CORRUPT", "identity signing seed does not derive the recorded fingerprint", "loading gitvault signing key");
|
|
254
|
+
}
|
|
255
|
+
return kp;
|
|
256
|
+
}
|
|
257
|
+
/** The encryption keypair, or `null` when the X25519 private key is lost. */
|
|
258
|
+
encryptionKeypair(identity = this.requireIdentity()) {
|
|
259
|
+
if (!identity.encryption_private_key_hex)
|
|
260
|
+
return null;
|
|
261
|
+
const kp = generateEncryptionKeypair(hexToBytes(identity.encryption_private_key_hex));
|
|
262
|
+
if (ekFingerprint(kp.public_key) !== identity.encryption_fingerprint) {
|
|
263
|
+
fail("GITVAULT_KEYSTORE_CORRUPT", "identity encryption key does not derive the recorded fingerprint", "loading gitvault encryption key");
|
|
264
|
+
}
|
|
265
|
+
return kp;
|
|
266
|
+
}
|
|
267
|
+
requireIdentity() {
|
|
268
|
+
const id = this.readIdentity();
|
|
269
|
+
if (!id)
|
|
270
|
+
fail("VAULT_UNRECOVERABLE", GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, "loading gitvault identity", { statement: GITVAULT_TERMINAL_LOSS_STATEMENT });
|
|
271
|
+
return id;
|
|
272
|
+
}
|
|
273
|
+
// ── repo files ──
|
|
274
|
+
readRepo(repoId) {
|
|
275
|
+
const text = readFileNoFollow(this.repoPath(repoId));
|
|
276
|
+
if (!text)
|
|
277
|
+
return null;
|
|
278
|
+
const parsed = JSON.parse(text);
|
|
279
|
+
if (parsed.version !== 1 || parsed.repo_id !== repoId || typeof parsed.k_repo_hex !== "string") {
|
|
280
|
+
fail("GITVAULT_KEYSTORE_CORRUPT", `repos/${repoId}.json is not a version-1 gitvault repo file`, "reading gitvault repo file", { repo_id: repoId });
|
|
281
|
+
}
|
|
282
|
+
return parsed;
|
|
283
|
+
}
|
|
284
|
+
listRepoIds() {
|
|
285
|
+
if (!existsSync(this.reposDir))
|
|
286
|
+
return [];
|
|
287
|
+
return readdirSync(this.reposDir).filter((n) => n.endsWith(".json")).map((n) => n.slice(0, -5)).filter((id) => GITVAULT_SRC_RE.test(id)).sort();
|
|
288
|
+
}
|
|
289
|
+
/** Save (create or replace) a repo file under the per-repo lock. */
|
|
290
|
+
saveRepo(repo) {
|
|
291
|
+
const full = { version: 1, ...repo, updated_at: formatGitvaultTimestamp(this.now()) };
|
|
292
|
+
this.withRepoLock(repo.repo_id, () => {
|
|
293
|
+
writeFileAtomic0600(this.repoPath(repo.repo_id), JSON.stringify(full, null, 2));
|
|
294
|
+
});
|
|
295
|
+
this.audit("repo_saved", repo.repo_id, { provenance: repo.provenance, genesis_sha256: repo.genesis_sha256 });
|
|
296
|
+
return full;
|
|
297
|
+
}
|
|
298
|
+
/** Update the dual pins / last ref transaction without touching key material. */
|
|
299
|
+
updateRepo(repoId, patch) {
|
|
300
|
+
return this.withRepoLock(repoId, () => {
|
|
301
|
+
const existing = this.readRepo(repoId);
|
|
302
|
+
if (!existing)
|
|
303
|
+
fail("GITVAULT_REPO_STATE_MISSING", `no repo file for ${repoId}`, "updating gitvault repo file", { repo_id: repoId });
|
|
304
|
+
const full = { ...existing, ...patch, updated_at: formatGitvaultTimestamp(this.now()) };
|
|
305
|
+
writeFileAtomic0600(this.repoPath(repoId), JSON.stringify(full, null, 2));
|
|
306
|
+
return full;
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
// ── recovery receipts ──
|
|
310
|
+
saveRecoveryReceipt(receipt) {
|
|
311
|
+
// Not a secret — but written with the same discipline so a partially written
|
|
312
|
+
// receipt is never mistaken for a complete one.
|
|
313
|
+
writeFileAtomic0600(this.recoveryReceiptPath(receipt.repo_id), JSON.stringify(receipt, null, 2));
|
|
314
|
+
this.audit("recovery_receipt_stored", receipt.repo_id, { genesis_sha256: receipt.genesis_sha256 });
|
|
315
|
+
}
|
|
316
|
+
readRecoveryReceipt(repoId) {
|
|
317
|
+
const text = readFileNoFollow(this.recoveryReceiptPath(repoId));
|
|
318
|
+
return text ? JSON.parse(text) : null;
|
|
319
|
+
}
|
|
320
|
+
// ── per-repo lock ──
|
|
321
|
+
/**
|
|
322
|
+
* Run `fn` holding the per-repo lock (`repos/<repo_id>.lock/`, mkdir-atomic).
|
|
323
|
+
* A lock older than `staleAfterMs` whose recorded pid is dead is reclaimed
|
|
324
|
+
* (audited). Re-entrant for the same process+repo.
|
|
325
|
+
*/
|
|
326
|
+
withRepoLock(repoId, fn, options = {}) {
|
|
327
|
+
const lockDir = `${this.repoPath(repoId)}.lock`;
|
|
328
|
+
if (this.held.has(lockDir))
|
|
329
|
+
return fn();
|
|
330
|
+
const staleAfterMs = options.staleAfterMs ?? 10 * 60 * 1000;
|
|
331
|
+
const timeoutMs = options.timeoutMs ?? 30 * 1000;
|
|
332
|
+
const deadline = Date.now() + timeoutMs;
|
|
333
|
+
mkdir0700(this.reposDir);
|
|
334
|
+
for (;;) {
|
|
335
|
+
try {
|
|
336
|
+
mkdirSync(lockDir, { mode: DIR_MODE });
|
|
337
|
+
break;
|
|
338
|
+
}
|
|
339
|
+
catch (e) {
|
|
340
|
+
if (e.code !== "EEXIST")
|
|
341
|
+
throw e;
|
|
342
|
+
if (this.reclaimStaleLock(lockDir, repoId, staleAfterMs))
|
|
343
|
+
continue;
|
|
344
|
+
if (Date.now() >= deadline) {
|
|
345
|
+
fail("GITVAULT_KEYSTORE_LOCKED", `another process holds the lock for ${repoId}`, "acquiring gitvault repo lock", { repo_id: repoId, lock: lockDir });
|
|
346
|
+
}
|
|
347
|
+
const until = Date.now() + 25;
|
|
348
|
+
while (Date.now() < until) { /* spin */ }
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
try {
|
|
352
|
+
writeFileAtomic0600(join(lockDir, "owner.json"), JSON.stringify({ pid: process.pid, at: formatGitvaultTimestamp(this.now()) }));
|
|
353
|
+
}
|
|
354
|
+
catch {
|
|
355
|
+
/* owner record is advisory */
|
|
356
|
+
}
|
|
357
|
+
this.held.add(lockDir);
|
|
358
|
+
this.audit("lock_acquired", repoId);
|
|
359
|
+
try {
|
|
360
|
+
return fn();
|
|
361
|
+
}
|
|
362
|
+
finally {
|
|
363
|
+
this.held.delete(lockDir);
|
|
364
|
+
try {
|
|
365
|
+
safeRemoveLock(lockDir);
|
|
366
|
+
}
|
|
367
|
+
catch { /* best-effort */ }
|
|
368
|
+
this.audit("lock_released", repoId);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
held = new Set();
|
|
372
|
+
reclaimStaleLock(lockDir, repoId, staleAfterMs) {
|
|
373
|
+
let ownerPid;
|
|
374
|
+
let age = Number.POSITIVE_INFINITY;
|
|
375
|
+
try {
|
|
376
|
+
const st = statSync(lockDir);
|
|
377
|
+
age = Date.now() - st.mtimeMs;
|
|
378
|
+
const owner = readFileNoFollow(join(lockDir, "owner.json"));
|
|
379
|
+
if (owner)
|
|
380
|
+
ownerPid = JSON.parse(owner).pid;
|
|
381
|
+
}
|
|
382
|
+
catch {
|
|
383
|
+
/* unreadable owner record → rely on age */
|
|
384
|
+
}
|
|
385
|
+
const ownerDead = ownerPid !== undefined && ownerPid !== process.pid && !pidAlive(ownerPid);
|
|
386
|
+
if (age > staleAfterMs || ownerDead) {
|
|
387
|
+
try {
|
|
388
|
+
safeRemoveLock(lockDir);
|
|
389
|
+
this.audit("lock_stale_reclaimed", repoId, { owner_pid: ownerPid ?? null, age_ms: Math.round(age) });
|
|
390
|
+
return true;
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
return false;
|
|
397
|
+
}
|
|
398
|
+
// ── §5.1 transitions ──
|
|
399
|
+
/**
|
|
400
|
+
* Derive the partial-loss transition for one vault. `expectedGenesisSha256`
|
|
401
|
+
* (from a freshly listed genesis, 5.4) turns a pin mismatch into `stale_pin`.
|
|
402
|
+
*/
|
|
403
|
+
assess(repoId, expectedGenesisSha256) {
|
|
404
|
+
const identity = this.readIdentity();
|
|
405
|
+
const repo = this.readRepo(repoId);
|
|
406
|
+
let state;
|
|
407
|
+
if (!identity && !repo) {
|
|
408
|
+
state = { state: "unrecoverable", code: "VAULT_UNRECOVERABLE", statement: GITVAULT_TERMINAL_LOSS_STATEMENT, doctor_text: GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT };
|
|
409
|
+
}
|
|
410
|
+
else if (!identity && repo) {
|
|
411
|
+
// K_repo survives but no key can sign or open anything new: the history
|
|
412
|
+
// stays READABLE (K_repo decrypts) but nothing can be published.
|
|
413
|
+
state = { state: "read_only", repo, reason: "signing_key_lost" };
|
|
414
|
+
}
|
|
415
|
+
else if (identity && !repo) {
|
|
416
|
+
state = identity.encryption_private_key_hex
|
|
417
|
+
? { state: "repo_state_lost_identity_intact", next_action: "restore_from_envelope" }
|
|
418
|
+
: { state: "unrecoverable", code: "VAULT_UNRECOVERABLE", statement: GITVAULT_TERMINAL_LOSS_STATEMENT, doctor_text: GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT };
|
|
419
|
+
}
|
|
420
|
+
else if (identity && repo && !identity.signing_seed_hex) {
|
|
421
|
+
state = { state: "read_only", repo, reason: "signing_key_lost" };
|
|
422
|
+
}
|
|
423
|
+
else if (expectedGenesisSha256 !== undefined && repo && repo.genesis_sha256 !== expectedGenesisSha256) {
|
|
424
|
+
state = { state: "stale_pin", repo, next_action: "reverify_from_genesis" };
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
state = { state: "ready", repo: repo };
|
|
428
|
+
}
|
|
429
|
+
this.audit("transition_assessed", repoId, { state: state.state });
|
|
430
|
+
return state;
|
|
431
|
+
}
|
|
432
|
+
/**
|
|
433
|
+
* §5.1 "repo file lost + identity intact → restore K_repo from own envelope".
|
|
434
|
+
* The genesis is checked (signature + key bindings against the stored
|
|
435
|
+
* envelope + the recovery receipt/pin when one survives) BEFORE the envelope
|
|
436
|
+
* is opened; the restored file is marked `restored_from_envelope`.
|
|
437
|
+
*/
|
|
438
|
+
async restoreRepoFromEnvelope(input) {
|
|
439
|
+
const identity = this.readIdentity();
|
|
440
|
+
if (!identity)
|
|
441
|
+
fail("VAULT_UNRECOVERABLE", GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, "restoring gitvault repo state", { statement: GITVAULT_TERMINAL_LOSS_STATEMENT });
|
|
442
|
+
const recipient = this.encryptionKeypair(identity);
|
|
443
|
+
if (!recipient)
|
|
444
|
+
fail("VAULT_UNRECOVERABLE", GITVAULT_TERMINAL_LOSS_DOCTOR_TEXT, "restoring gitvault repo state", { statement: GITVAULT_TERMINAL_LOSS_STATEMENT });
|
|
445
|
+
const { genesis, envelope } = input;
|
|
446
|
+
if (!verifyGitvaultObject(genesis, genesis.creator_signing_pubkey)) {
|
|
447
|
+
fail("GITVAULT_SIGNATURE_INVALID", "vault_genesis signature does not verify", "restoring gitvault repo state", { repo_id: genesis.repo_id });
|
|
448
|
+
}
|
|
449
|
+
const bindings = checkGenesisKeyBindings(genesis, envelope);
|
|
450
|
+
if (bindings.length > 0) {
|
|
451
|
+
fail("VAULT_CREATION_CONFLICT", "genesis key bindings do not hold for the stored envelope", "restoring gitvault repo state", { repo_id: genesis.repo_id, problems: bindings });
|
|
452
|
+
}
|
|
453
|
+
const genesisSha = storedBytesSha256(genesis);
|
|
454
|
+
const receipt = input.recovery_receipt ?? this.readRecoveryReceipt(genesis.repo_id);
|
|
455
|
+
let trust = "unauthenticated_salvage";
|
|
456
|
+
if (receipt) {
|
|
457
|
+
const problems = checkRecoveryReceipt(receipt, genesis);
|
|
458
|
+
if (problems.length > 0) {
|
|
459
|
+
fail("VAULT_CREATION_CONFLICT", "recovery receipt does not pin this genesis (substituted vault?)", "restoring gitvault repo state", { repo_id: genesis.repo_id, problems });
|
|
460
|
+
}
|
|
461
|
+
trust = "receipt";
|
|
462
|
+
}
|
|
463
|
+
if (envelope.recipient_fingerprint !== identity.encryption_fingerprint) {
|
|
464
|
+
fail("GITVAULT_ENVELOPE_NOT_FOR_RECIPIENT", "the stored envelope is addressed to another principal", "restoring gitvault repo state", { recipient_fingerprint: envelope.recipient_fingerprint });
|
|
465
|
+
}
|
|
466
|
+
const kRepo = await openKeyEnvelope({ envelope, recipient, signer_public_key: genesis.creator_signing_pubkey });
|
|
467
|
+
const repo = this.saveRepo({
|
|
468
|
+
repo_id: genesis.repo_id,
|
|
469
|
+
org_id: genesis.org_id,
|
|
470
|
+
project_id: genesis.project_id,
|
|
471
|
+
k_repo_hex: bytesToHex(kRepo),
|
|
472
|
+
epoch: envelope.epoch,
|
|
473
|
+
genesis_sha256: genesisSha,
|
|
474
|
+
head_pin: null,
|
|
475
|
+
last_ref_transaction: null,
|
|
476
|
+
provenance: "restored_from_envelope",
|
|
477
|
+
});
|
|
478
|
+
this.audit("repo_restored_from_envelope", genesis.repo_id, { trust });
|
|
479
|
+
return { repo, trust };
|
|
480
|
+
}
|
|
481
|
+
/** Identity fingerprints for display/doctor (never key material). */
|
|
482
|
+
identitySummary() {
|
|
483
|
+
const id = this.readIdentity();
|
|
484
|
+
if (!id)
|
|
485
|
+
return null;
|
|
486
|
+
if (!GITVAULT_VK_RE.test(id.signing_fingerprint) || !GITVAULT_EK_RE.test(id.encryption_fingerprint)) {
|
|
487
|
+
fail("GITVAULT_KEYSTORE_CORRUPT", "identity fingerprints are malformed", "reading gitvault identity");
|
|
488
|
+
}
|
|
489
|
+
return {
|
|
490
|
+
signing_fingerprint: id.signing_fingerprint,
|
|
491
|
+
encryption_fingerprint: id.encryption_fingerprint,
|
|
492
|
+
signing_key_present: Boolean(id.signing_seed_hex),
|
|
493
|
+
encryption_key_present: Boolean(id.encryption_private_key_hex),
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
function isSymlink(path) {
|
|
498
|
+
try {
|
|
499
|
+
return lstatSync(path).isSymbolicLink();
|
|
500
|
+
}
|
|
501
|
+
catch {
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
function statSafe(path) {
|
|
506
|
+
try {
|
|
507
|
+
return lstatSync(path);
|
|
508
|
+
}
|
|
509
|
+
catch {
|
|
510
|
+
return null;
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
function pidAlive(pid) {
|
|
514
|
+
try {
|
|
515
|
+
process.kill(pid, 0);
|
|
516
|
+
return true;
|
|
517
|
+
}
|
|
518
|
+
catch (e) {
|
|
519
|
+
return e.code === "EPERM";
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
function safeRemoveLock(lockDir) {
|
|
523
|
+
const owner = join(lockDir, "owner.json");
|
|
524
|
+
// rmdir needs an empty directory; the owner record is the only file ever written there.
|
|
525
|
+
if (existsSync(owner))
|
|
526
|
+
unlinkSync(owner);
|
|
527
|
+
rmdirSync(lockDir);
|
|
528
|
+
}
|
|
529
|
+
//# sourceMappingURL=gitvault-keystore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitvault-keystore.js","sourceRoot":"","sources":["../../src/node/gitvault-keystore.ts"],"names":[],"mappings":"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"}
|