aqta-verify-receipt 1.0.2 → 1.0.5

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 CHANGED
@@ -1,172 +1,138 @@
1
+ ```
2
+ ▄▄▄▄▄▄▄▄
3
+ ▄███████▀████▄▄
4
+ ▄████████████████
5
+ ██████████████▀▀
6
+ █████████████▀
7
+ ▄█████████████
8
+ ▄██████████████
9
+ ▄█████████████████
10
+ ▄███████████████████
11
+ ████████████████████ ▄
12
+ ██████████████▀ ████ ▄▀
13
+ ▀▀█████████▀ ███▀ ▄▄▀▀
14
+ ▀▀▀██▄▄▄▄▄▄██▀ ▀▀
15
+ ```
16
+
1
17
  # aqta-verify-receipt
2
18
 
3
19
  [![npm](https://img.shields.io/npm/v/aqta-verify-receipt.svg)](https://www.npmjs.com/package/aqta-verify-receipt)
4
- [![CI](https://github.com/Aqta-ai/attestation-spec/actions/workflows/test.yml/badge.svg)](https://github.com/Aqta-ai/attestation-spec/actions/workflows/test.yml)
5
- [![Licence](https://img.shields.io/badge/licence-Apache--2.0-blue.svg)](https://github.com/Aqta-ai/attestation-spec/blob/main/LICENSE)
20
+ [![PyPI](https://img.shields.io/pypi/v/aqta-verify-receipt.svg)](https://pypi.org/project/aqta-verify-receipt/)
21
+ [![Licence](https://img.shields.io/badge/licence-Apache--2.0-blue.svg)](LICENSE)
6
22
 
7
- Independent verifier for [AqtaCore](https://app.aqta.ai) attestation
8
- receipts. Checks the Ed25519 signature on an enforcement-attestation
9
- receipt using only the published public key: **no dependency on Aqta's
10
- servers**.
23
+ Offline verifier for **Seal** receipts ([ATTESTATION-v1](https://github.com/Aqta-ai/attestation-spec/blob/main/spec/ATTESTATION-v1.md)).
11
24
 
12
- ## Why this exists
25
+ Seal signs the model call at runtime. This package checks that signature
26
+ without contacting Aqta. No account. Exit code only if you want it quiet.
13
27
 
14
- AqtaCore returns a signed receipt with every AI enforcement decision.
15
- Regulators, auditors, and internal compliance teams need to verify
16
- those receipts independently, without trusting the issuer. This
17
- package is the reference implementation of that verifier, maintained
18
- by Aqta under the open
19
- [ATTESTATION-v1](https://github.com/Aqta-ai/attestation-spec/blob/main/spec/ATTESTATION-v1.md)
20
- format specification.
28
+ Same algorithm on npm and PyPI. Reference implementation, not a platform SDK.
21
29
 
22
- This verifier is the same code path AqtaCore uses internally to
23
- validate its own production receipts and to power the receipt-
24
- verification endpoint exposed to customer audit teams.
25
-
26
- ## Install
30
+ ## 30-second check
27
31
 
28
32
  ```bash
29
- npm install aqta-verify-receipt
33
+ # download a receipt JSON, then:
34
+ npx aqta-verify-receipt@1.0.5 receipt.json \
35
+ --key gUoUhIvptKAoLTnry3VrDtOQEWggGQveLrHFVrfNqmE
30
36
  ```
31
37
 
32
- Two dependencies: `tweetnacl` and `tweetnacl-util`, for constant-time
33
- Ed25519 verification.
34
-
35
- ## Usage
36
-
37
- ```ts
38
- import { verifyReceipt, fetchPublishedPublicKey } from 'aqta-verify-receipt';
38
+ Or pipe a public share link body:
39
39
 
40
- // ONE-TIME, on first use of this library in your environment.
41
- const trustedPublicKey = await fetchPublishedPublicKey();
42
- saveToConfig(trustedPublicKey); // file, database, KMS, secret manager
43
-
44
- // EVERY VERIFICATION: load the pinned value, do not re-fetch.
45
- const pinned = loadFromConfig();
46
- const result = verifyReceipt(receipt, { trustedPublicKey: pinned });
47
-
48
- if (!result.valid) {
49
- throw new Error(`Receipt invalid: ${result.reason}`);
50
- }
40
+ ```bash
41
+ curl -sS https://api.aqta.ai/r/YOUR_RECEIPT_ID | npx aqta-verify-receipt@1.0.5 - \
42
+ --key gUoUhIvptKAoLTnry3VrDtOQEWggGQveLrHFVrfNqmE
51
43
  ```
52
44
 
53
- ## ⚠️ Pin the public key. Do not re-fetch on every call.
54
-
55
- `fetchPublishedPublicKey()` performs a live HTTPS fetch. Calling it
56
- inside a verification loop collapses the trust model back to "trust the
57
- issuer's server right now", which is exactly what this format is
58
- designed to avoid.
45
+ `ok` + exit `0` means the Ed25519 signature verifies against the pinned key.
46
+ `fail` + exit `1` means it does not. Exit `2` is usage or IO.
59
47
 
60
- **The correct pattern is:**
48
+ Production public key (also at
49
+ [`/v1/attestation/public-key`](https://api.aqta.ai/v1/attestation/public-key),
50
+ key id `aqta-att-0a18c7c16bc18a12`):
61
51
 
62
- 1. Fetch once, on first use.
63
- 2. Persist the result (configuration, database, KMS, secret manager).
64
- 3. Pass the persisted value as `trustedPublicKey` on every verification
65
- thereafter.
66
- 4. Rotate only when you receive a documented key-rotation notice via a
67
- channel you already trust.
52
+ ```
53
+ gUoUhIvptKAoLTnry3VrDtOQEWggGQveLrHFVrfNqmE
54
+ ```
68
55
 
69
- Re-fetching the key on every verification is a misuse.
56
+ Pin that string. Do not re-fetch it inside a verify loop.
70
57
 
71
- ## API
58
+ ## Install
72
59
 
73
- ### `verifyReceipt(receipt, options?) → { valid, reason? }`
60
+ ```bash
61
+ npm install aqta-verify-receipt
62
+ # or one-shot:
63
+ npx aqta-verify-receipt receipt.json --key <pinned>
64
+ ```
74
65
 
75
- Verifies an attestation receipt against the declared (or pinned)
76
- public key.
66
+ Two runtime deps: `tweetnacl`, `tweetnacl-util`.
77
67
 
78
- Options:
79
- - `trustedPublicKey`: base64url public key. If set, the receipt's
80
- `public_key` field must match byte for byte. **Strongly recommended
81
- for production.**
82
- - `strictFields` (default `true`): any unknown top-level field causes
83
- rejection, per ATTESTATION-v1 §4. See "Forward compatibility" below.
68
+ ## Library
84
69
 
85
- Returns `{ valid: boolean, reason?: string }`. **Never throws.**
70
+ ```ts
71
+ import { verifyReceipt, fetchPublishedPublicKey } from 'aqta-verify-receipt';
86
72
 
87
- ### `fetchPublishedPublicKey(url?) → Promise<string>`
73
+ // Once per environment: fetch, then pin somewhere you control.
74
+ const trustedPublicKey = await fetchPublishedPublicKey();
88
75
 
89
- Fetches the AqtaCore public key from
90
- `https://app.aqta.ai/security/pubkey.txt`. Pass a custom URL for
91
- self-hosted issuers. **Pin the result; see the warning above.**
76
+ const result = verifyReceipt(receipt, { trustedPublicKey });
77
+ if (!result.valid) throw new Error(result.reason);
78
+ ```
92
79
 
93
- ## Forward compatibility
80
+ ### Pin the key
94
81
 
95
- `strictFields: true` (the default) rejects any receipt containing a
96
- field not defined in the version of the spec this library was built
97
- against. This is the correct behaviour for a security-critical
98
- verifier: a receipt containing an unknown field may carry
99
- attacker-controlled metadata that downstream systems should not treat
100
- as signed evidence.
82
+ `fetchPublishedPublicKey()` is for first-time setup. Calling it on every
83
+ verify collapses trust back to "trust the issuer's server right now".
101
84
 
102
- ATTESTATION-v1 versioning policy:
85
+ 1. Fetch once.
86
+ 2. Persist (config, KMS, secret store).
87
+ 3. Pass `trustedPublicKey` on every call.
88
+ 4. Rotate only on a documented key-rotation notice.
103
89
 
104
- - **Patch** versions of the spec (v1.0.x): clarifications only, no
105
- field changes. Your verifier keeps working.
106
- - **Minor** versions of the spec (v1.x.0): may add new optional
107
- fields. A v1.0-era verifier will reject v1.1 receipts under
108
- `strictFields: true`. Upgrade the verifier, or set
109
- `strictFields: false` to let forward receipts through the signature
110
- check. Cryptographic verification still holds in both cases; only
111
- the structural-allowlist check is relaxed.
112
- - **Major** versions (vN.0, N ≥ 2): breaking changes; upgrade
113
- required.
90
+ ## CLI
114
91
 
115
- Set `strictFields: false` only if your compliance team has reviewed
116
- the forward-compatibility trade-off.
92
+ ```
93
+ aqta-verify-receipt <file|-> --key <base64url> [--no-strict] [-q]
94
+ aqta-verify-receipt <file|-> --integrity-only [--no-strict] [-q]
95
+ ```
117
96
 
118
- ## Test vectors
97
+ | Flag | Meaning |
98
+ |------|---------|
99
+ | `--key` | Pin issuer identity (required for counsel-grade). |
100
+ | `--integrity-only` | Signature vs embedded key only; returns untrusted. Anyone can self-sign. |
101
+ | `--no-strict` | Allow unknown top-level fields |
102
+ | `-q` | Silent; exit code only |
119
103
 
120
- A conformance suite for this library (6 valid + 8 invalid receipts,
121
- each documenting one specific behaviour) lives in the spec repository:
104
+ ## API
122
105
 
123
- - Vectors: [`test-vectors/`](https://github.com/Aqta-ai/attestation-spec/tree/main/test-vectors)
124
- - Reproducible generator:
125
- [`test-vectors/generate.py`](https://github.com/Aqta-ai/attestation-spec/blob/main/test-vectors/generate.py)
106
+ ### `verifyReceipt(receipt, options?) → { valid, reason?, keySource? }`
126
107
 
127
- If your verifier disagrees with any vector, please file an issue on
128
- [Aqta-ai/attestation-spec](https://github.com/Aqta-ai/attestation-spec/issues).
108
+ Never throws. **Pinning is required by default.** Without `trustedPublicKey`,
109
+ returns `valid: false` unless `allowUntrustedEmbeddedKey: true` (then
110
+ `keySource: "untrusted"` on success). Default `strictFields: true` rejects
111
+ unknown top-level fields (ATTESTATION-v1 §4).
129
112
 
130
- ### Quick self-test
113
+ ### `fetchPublishedPublicKey(url?) → Promise<string>`
131
114
 
132
- To confirm your environment and this library behave as the spec
133
- intends, run all 14 vectors in one command after installing:
115
+ Default: `https://app.aqta.ai/security/pubkey.txt`. Same material as
116
+ `https://api.aqta.ai/v1/attestation/public-key`.
134
117
 
135
- ```bash
136
- git clone https://github.com/Aqta-ai/attestation-spec.git
137
- cd attestation-spec
138
- npm install aqta-verify-receipt
139
- node - <<'JS'
140
- const fs = require('node:fs');
141
- const path = require('node:path');
142
- const { verifyReceipt } = require('aqta-verify-receipt');
143
-
144
- const TRUSTED = 'alWzEnrA_z9McN9z_MFfQCnH9mVgOwRZ26wrI7oix4E';
145
-
146
- for (const sub of ['valid', 'invalid']) {
147
- const shouldPass = sub === 'valid';
148
- for (const name of fs.readdirSync(path.join('test-vectors', sub)).sort()) {
149
- const r = JSON.parse(fs.readFileSync(path.join('test-vectors', sub, name), 'utf8'));
150
- const { valid } = verifyReceipt(r, { trustedPublicKey: TRUSTED });
151
- if (valid !== shouldPass) throw new Error(`${sub}/${name} behaved wrong`);
152
- }
153
- }
154
- console.log('all 14 vectors behave as specified');
155
- JS
156
- ```
118
+ ## Test vectors
157
119
 
158
- A clean run prints `all 14 vectors behave as specified` and exits 0.
120
+ Conformance suite (6 valid + 8 invalid):
121
+ [`test-vectors/`](https://github.com/Aqta-ai/attestation-spec/tree/main/test-vectors).
159
122
 
160
- ## Receipt format
123
+ ## What this is not
161
124
 
162
- See [ATTESTATION-v1](https://github.com/Aqta-ai/attestation-spec/blob/main/spec/ATTESTATION-v1.md).
125
+ Not a governance dashboard. Not a cost router. Not a chain explorer.
126
+ A small verifier for one signed model-call receipt.
163
127
 
164
- ## Security issues
128
+ ## Security
165
129
 
166
- Please do not open public GitHub issues for cryptographic
167
- vulnerabilities. See
168
- [SECURITY.md](https://github.com/Aqta-ai/attestation-spec/blob/main/SECURITY.md).
130
+ Cryptographic issues: see [SECURITY.md](../../SECURITY.md). Prefer
131
+ security@aqta.ai over public issues for key or signature bugs.
169
132
 
170
133
  ## Licence
171
134
 
172
- Apache-2.0.
135
+ Apache-2.0. Aqta Technologies Limited.
136
+
137
+ If you implement or cite the ATTESTATION-v1 format itself, credit under
138
+ CC-BY-4.0: see the repo [CITATION.cff](https://github.com/Aqta-ai/attestation-spec/blob/main/CITATION.cff).
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/cli.js');
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,170 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ /**
5
+ * aqta-verify-receipt CLI.
6
+ *
7
+ * Offline check of an ATTESTATION-v1 receipt. No account. No network by
8
+ * default. Exit 0 if the signature verifies, 1 if not, 2 on usage/IO errors.
9
+ *
10
+ * npx aqta-verify-receipt receipt.json --key <base64url-ed25519-key>
11
+ * curl -sS https://api.aqta.ai/r/REC_ID | npx aqta-verify-receipt - --key <key>
12
+ * npx aqta-verify-receipt receipt.json --integrity-only
13
+ */
14
+ const fs_1 = require("fs");
15
+ const index_1 = require("./index");
16
+ const PUB_KEY_HINT = 'https://api.aqta.ai/v1/attestation/public-key';
17
+ /**
18
+ * The Seal mark, traced from the brand artwork: head up, snout right,
19
+ * one eye (the notch in the head). Half blocks give twice the vertical
20
+ * resolution per line; plain ASCII is the fallback for non UTF-8 terminals.
21
+ */
22
+ const SEAL_BLOCK = [
23
+ ' ▄▄▄▄▄▄▄▄',
24
+ ' ▄███████▀████▄▄',
25
+ ' ▄████████████████',
26
+ ' ██████████████▀▀',
27
+ ' █████████████▀',
28
+ ' ▄█████████████',
29
+ ' ▄██████████████',
30
+ ' ▄█████████████████',
31
+ '▄███████████████████',
32
+ '████████████████████ ▄',
33
+ '██████████████▀ ████ ▄▀',
34
+ ' ▀▀█████████▀ ███▀ ▄▄▀▀',
35
+ ' ▀▀▀██▄▄▄▄▄▄██▀ ▀▀',
36
+ ];
37
+ const SEAL_ASCII = [
38
+ ' +%@@@@%+',
39
+ ' %@@@@@@oo@@@@@',
40
+ ' @@@@@@@@@@@@@@+',
41
+ ' +@@@@@@@@@@@+',
42
+ ' @@@@@@@@@@@',
43
+ ' +@@@@@@@@@@@@%',
44
+ ' @@@@@@@@@@@@@@@',
45
+ '@@@@@@@@@@@@@@@@@%',
46
+ '@@@@@@@@@@@@@%@@@%',
47
+ '+%@@@@@@@@@+ @@@',
48
+ ' +%@@%+ @@+',
49
+ ];
50
+ /**
51
+ * Human-facing stamp: an intact seal when the signature verifies, a sheared
52
+ * one when it does not, so the shape carries the answer before the word.
53
+ *
54
+ * stderr only, TTY only, so piped runs still see exactly the verdict line.
55
+ */
56
+ function stamp(valid) {
57
+ if (!process.stderr.isTTY)
58
+ return;
59
+ const utf8 = /UTF-?8/i.test(process.env.LC_ALL || process.env.LC_CTYPE || process.env.LANG || '');
60
+ const ESC = String.fromCharCode(27);
61
+ const colour = process.env.NO_COLOR === undefined;
62
+ const body = colour ? ESC + '[' + (valid ? '32' : '31') + 'm' : '';
63
+ const off = colour ? ESC + '[0m' : '';
64
+ // A failed check shears the mark along its midline: the seal is broken.
65
+ const base = utf8 ? SEAL_BLOCK : SEAL_ASCII;
66
+ const half = Math.ceil(base.length / 2);
67
+ const art = valid ? base : base.map((l, i) => (i < half ? l : ' ' + l));
68
+ const painted = art.map((l) => body + l + off);
69
+ painted.push(body + (valid ? ' sealed' : ' broken') + off);
70
+ process.stderr.write(painted.join('\n') + '\n');
71
+ }
72
+ function usage() {
73
+ console.error(`aqta-verify-receipt - offline check for ATTESTATION-v1 (Seal)
74
+
75
+ Usage:
76
+ aqta-verify-receipt <receipt.json | -> --key <base64url> [--no-strict] [-q]
77
+ aqta-verify-receipt <receipt.json | -> --integrity-only [--no-strict] [-q]
78
+
79
+ Options:
80
+ --key <key> pin the issuer public key (required for counsel-grade)
81
+ --integrity-only check signature vs embedded key only (anyone can self-sign)
82
+ --no-strict allow unknown top-level fields
83
+ -q, --quiet exit code only
84
+
85
+ Pin the production key once from ${PUB_KEY_HINT}
86
+ (field public_key). Do not re-fetch on every verify.
87
+ `);
88
+ process.exit(2);
89
+ }
90
+ function main() {
91
+ const args = process.argv.slice(2);
92
+ if (args.length === 0 || args.includes('--help') || args.includes('-h'))
93
+ usage();
94
+ let file = '';
95
+ let trustedKey;
96
+ let integrityOnly = false;
97
+ let strict = true;
98
+ let quiet = false;
99
+ for (let i = 0; i < args.length; i++) {
100
+ const a = args[i];
101
+ if (a === '--key') {
102
+ trustedKey = args[++i];
103
+ if (!trustedKey)
104
+ usage();
105
+ }
106
+ else if (a === '--integrity-only') {
107
+ integrityOnly = true;
108
+ }
109
+ else if (a === '--no-strict') {
110
+ strict = false;
111
+ }
112
+ else if (a === '--quiet' || a === '-q') {
113
+ quiet = true;
114
+ }
115
+ else if (!file) {
116
+ file = a;
117
+ }
118
+ else {
119
+ usage();
120
+ }
121
+ }
122
+ if (!file)
123
+ usage();
124
+ if (!trustedKey && !integrityOnly) {
125
+ console.error('aqta-verify-receipt: pass --key <pinned> (or --integrity-only for embedded-key checks)');
126
+ process.exit(2);
127
+ }
128
+ if (trustedKey && integrityOnly) {
129
+ console.error('aqta-verify-receipt: use --key or --integrity-only, not both');
130
+ process.exit(2);
131
+ }
132
+ let raw;
133
+ try {
134
+ raw = file === '-' ? (0, fs_1.readFileSync)(0, 'utf8') : (0, fs_1.readFileSync)(file, 'utf8');
135
+ }
136
+ catch {
137
+ console.error(`aqta-verify-receipt: cannot read ${file === '-' ? 'stdin' : file}`);
138
+ process.exit(2);
139
+ }
140
+ let receipt;
141
+ try {
142
+ receipt = JSON.parse(raw);
143
+ }
144
+ catch {
145
+ console.error('aqta-verify-receipt: input is not valid JSON');
146
+ process.exit(2);
147
+ }
148
+ const result = (0, index_1.verifyReceipt)(receipt, {
149
+ trustedPublicKey: trustedKey,
150
+ allowUntrustedEmbeddedKey: integrityOnly,
151
+ strictFields: strict,
152
+ });
153
+ if (!quiet) {
154
+ stamp(result.valid);
155
+ const id = typeof receipt.attestation_id === 'string' ? receipt.attestation_id : '?';
156
+ const outcome = typeof receipt.outcome === 'string' ? receipt.outcome : '?';
157
+ if (result.valid) {
158
+ const trust = result.keySource === 'pinned'
159
+ ? 'pinned key'
160
+ : 'untrusted embedded key (integrity only)';
161
+ console.log(`ok ${outcome} ${id} ${trust}`);
162
+ }
163
+ else {
164
+ console.log(`fail ${result.reason ?? 'verification failed'} ${id}`);
165
+ }
166
+ }
167
+ process.exit(result.valid ? 0 : 1);
168
+ }
169
+ main();
170
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * aqta-verify-receipt
3
3
  *
4
- * Independent verifier for AqtaCore attestation receipts (ATTESTATION-v1).
4
+ * Independent verifier for Seal attestation receipts (ATTESTATION-v1).
5
5
  * Verifies the Ed25519 signature on a receipt using only the published
6
6
  * public key: no dependency on any third-party server.
7
7
  *
@@ -24,14 +24,19 @@ export interface AttestationReceipt {
24
24
  }
25
25
  export interface VerifyOptions {
26
26
  /**
27
- * The trusted public key (base64url, no padding). If supplied, the receipt
28
- * is rejected unless its `public_key` field matches byte-for-byte. This
29
- * prevents an attacker from substituting a different key.
27
+ * Trusted issuer public key (base64url, no padding). Required for a
28
+ * counsel-grade check: the receipt must carry this key and verify under it.
30
29
  *
31
- * If omitted, the receipt is verified against whatever public key it
32
- * declares. This is lower trust but useful for offline / one-shot checks.
30
+ * Omit only with `allowUntrustedEmbeddedKey: true` for integrity-only
31
+ * checks against whatever key the receipt embeds (anyone can self-sign).
33
32
  */
34
33
  trustedPublicKey?: string;
34
+ /**
35
+ * If true, verify against the receipt's embedded `public_key` without
36
+ * pinning an issuer. Result includes `keySource: "untrusted"`. Default
37
+ * false: without `trustedPublicKey`, verification fails.
38
+ */
39
+ allowUntrustedEmbeddedKey?: boolean;
35
40
  /**
36
41
  * If true, unknown top-level fields in the receipt cause rejection. Default
37
42
  * true per spec §4: "Verifiers MUST reject receipts containing unknown
@@ -39,18 +44,24 @@ export interface VerifyOptions {
39
44
  */
40
45
  strictFields?: boolean;
41
46
  }
47
+ export type KeySource = 'pinned' | 'untrusted';
42
48
  export interface VerifyResult {
43
49
  valid: boolean;
44
50
  reason?: string;
51
+ /** Present when `valid` is true. */
52
+ keySource?: KeySource;
45
53
  }
46
54
  /**
47
- * Verify an AqtaCore attestation receipt.
55
+ * Verify a Seal attestation receipt.
56
+ *
57
+ * Pinning is required by default. A self-signed receipt must not return
58
+ * `valid: true` unless `allowUntrustedEmbeddedKey` is set.
48
59
  *
49
60
  * @param receipt The full receipt object (including `signature`).
50
- * @param options Optional verification constraints.
51
- * @returns `{ valid: true }` if the signature is valid under the
52
- * declared (and optionally pinned) public key; otherwise
53
- * `{ valid: false, reason: string }`.
61
+ * @param options Verification constraints.
62
+ * @returns `{ valid: true, keySource }` if the signature is valid under
63
+ * the pinned (or explicitly allowed embedded) public key;
64
+ * otherwise `{ valid: false, reason: string }`.
54
65
  *
55
66
  * @example
56
67
  * const result = verifyReceipt(receipt, {
@@ -60,7 +71,7 @@ export interface VerifyResult {
60
71
  */
61
72
  export declare function verifyReceipt(receipt: unknown, options?: VerifyOptions): VerifyResult;
62
73
  /**
63
- * Fetch the AqtaCore public key from the published URL and return it as a
74
+ * Fetch the Seal public key from the published URL and return it as a
64
75
  * base64url string ready to pass to `verifyReceipt` as `trustedPublicKey`.
65
76
  *
66
77
  * **PIN THE RESULT.** This helper performs a live HTTPS fetch. Calling it
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;IACzD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;;OAOG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAoED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAuEd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,SAA4C,GAC9C,OAAO,CAAC,MAAM,CAAC,CAMjB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,8DAA8D;AAC9D,MAAM,WAAW,kBAAkB;IACjC,CAAC,EAAE,MAAM,CAAC;IACV,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,QAAQ,CAAC;IACzD,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAsED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAqFd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,SAA4C,GAC9C,OAAO,CAAC,MAAM,CAAC,CAMjB"}
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /**
3
3
  * aqta-verify-receipt
4
4
  *
5
- * Independent verifier for AqtaCore attestation receipts (ATTESTATION-v1).
5
+ * Independent verifier for Seal attestation receipts (ATTESTATION-v1).
6
6
  * Verifies the Ed25519 signature on a receipt using only the published
7
7
  * public key: no dependency on any third-party server.
8
8
  *
@@ -67,24 +67,29 @@ function canonicalValue(v) {
67
67
  return '[' + v.map(canonicalValue).join(',') + ']';
68
68
  }
69
69
  if (typeof v === 'number') {
70
- // Preserving the serialisation of floats such as 0.0 as "0.0" is NOT
71
- // spec. JSON.stringify(0) yields "0" and that is what Python json.dumps
72
- // yields for float 0.0 when sort_keys=True on a rounded value. For the
73
- // one float field on the receipt (cost_prevented_eur) the issuer rounds
74
- // to 6 dp and integers serialise as integers.
70
+ // Spec section 6: integer-valued numbers serialise without a decimal
71
+ // point. JSON.stringify does that natively, so nothing extra is needed
72
+ // here. Python's json.dumps does NOT (it yields "0.0" for float 0.0),
73
+ // which is why the spec puts the coercion duty on the issuer: an
74
+ // integer-valued float must become an int before it is signed. A receipt
75
+ // carrying a literal "0.0" was signed by a non-conforming issuer, and
76
+ // failing it is correct behaviour, not a gap in this verifier.
75
77
  return JSON.stringify(v);
76
78
  }
77
79
  // Strings, booleans
78
80
  return JSON.stringify(v);
79
81
  }
80
82
  /**
81
- * Verify an AqtaCore attestation receipt.
83
+ * Verify a Seal attestation receipt.
84
+ *
85
+ * Pinning is required by default. A self-signed receipt must not return
86
+ * `valid: true` unless `allowUntrustedEmbeddedKey` is set.
82
87
  *
83
88
  * @param receipt The full receipt object (including `signature`).
84
- * @param options Optional verification constraints.
85
- * @returns `{ valid: true }` if the signature is valid under the
86
- * declared (and optionally pinned) public key; otherwise
87
- * `{ valid: false, reason: string }`.
89
+ * @param options Verification constraints.
90
+ * @returns `{ valid: true, keySource }` if the signature is valid under
91
+ * the pinned (or explicitly allowed embedded) public key;
92
+ * otherwise `{ valid: false, reason: string }`.
88
93
  *
89
94
  * @example
90
95
  * const result = verifyReceipt(receipt, {
@@ -123,9 +128,16 @@ function verifyReceipt(receipt, options = {}) {
123
128
  if (typeof r.request_hash !== 'string' || !/^[0-9a-f]{64}$/.test(r.request_hash)) {
124
129
  return { valid: false, reason: 'request_hash must be 64 lowercase hex chars' };
125
130
  }
131
+ const pinned = options.trustedPublicKey;
132
+ const allowUntrusted = options.allowUntrustedEmbeddedKey === true;
133
+ if (pinned === undefined && !allowUntrusted) {
134
+ return {
135
+ valid: false,
136
+ reason: 'trustedPublicKey required (pass allowUntrustedEmbeddedKey for integrity-only)',
137
+ };
138
+ }
126
139
  // Public-key pinning
127
- if (options.trustedPublicKey !== undefined &&
128
- options.trustedPublicKey !== r.public_key) {
140
+ if (pinned !== undefined && pinned !== r.public_key) {
129
141
  return {
130
142
  valid: false,
131
143
  reason: 'public_key does not match trusted key',
@@ -152,14 +164,20 @@ function verifyReceipt(receipt, options = {}) {
152
164
  return { valid: false, reason: 'public key length != 32 bytes' };
153
165
  }
154
166
  const ok = tweetnacl_1.default.sign.detached.verify(canonical, sig, pub);
155
- return ok ? { valid: true } : { valid: false, reason: 'signature check failed' };
167
+ if (!ok) {
168
+ return { valid: false, reason: 'signature check failed' };
169
+ }
170
+ return {
171
+ valid: true,
172
+ keySource: pinned !== undefined ? 'pinned' : 'untrusted',
173
+ };
156
174
  }
157
175
  catch (e) {
158
176
  return { valid: false, reason: `signature decode error: ${String(e)}` };
159
177
  }
160
178
  }
161
179
  /**
162
- * Fetch the AqtaCore public key from the published URL and return it as a
180
+ * Fetch the Seal public key from the published URL and return it as a
163
181
  * base64url string ready to pass to `verifyReceipt` as `trustedPublicKey`.
164
182
  *
165
183
  * **PIN THE RESULT.** This helper performs a live HTTPS fetch. Calling it
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;AA6IH,sCAwFC;AAsBD,0DAQC;AAjQD,0DAA6B;AAC7B,oEAAsC;AAoDtC,MAAM,gBAAgB,GAAwB,IAAI,GAAG,CAAC;IACpD,SAAS;IACT,SAAS;IACT,YAAY;IACZ,QAAQ;CACT,CAAC,CAAC;AAEH,MAAM,eAAe,GAAwB,IAAI,GAAG,CAAC;IACnD,GAAG;IACH,gBAAgB;IAChB,UAAU;IACV,QAAQ;IACR,cAAc;IACd,OAAO;IACP,SAAS;IACT,gBAAgB;IAChB,oBAAoB;IACpB,WAAW;IACX,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAEH,gEAAgE;AAChE,SAAS,eAAe,CAAC,CAAS;IAChC,MAAM,MAAM,GAAG,CAAC,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACxD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACzD,OAAO,wBAAQ,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;;;GAQG;AACH,SAAS,YAAY,CAAC,OAAgC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC/D,CAAC;AAED,SAAS,cAAc,CAAC,CAAU;IAChC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACrB,OAAO,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACrD,CAAC;IACD,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,qEAAqE;QACrE,uEAAuE;QACvE,sEAAsE;QACtE,iEAAiE;QACjE,yEAAyE;QACzE,sEAAsE;QACtE,+DAA+D;QAC/D,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;IACD,oBAAoB;IACpB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,SAAgB,aAAa,CAC3B,OAAgB,EAChB,UAAyB,EAAE;IAE3B,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,KAAK,IAAI,EAAE,CAAC;QACpD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,0BAA0B,EAAE,CAAC;IAC9D,CAAC;IACD,MAAM,CAAC,GAAG,OAAkC,CAAC;IAE7C,oBAAoB;IACpB,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,KAAK,EAAE,EAAE,CAAC;QACtE,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,YAAY,KAAK,KAAK,EAAE,CAAC;QACnC,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAC/B,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC5B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,CAAC,EAAE,EAAE,CAAC;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QACd,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACjE,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;QACtE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,oBAAoB,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;IAC3E,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC;IACrE,CAAC;IACD,IAAI,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,EAAE,CAAC;QACjF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,6CAA6C,EAAE,CAAC;IACjF,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC;IACxC,MAAM,cAAc,GAAG,OAAO,CAAC,yBAAyB,KAAK,IAAI,CAAC;IAElE,IAAI,MAAM,KAAK,SAAS,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5C,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EACJ,+EAA+E;SAClF,CAAC;IACJ,CAAC;IAED,qBAAqB;IACrB,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,CAAC,CAAC,UAAU,EAAE,CAAC;QACpD,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,uCAAuC;SAChD,CAAC;IACJ,CAAC;IAED,kDAAkD;IAClD,MAAM,OAAO,GAA4B,EAAE,GAAG,CAAC,EAAE,CAAC;IAClD,OAAO,OAAO,CAAC,SAAS,CAAC;IAEzB,IAAI,SAAqB,CAAC;IAC1B,IAAI,CAAC;QACH,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC1E,CAAC;IAED,uBAAuB;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,SAAmB,CAAC,CAAC;QACnD,MAAM,GAAG,GAAG,eAAe,CAAC,CAAC,CAAC,UAAoB,CAAC,CAAC;QACpD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,8BAA8B,EAAE,CAAC;QAClE,CAAC;QACD,IAAI,GAAG,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACtB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,+BAA+B,EAAE,CAAC;QACnE,CAAC;QACD,MAAM,EAAE,GAAG,mBAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;QAC1D,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QAC5D,CAAC;QACD,OAAO;YACL,KAAK,EAAE,IAAI;YACX,SAAS,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW;SACzD,CAAC;IACJ,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,2BAA2B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IAC1E,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACI,KAAK,UAAU,uBAAuB,CAC3C,GAAG,GAAG,yCAAyC;IAE/C,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oCAAoC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACpE,CAAC;IACD,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC"}
package/package.json CHANGED
@@ -1,11 +1,22 @@
1
1
  {
2
2
  "name": "aqta-verify-receipt",
3
- "version": "1.0.2",
4
- "description": "Independent verifier for AqtaCore attestation receipts. Verifies the Ed25519 signature on an attestation receipt without trusting any third-party server. Reference implementation of ATTESTATION-v1.",
3
+ "version": "1.0.5",
4
+ "description": "Offline CLI and library for Seal ATTESTATION-v1 receipts. Ed25519 check of a signed model call; no account, no Aqta server required.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
+ "bin": {
8
+ "aqta-verify-receipt": "bin/aqta-verify-receipt.js"
9
+ },
7
10
  "files": [
8
- "dist/",
11
+ "bin/",
12
+ "dist/cli.js",
13
+ "dist/cli.js.map",
14
+ "dist/cli.d.ts",
15
+ "dist/cli.d.ts.map",
16
+ "dist/index.js",
17
+ "dist/index.js.map",
18
+ "dist/index.d.ts",
19
+ "dist/index.d.ts.map",
9
20
  "README.md",
10
21
  "LICENSE"
11
22
  ],
@@ -15,15 +26,15 @@
15
26
  "prepublishOnly": "npm run build"
16
27
  },
17
28
  "keywords": [
29
+ "seal",
18
30
  "aqta",
19
- "ai-governance",
20
- "attestation",
31
+ "attestation-v1",
21
32
  "ed25519",
22
- "zero-trust",
23
- "eu-ai-act",
24
- "dora",
25
- "compliance",
26
- "receipt-verification"
33
+ "offline-verification",
34
+ "ai-receipts",
35
+ "model-call",
36
+ "tamper-evident",
37
+ "cli"
27
38
  ],
28
39
  "author": "Aqta Technologies Ltd",
29
40
  "license": "Apache-2.0",
@@ -32,7 +43,7 @@
32
43
  "url": "https://github.com/Aqta-ai/attestation-spec.git",
33
44
  "directory": "packages/verify-receipt"
34
45
  },
35
- "homepage": "https://github.com/Aqta-ai/attestation-spec",
46
+ "homepage": "https://aqta.ai/verify",
36
47
  "bugs": {
37
48
  "url": "https://github.com/Aqta-ai/attestation-spec/issues"
38
49
  },
@@ -1,6 +0,0 @@
1
- /**
2
- * Interop tests: verify a receipt produced by the Python reference implementation
3
- * against this TypeScript verifier. Run: `npm run build && node --test dist/index.test.js`.
4
- */
5
- export {};
6
- //# sourceMappingURL=index.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -1,85 +0,0 @@
1
- "use strict";
2
- /**
3
- * Interop tests: verify a receipt produced by the Python reference implementation
4
- * against this TypeScript verifier. Run: `npm run build && node --test dist/index.test.js`.
5
- */
6
- var __importDefault = (this && this.__importDefault) || function (mod) {
7
- return (mod && mod.__esModule) ? mod : { "default": mod };
8
- };
9
- Object.defineProperty(exports, "__esModule", { value: true });
10
- const node_test_1 = require("node:test");
11
- const strict_1 = __importDefault(require("node:assert/strict"));
12
- const index_js_1 = require("./index.js");
13
- /**
14
- * Fixture receipt shape, used here to exercise the structural checks.
15
- * Full signature-level interop is covered by the cross-implementation
16
- * runner at `scripts/make-interop-fixture.mjs`, which generates a receipt
17
- * with the reference issuer and verifies it with this library.
18
- */
19
- const FIXTURE_RECEIPT = {
20
- v: 1,
21
- attestation_id: 'a3f2b1c4-9d87-4e6f-b012-34567890abcd',
22
- trace_id: 'trace-fixture-v1',
23
- org_id: 'org-test',
24
- request_hash: '8f3a7e2b9c4d5f6a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a',
25
- model: 'gpt-4o',
26
- outcome: 'ALLOWED',
27
- policy_applied: ['budget_guard', 'loop_guard'],
28
- cost_prevented_eur: 0.0,
29
- timestamp: '2026-04-23T10:15:30.123456+00:00',
30
- public_key: '', // populated by make-test-fixture.py
31
- signature: '', // populated by make-test-fixture.py
32
- };
33
- (0, node_test_1.test)('rejects empty object', () => {
34
- const res = (0, index_js_1.verifyReceipt)({});
35
- strict_1.default.equal(res.valid, false);
36
- });
37
- (0, node_test_1.test)('rejects missing required field', () => {
38
- const bad = { ...FIXTURE_RECEIPT };
39
- delete bad.outcome;
40
- const res = (0, index_js_1.verifyReceipt)(bad);
41
- strict_1.default.equal(res.valid, false);
42
- strict_1.default.match(res.reason ?? '', /missing required field/);
43
- });
44
- (0, node_test_1.test)('rejects unknown top-level field (strict mode)', () => {
45
- const bad = { ...FIXTURE_RECEIPT, extra: 'foo' };
46
- const res = (0, index_js_1.verifyReceipt)(bad);
47
- strict_1.default.equal(res.valid, false);
48
- strict_1.default.match(res.reason ?? '', /unknown top-level field/);
49
- });
50
- (0, node_test_1.test)('rejects unsupported version', () => {
51
- const bad = { ...FIXTURE_RECEIPT, v: 2 };
52
- const res = (0, index_js_1.verifyReceipt)(bad);
53
- strict_1.default.equal(res.valid, false);
54
- strict_1.default.match(res.reason ?? '', /unsupported version/);
55
- });
56
- (0, node_test_1.test)('rejects invalid outcome', () => {
57
- const bad = { ...FIXTURE_RECEIPT, outcome: 'YOLO' };
58
- const res = (0, index_js_1.verifyReceipt)(bad);
59
- strict_1.default.equal(res.valid, false);
60
- strict_1.default.match(res.reason ?? '', /invalid outcome/);
61
- });
62
- (0, node_test_1.test)('rejects malformed request_hash', () => {
63
- const bad = { ...FIXTURE_RECEIPT, request_hash: 'not-a-hash' };
64
- const res = (0, index_js_1.verifyReceipt)(bad);
65
- strict_1.default.equal(res.valid, false);
66
- strict_1.default.match(res.reason ?? '', /request_hash/);
67
- });
68
- (0, node_test_1.test)('rejects pinned-key mismatch', () => {
69
- const res = (0, index_js_1.verifyReceipt)(FIXTURE_RECEIPT, {
70
- trustedPublicKey: 'different_key_000000000000000000000000000000',
71
- });
72
- strict_1.default.equal(res.valid, false);
73
- strict_1.default.match(res.reason ?? '', /does not match trusted key/);
74
- });
75
- // Note: full signature-verification interop test requires the fixture to be
76
- // populated by `scripts/make-test-fixture.py` before running this suite.
77
- // When FIXTURE_RECEIPT.signature is empty, the signature check is skipped.
78
- (0, node_test_1.test)('signature decoder rejects empty signature', () => {
79
- const res = (0, index_js_1.verifyReceipt)(FIXTURE_RECEIPT);
80
- strict_1.default.equal(res.valid, false);
81
- // Either the empty signature fails decode or fails length check
82
- strict_1.default.ok(/signature/.test(res.reason ?? '') ||
83
- /signature length/.test(res.reason ?? ''));
84
- });
85
- //# sourceMappingURL=index.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.test.js","sourceRoot":"","sources":["../src/index.test.ts"],"names":[],"mappings":"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"}