@graneth/verify
Advanced tools
+30
-0
@@ -15,1 +15,31 @@ /** | ||
| export declare function runVerifyCli(argv: string[], io: CliIO): number; | ||
| /** | ||
| * What the signature actually attests to — and, when it attests to less than a | ||
| * reader expects, SAYING SO instead of printing `undefined`. | ||
| * | ||
| * ── THE DEFECT THIS REPLACES ──────────────────────────────────────────────── | ||
| * The old lines interpolated the fields directly, so a receipt whose signed | ||
| * object omits them printed: | ||
| * | ||
| * PASS — Ed25519 signature is valid. | ||
| * scan #4821 undefined | ||
| * verdict: undefined (critical undefined, warnings undefined) | ||
| * | ||
| * Reproduced with a locally generated key, no production receipt needed: the | ||
| * signature IS valid there. `canonicalize()` signs whatever object it is given | ||
| * — the package documents that as forward-compatibility — so a valid signature | ||
| * over a sparse object is a legitimate state, not a corruption. | ||
| * | ||
| * ── WHY IT MATTERS MORE HERE THAN ANYWHERE ELSE ───────────────────────────── | ||
| * This is the only thing we ship that runs on the client's machine, offline, | ||
| * on evidence we asked them to trust without trusting us. A tool that prints | ||
| * PASS beside a blank is worse than one that fails: it spends the credibility | ||
| * the receipt exists to earn. The honest output distinguishes "the signature | ||
| * covers these facts" from "the signature is valid over an object that does | ||
| * not state them" — the same third state the scanner owes its own users. | ||
| * | ||
| * The exit code stays 0. The signature IS valid, scripts key on that, and | ||
| * changing the contract to express a display concern would break automation | ||
| * to fix prose. | ||
| */ | ||
| export declare function describeAttestation(attestation: unknown): string[]; |
+61
-6
@@ -112,10 +112,65 @@ /** | ||
| io.log("PASS — Ed25519 signature is valid."); | ||
| const attestation = receiptObj.attestation; | ||
| if (attestation && typeof attestation === "object") { | ||
| const a = attestation; | ||
| io.log(` scan #${a.scanId} ${a.repositoryName}`); | ||
| io.log(` verdict: ${a.verdict} (critical ${a.criticalCount}, warnings ${a.warningCount})`); | ||
| } | ||
| for (const line of describeAttestation(receiptObj.attestation)) | ||
| io.log(line); | ||
| io.log(` keyId: ${result.keyId}`); | ||
| return 0; | ||
| } | ||
| /** Fields a reader expects a governance receipt to attest to, and their labels. */ | ||
| const ATTESTED_FACTS = [ | ||
| ["repositoryName", "repository"], | ||
| ["verdict", "verdict"], | ||
| ["criticalCount", "critical findings"], | ||
| ["warningCount", "warnings"], | ||
| ]; | ||
| /** | ||
| * What the signature actually attests to — and, when it attests to less than a | ||
| * reader expects, SAYING SO instead of printing `undefined`. | ||
| * | ||
| * ── THE DEFECT THIS REPLACES ──────────────────────────────────────────────── | ||
| * The old lines interpolated the fields directly, so a receipt whose signed | ||
| * object omits them printed: | ||
| * | ||
| * PASS — Ed25519 signature is valid. | ||
| * scan #4821 undefined | ||
| * verdict: undefined (critical undefined, warnings undefined) | ||
| * | ||
| * Reproduced with a locally generated key, no production receipt needed: the | ||
| * signature IS valid there. `canonicalize()` signs whatever object it is given | ||
| * — the package documents that as forward-compatibility — so a valid signature | ||
| * over a sparse object is a legitimate state, not a corruption. | ||
| * | ||
| * ── WHY IT MATTERS MORE HERE THAN ANYWHERE ELSE ───────────────────────────── | ||
| * This is the only thing we ship that runs on the client's machine, offline, | ||
| * on evidence we asked them to trust without trusting us. A tool that prints | ||
| * PASS beside a blank is worse than one that fails: it spends the credibility | ||
| * the receipt exists to earn. The honest output distinguishes "the signature | ||
| * covers these facts" from "the signature is valid over an object that does | ||
| * not state them" — the same third state the scanner owes its own users. | ||
| * | ||
| * The exit code stays 0. The signature IS valid, scripts key on that, and | ||
| * changing the contract to express a display concern would break automation | ||
| * to fix prose. | ||
| */ | ||
| export function describeAttestation(attestation) { | ||
| if (!attestation || typeof attestation !== "object") | ||
| return []; | ||
| const a = attestation; | ||
| const has = (k) => a[k] !== undefined && a[k] !== null; | ||
| const lines = []; | ||
| const scan = has("scanId") ? `scan #${a.scanId}` : null; | ||
| const repo = has("repositoryName") ? String(a.repositoryName) : null; | ||
| if (scan || repo) | ||
| lines.push(` ${[scan, repo].filter(Boolean).join(" ")}`); | ||
| if (has("verdict")) { | ||
| const counts = has("criticalCount") && has("warningCount") | ||
| ? ` (critical ${a.criticalCount}, warnings ${a.warningCount})` | ||
| : ""; | ||
| lines.push(` verdict: ${a.verdict}${counts}`); | ||
| } | ||
| const missing = ATTESTED_FACTS.filter(([field]) => !has(field)).map(([, label]) => label); | ||
| if (missing.length > 0) { | ||
| lines.push(` NOT ATTESTED: ${missing.join(", ")} — the signature is valid, but`); | ||
| lines.push(" this receipt's signed object does not carry those facts."); | ||
| } | ||
| return lines; | ||
| } |
+1
-1
| { | ||
| "name": "@graneth/verify", | ||
| "version": "0.1.0", | ||
| "version": "0.1.1", | ||
| "description": "Offline verifier for Graneth's signed governance receipts — checks the Ed25519 signature against a public key you already have. Zero network calls, zero runtime dependencies.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+24
-0
@@ -21,2 +21,26 @@ # @graneth/verify | ||
| ## What a PASS tells you — and what it does not | ||
| ``` | ||
| PASS — Ed25519 signature is valid. | ||
| scan #4821 acme-corp/payments-api | ||
| verdict: PASSED (critical 0, warnings 2) | ||
| keyId: 3ed76e31c05aecdb | ||
| ``` | ||
| The signature covers **the object it was given**, so a receipt can be validly | ||
| signed and still not state a repository or a verdict. When that happens the | ||
| tool says so rather than printing a blank: | ||
| ``` | ||
| PASS — Ed25519 signature is valid. | ||
| scan #4821 | ||
| NOT ATTESTED: repository, verdict — the signature is valid, but | ||
| this receipt's signed object does not carry those facts. | ||
| ``` | ||
| Exit code is still 0 in that case: the signature really is valid, and scripts | ||
| key on that. What changes is that the human reading it is not left to assume | ||
| the receipt attested to more than it did. | ||
| Programmatic use: `import { verifyReceipt } from "@graneth/verify"`. | ||
@@ -23,0 +47,0 @@ |
21936
32.11%419
25.45%50
92.31%