🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@veritasacta/verify

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@veritasacta/verify - npm Package Compare versions

Comparing version
0.2.4
to
0.2.5
+50
-11
cli.js

@@ -17,4 +17,5 @@ #!/usr/bin/env node

* Exit codes:
* 0 = valid
* 1 = invalid or error
* 0 = signature valid (proven authentic)
* 1 = signature invalid (proven tampered)
* 2 = verifier error (malformed input, missing key, parse failure — undecidable)
*/

@@ -114,4 +115,5 @@

${bold('Exit Codes:')}
0 All artifacts valid
1 Invalid signature, error, or missing input
0 Signature valid — proven authentic
1 Signature invalid — proven tampered
2 Verifier error — malformed input, missing key, or parse failure
`);

@@ -429,3 +431,3 @@ }

console.log('');
process.exit(allPassed ? 0 : 1);
process.exit(allPassed ? 0 : 1); // self-test: 0=pass, 1=fail (not a verification result)
}

@@ -447,7 +449,7 @@

console.error('Usage: npx @veritasacta/verify <file.json> [--key <hex>]');
process.exit(1);
process.exit(2);
}
} catch (err) {
console.error(red(`Error reading input: ${err.message}`));
process.exit(1);
process.exit(2);
}

@@ -460,3 +462,3 @@

console.error(red(`Error: Invalid JSON: ${err.message}`));
process.exit(1);
process.exit(2);
}

@@ -468,3 +470,3 @@

printBundleResult(result, opts);
process.exit(result.valid ? 0 : 1);
process.exit(exitCodeForResult(result));
}

@@ -475,8 +477,45 @@

printResult(result, opts);
process.exit(result.valid ? 0 : 1);
process.exit(exitCodeForResult(result));
}
/**
* Derive exit code from a verification result.
*
* 0 = signature valid (proven authentic)
* 1 = signature invalid (proven tampered — the math confirms modification)
* 2 = verifier error (undecidable — missing key, malformed input, etc.)
*
* The distinction matters: exit 1 is a security event (evidence of tampering).
* Exit 2 is an operational error (the check could not be performed).
*/
function exitCodeForResult(result) {
if (result.valid) return 0;
// These errors mean the verifier could not perform the check at all.
// The signature was not tested — the result is undecidable.
const undecidableErrors = [
'no_public_key',
'missing_signature',
'missing_payload',
'unsupported_algorithm',
];
if (result.error && undecidableErrors.includes(result.error)) return 2;
if (result.error && result.error.startsWith('JWKS')) return 2;
// For bundles: if any receipt had an undecidable error, the bundle is undecidable
if (result.errors && Array.isArray(result.errors)) {
const hasUndecidable = result.errors.some(e =>
undecidableErrors.some(u => e.includes(u))
);
if (hasUndecidable) return 2;
}
// Default: the signature was tested and failed. This is proven tampering.
return 1;
}
main().catch((err) => {
console.error(red(`Fatal error: ${err.message}`));
process.exit(1);
process.exit(2);
});
+1
-1
{
"name": "@veritasacta/verify",
"version": "0.2.4",
"version": "0.2.5",
"mcpName": "io.github.tomjwxf/veritasacta-verify",

@@ -5,0 +5,0 @@ "description": "CLI tool to verify signed artifacts (receipts, manifests, tickets). Works offline.",

@@ -79,5 +79,11 @@ # @veritasacta/verify

- `0` — signature valid (all artifacts valid for bundles)
- `1` — signature invalid, missing key, or error
| Code | Meaning | Semantics |
|------|---------|-----------|
| `0` | Signature valid | **Proven authentic** — the Ed25519 math confirms this artifact has not been modified since signing |
| `1` | Signature invalid | **Proven tampered** — the signature does not match the payload. This is a security event. |
| `2` | Verifier error | **Undecidable** — malformed input, missing key, unparseable JSON. The check could not be performed. |
The distinction matters: exit 1 is evidence of tampering (the math was tested and failed).
Exit 2 is an operational error (the math was never tested). These demand different responses.
## Where Do Receipts Come From?

@@ -84,0 +90,0 @@

@@ -12,5 +12,6 @@ #!/usr/bin/env node

import { readFileSync } from 'node:fs';
import { readFileSync, writeFileSync, unlinkSync } from 'node:fs';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { execFileSync } from 'node:child_process';
import { verifyArtifact } from '@veritasacta/artifacts';

@@ -110,2 +111,64 @@

// ── Exit Code Contract (3-way split) ────────────────────────────
console.log('\n⬢ Exit code contract (0=valid, 1=invalid, 2=error)\n');
const cliPath = join(pkgRoot, 'cli.js');
function runCli(args) {
try {
execFileSync('node', [cliPath, ...args], {
stdio: 'pipe',
timeout: 10000,
});
return 0;
} catch (err) {
return err.status;
}
}
// Exit 0: valid receipt with correct key
assert(
runCli([join(pkgRoot, 'samples', 'sample-receipt.json'), '--key', sampleKey]) === 0,
'Exit 0 for valid receipt'
);
// Exit 1: tampered artifact (wrong key forces signature mismatch)
assert(
runCli([join(pkgRoot, 'samples', 'sample-receipt.json'), '--key', '0000000000000000000000000000000000000000000000000000000000000000']) === 1,
'Exit 1 for invalid signature (wrong key)'
);
// Exit 2: no input file specified
assert(
runCli([]) === 2,
'Exit 2 for missing input'
);
// Exit 2: non-existent file
assert(
runCli(['/tmp/nonexistent_file_for_verify_test.json']) === 2,
'Exit 2 for unreadable file'
);
// Exit 2: malformed JSON (test with a temp file containing invalid JSON)
const badJsonPath = join(pkgRoot, 'test', '_tmp_bad.json');
writeFileSync(badJsonPath, 'not-valid-json{{{');
assert(
runCli([badJsonPath]) === 2,
'Exit 2 for invalid JSON'
);
// Exit 2: valid JSON but missing required fields (no key)
const malformedPath = join(pkgRoot, 'test', '_tmp_malformed.json');
writeFileSync(malformedPath, '{"type": "protectmcp:decision", "tool_name": "something"}');
assert(
runCli([malformedPath]) === 2,
'Exit 2 for missing public key (undecidable)'
);
// Clean up temp files
try { unlinkSync(badJsonPath); } catch {}
try { unlinkSync(malformedPath); } catch {}
// ── Results ─────────────────────────────────────────────────────

@@ -112,0 +175,0 @@