aqta-verify-receipt 1.0.7 → 1.0.9
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 +38 -11
- package/dist/cli.js +178 -67
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +111 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="https://aqta.ai/brand/seal-mark-512.png" alt="Seal" width="
|
|
2
|
+
<img src="https://aqta.ai/brand/seal-mark-512.png" alt="Seal" width="96" height="96" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# aqta-verify-receipt
|
|
@@ -18,20 +18,42 @@ Same algorithm on npm and PyPI. Reference implementation, not a platform SDK.
|
|
|
18
18
|
## 30-second check
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
|
-
|
|
22
|
-
npx aqta-verify-receipt@1.0.7 receipt.json \
|
|
21
|
+
npx aqta-verify-receipt@1.0.8 receipt.json \
|
|
23
22
|
--key gUoUhIvptKAoLTnry3VrDtOQEWggGQveLrHFVrfNqmE
|
|
24
23
|
```
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
Default output is one compact line (words carry meaning; colour is optional):
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
✓ valid ALLOWED 2d41…871e94c pinned issuer key
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Invalid:
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
✕ invalid signature mismatch 2d41…871e94c
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Optional flourish (never the proof):
|
|
27
38
|
|
|
28
39
|
```bash
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
npx aqta-verify-receipt@1.0.8 receipt.json --key <pinned> --pretty
|
|
41
|
+
# …
|
|
42
|
+
◈ seal intact · verified offline
|
|
31
43
|
```
|
|
32
44
|
|
|
33
|
-
|
|
34
|
-
|
|
45
|
+
Automation:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npx aqta-verify-receipt@1.0.8 receipt.json --key <pinned> --json
|
|
49
|
+
npx aqta-verify-receipt@1.0.8 receipt.json --key <pinned> -q; echo $?
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
| Exit | Meaning |
|
|
53
|
+
|------|---------|
|
|
54
|
+
| `0` | valid |
|
|
55
|
+
| `1` | invalid |
|
|
56
|
+
| `2` | usage / IO |
|
|
35
57
|
|
|
36
58
|
Production public key (also at
|
|
37
59
|
[`/v1/attestation/public-key`](https://api.aqta.ai/v1/attestation/public-key),
|
|
@@ -78,8 +100,8 @@ verify collapses trust back to "trust the issuer's server right now".
|
|
|
78
100
|
## CLI
|
|
79
101
|
|
|
80
102
|
```
|
|
81
|
-
aqta-verify-receipt <file|-> --key <base64url> [
|
|
82
|
-
aqta-verify-receipt <file|-> --integrity-only [
|
|
103
|
+
aqta-verify-receipt <file|-> --key <base64url> [options]
|
|
104
|
+
aqta-verify-receipt <file|-> --integrity-only [options]
|
|
83
105
|
```
|
|
84
106
|
|
|
85
107
|
| Flag | Meaning |
|
|
@@ -87,8 +109,12 @@ aqta-verify-receipt <file|-> --integrity-only [--no-strict] [-q]
|
|
|
87
109
|
| `--key` | Pin issuer identity (required for counsel-grade). |
|
|
88
110
|
| `--integrity-only` | Signature vs embedded key only; returns untrusted. Anyone can self-sign. |
|
|
89
111
|
| `--no-strict` | Allow unknown top-level fields |
|
|
112
|
+
| `--json` | One JSON object on stdout |
|
|
113
|
+
| `--pretty` | Optional human flourish after the compact line (not the proof) |
|
|
90
114
|
| `-q` | Silent; exit code only |
|
|
91
115
|
|
|
116
|
+
`NO_COLOR=1` disables colour. Meaning never depends on colour alone.
|
|
117
|
+
|
|
92
118
|
## API
|
|
93
119
|
|
|
94
120
|
### `verifyReceipt(receipt, options?) → { valid, reason?, keySource? }`
|
|
@@ -111,7 +137,8 @@ Conformance suite (6 valid + 8 invalid):
|
|
|
111
137
|
## What this is not
|
|
112
138
|
|
|
113
139
|
Not a governance dashboard. Not a cost router. Not a chain explorer.
|
|
114
|
-
A small verifier for one signed model-call receipt.
|
|
140
|
+
A small verifier for one signed model-call receipt. The novel part is the
|
|
141
|
+
receipt format and offline verification model, not ASCII theatre.
|
|
115
142
|
|
|
116
143
|
## Security
|
|
117
144
|
|
package/dist/cli.js
CHANGED
|
@@ -7,78 +7,79 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
* Offline check of an ATTESTATION-v1 receipt. No account. No network by
|
|
8
8
|
* default. Exit 0 if the signature verifies, 1 if not, 2 on usage/IO errors.
|
|
9
9
|
*
|
|
10
|
+
* Default output is one compact, scriptable line on stdout. Colour is
|
|
11
|
+
* presentation only (NO_COLOR / non-TTY disables it). --pretty adds a short
|
|
12
|
+
* human flourish; it is never the verification contract.
|
|
13
|
+
*
|
|
10
14
|
* npx aqta-verify-receipt receipt.json --key <base64url-ed25519-key>
|
|
11
15
|
* curl -sS https://api.aqta.ai/r/REC_ID | npx aqta-verify-receipt - --key <key>
|
|
12
|
-
* npx aqta-verify-receipt receipt.json --
|
|
16
|
+
* npx aqta-verify-receipt receipt.json --key <key> --json
|
|
17
|
+
* npx aqta-verify-receipt receipt.json --key <key> --pretty
|
|
13
18
|
*/
|
|
14
19
|
const fs_1 = require("fs");
|
|
15
20
|
const index_1 = require("./index");
|
|
16
21
|
const PUB_KEY_HINT = 'https://api.aqta.ai/v1/attestation/public-key';
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
const colour = process.env.NO_COLOR === undefined;
|
|
34
|
-
const paint = (code, s) => colour ? ESC + '[' + code + 'm' + s + ESC + '[0m' : s;
|
|
35
|
-
const dim = (s) => paint('2', s);
|
|
36
|
-
const r = receipt;
|
|
37
|
-
const str = (v) => (typeof v === 'string' ? v : '?');
|
|
38
|
-
const mid = (v, head = 8, tail = 6) => {
|
|
39
|
-
const s = str(v);
|
|
40
|
-
return s.length > head + tail + 1 ? s.slice(0, head) + ELL + s.slice(-tail) : s;
|
|
41
|
-
};
|
|
42
|
-
const policies = Array.isArray(r.policy_applied) && r.policy_applied.length
|
|
43
|
-
? r.policy_applied.map(str).join(' ' + DOT + ' ')
|
|
44
|
-
: '';
|
|
45
|
-
const rows = [
|
|
46
|
-
['outcome', str(r.outcome)],
|
|
47
|
-
['model', str(r.model)],
|
|
48
|
-
];
|
|
49
|
-
if (policies)
|
|
50
|
-
rows.push(['rules', policies]);
|
|
51
|
-
rows.push(['key', trust]);
|
|
52
|
-
rows.push(['request', mid(r.request_hash)]);
|
|
53
|
-
rows.push(['id', mid(r.attestation_id, 8, 4)]);
|
|
54
|
-
const out = ['', ' ' + dim(MARK + ' Seal ' + DOT + ' ATTESTATION-v1'), ''];
|
|
55
|
-
for (const [k, v] of rows)
|
|
56
|
-
out.push(' ' + dim(k.padEnd(8)) + v);
|
|
57
|
-
out.push('');
|
|
58
|
-
out.push(valid
|
|
59
|
-
? ' ' + paint('32', OK + ' sealed') + ' ' + dim('signature valid, checked offline')
|
|
60
|
-
: ' ' + paint('31', NO + ' broken') + ' ' + dim(reason ?? 'signature does not match the key'));
|
|
61
|
-
out.push('');
|
|
62
|
-
process.stderr.write(out.join('\n') + '\n');
|
|
22
|
+
function useUtf8() {
|
|
23
|
+
return /UTF-?8/i.test(process.env.LC_ALL || process.env.LC_CTYPE || process.env.LANG || '');
|
|
24
|
+
}
|
|
25
|
+
function useColour() {
|
|
26
|
+
return (process.stdout.isTTY === true &&
|
|
27
|
+
process.env.NO_COLOR === undefined &&
|
|
28
|
+
process.env.TERM !== 'dumb');
|
|
29
|
+
}
|
|
30
|
+
function paint(code, s) {
|
|
31
|
+
if (!useColour())
|
|
32
|
+
return s;
|
|
33
|
+
return `\x1b[${code}m${s}\x1b[0m`;
|
|
34
|
+
}
|
|
35
|
+
function mid(s, head = 4, tail = 6) {
|
|
36
|
+
const ell = useUtf8() ? '…' : '...';
|
|
37
|
+
return s.length > head + tail + 1 ? `${s.slice(0, head)}${ell}${s.slice(-tail)}` : s;
|
|
63
38
|
}
|
|
64
39
|
function usage() {
|
|
65
|
-
|
|
40
|
+
process.stderr.write(`aqta-verify-receipt - offline check for ATTESTATION-v1 (Seal)
|
|
66
41
|
|
|
67
42
|
Usage:
|
|
68
|
-
aqta-verify-receipt <receipt.json | -> --key <base64url> [
|
|
69
|
-
aqta-verify-receipt <receipt.json | -> --integrity-only [
|
|
43
|
+
aqta-verify-receipt <receipt.json | -> --key <base64url> [options]
|
|
44
|
+
aqta-verify-receipt <receipt.json | -> --integrity-only [options]
|
|
70
45
|
|
|
71
46
|
Options:
|
|
72
47
|
--key <key> pin the issuer public key (required for counsel-grade)
|
|
73
48
|
--integrity-only check signature vs embedded key only (anyone can self-sign)
|
|
49
|
+
--envelope <name> opt in to a non-ATTESTATION-v1 envelope (e.g. anchor-v1)
|
|
74
50
|
--no-strict allow unknown top-level fields
|
|
51
|
+
--json machine JSON on stdout (one object)
|
|
52
|
+
--pretty optional human flourish after the compact line
|
|
75
53
|
-q, --quiet exit code only
|
|
76
54
|
|
|
55
|
+
Contract:
|
|
56
|
+
exit 0 valid · exit 1 invalid · exit 2 usage/IO
|
|
57
|
+
default stdout is one compact line (words carry meaning; colour is optional)
|
|
58
|
+
--pretty never changes the exit code or the verify result
|
|
59
|
+
|
|
77
60
|
Pin the production key once from ${PUB_KEY_HINT}
|
|
78
61
|
(field public_key). Do not re-fetch on every verify.
|
|
79
62
|
`);
|
|
80
63
|
process.exit(2);
|
|
81
64
|
}
|
|
65
|
+
function compactLine(valid, outcome, id, trustOrReason) {
|
|
66
|
+
const utf8 = useUtf8();
|
|
67
|
+
const ok = utf8 ? '✓' : '+';
|
|
68
|
+
const no = utf8 ? '✕' : 'x';
|
|
69
|
+
if (valid) {
|
|
70
|
+
return `${paint('32', `${ok} valid`)} ${outcome} ${mid(id)} ${trustOrReason}`;
|
|
71
|
+
}
|
|
72
|
+
return `${paint('31', `${no} invalid`)} ${trustOrReason} ${mid(id)}`;
|
|
73
|
+
}
|
|
74
|
+
function prettyExtra(valid) {
|
|
75
|
+
const utf8 = useUtf8();
|
|
76
|
+
const mark = utf8 ? '◈' : '*';
|
|
77
|
+
const dot = utf8 ? '·' : '-';
|
|
78
|
+
if (valid) {
|
|
79
|
+
return `${mark} seal intact ${dot} verified offline`;
|
|
80
|
+
}
|
|
81
|
+
return `${mark} seal broken ${dot} do not trust this receipt`;
|
|
82
|
+
}
|
|
82
83
|
function main() {
|
|
83
84
|
const args = process.argv.slice(2);
|
|
84
85
|
if (args.length === 0 || args.includes('--help') || args.includes('-h'))
|
|
@@ -86,8 +87,11 @@ function main() {
|
|
|
86
87
|
let file = '';
|
|
87
88
|
let trustedKey;
|
|
88
89
|
let integrityOnly = false;
|
|
90
|
+
let envelope;
|
|
89
91
|
let strict = true;
|
|
90
92
|
let quiet = false;
|
|
93
|
+
let asJson = false;
|
|
94
|
+
let pretty = false;
|
|
91
95
|
for (let i = 0; i < args.length; i++) {
|
|
92
96
|
const a = args[i];
|
|
93
97
|
if (a === '--key') {
|
|
@@ -98,12 +102,23 @@ function main() {
|
|
|
98
102
|
else if (a === '--integrity-only') {
|
|
99
103
|
integrityOnly = true;
|
|
100
104
|
}
|
|
105
|
+
else if (a === '--envelope') {
|
|
106
|
+
envelope = args[++i];
|
|
107
|
+
if (!envelope)
|
|
108
|
+
usage();
|
|
109
|
+
}
|
|
101
110
|
else if (a === '--no-strict') {
|
|
102
111
|
strict = false;
|
|
103
112
|
}
|
|
104
113
|
else if (a === '--quiet' || a === '-q') {
|
|
105
114
|
quiet = true;
|
|
106
115
|
}
|
|
116
|
+
else if (a === '--json') {
|
|
117
|
+
asJson = true;
|
|
118
|
+
}
|
|
119
|
+
else if (a === '--pretty') {
|
|
120
|
+
pretty = true;
|
|
121
|
+
}
|
|
107
122
|
else if (!file) {
|
|
108
123
|
file = a;
|
|
109
124
|
}
|
|
@@ -114,11 +129,15 @@ function main() {
|
|
|
114
129
|
if (!file)
|
|
115
130
|
usage();
|
|
116
131
|
if (!trustedKey && !integrityOnly) {
|
|
117
|
-
|
|
132
|
+
process.stderr.write('aqta-verify-receipt: pass --key <pinned> (or --integrity-only for embedded-key checks)\n');
|
|
118
133
|
process.exit(2);
|
|
119
134
|
}
|
|
120
135
|
if (trustedKey && integrityOnly) {
|
|
121
|
-
|
|
136
|
+
process.stderr.write('aqta-verify-receipt: use --key or --integrity-only, not both\n');
|
|
137
|
+
process.exit(2);
|
|
138
|
+
}
|
|
139
|
+
if (quiet && (asJson || pretty)) {
|
|
140
|
+
process.stderr.write('aqta-verify-receipt: -q cannot be combined with --json or --pretty\n');
|
|
122
141
|
process.exit(2);
|
|
123
142
|
}
|
|
124
143
|
let raw;
|
|
@@ -126,7 +145,7 @@ function main() {
|
|
|
126
145
|
raw = file === '-' ? (0, fs_1.readFileSync)(0, 'utf8') : (0, fs_1.readFileSync)(file, 'utf8');
|
|
127
146
|
}
|
|
128
147
|
catch {
|
|
129
|
-
|
|
148
|
+
process.stderr.write(`aqta-verify-receipt: cannot read ${file === '-' ? 'stdin' : file}\n`);
|
|
130
149
|
process.exit(2);
|
|
131
150
|
}
|
|
132
151
|
let receipt;
|
|
@@ -134,33 +153,125 @@ function main() {
|
|
|
134
153
|
receipt = JSON.parse(raw);
|
|
135
154
|
}
|
|
136
155
|
catch {
|
|
137
|
-
|
|
156
|
+
process.stderr.write('aqta-verify-receipt: input is not valid JSON\n');
|
|
157
|
+
process.exit(2);
|
|
158
|
+
}
|
|
159
|
+
// Bare `null` parses fine and then crashed the display code below with an
|
|
160
|
+
// uncaught TypeError and a Node stack trace, including on the documented
|
|
161
|
+
// `curl ... | aqta-verify-receipt -` path. Matches the Python message and
|
|
162
|
+
// exit code.
|
|
163
|
+
if (typeof receipt !== 'object' || receipt === null || Array.isArray(receipt)) {
|
|
164
|
+
process.stderr.write('aqta-verify-receipt: receipt must be a JSON object\n');
|
|
165
|
+
process.exit(2);
|
|
166
|
+
}
|
|
167
|
+
// ATTESTATION-v1 canonicalises a parsed object, so a receipt carrying the same
|
|
168
|
+
// member name twice has no single canonical payload: a parser keeping the first
|
|
169
|
+
// value and one keeping the last compute different signed bytes from identical
|
|
170
|
+
// input. RFC 8259 leaves that choice to the implementation, so the format
|
|
171
|
+
// rejects the receipt. JSON.parse silently keeps the last value, so the check
|
|
172
|
+
// has to run over the raw text.
|
|
173
|
+
const duplicate = findDuplicateMemberName(raw);
|
|
174
|
+
if (duplicate !== null) {
|
|
175
|
+
process.stderr.write(`aqta-verify-receipt: duplicate member name: ${duplicate}\n`);
|
|
138
176
|
process.exit(2);
|
|
139
177
|
}
|
|
140
178
|
const result = (0, index_1.verifyReceipt)(receipt, {
|
|
141
179
|
trustedPublicKey: trustedKey,
|
|
142
180
|
allowUntrustedEmbeddedKey: integrityOnly,
|
|
181
|
+
envelope,
|
|
143
182
|
strictFields: strict,
|
|
144
183
|
});
|
|
184
|
+
const id = typeof receipt.attestation_id === 'string' ? receipt.attestation_id : '?';
|
|
185
|
+
const outcome = typeof receipt.outcome === 'string' ? receipt.outcome : '?';
|
|
186
|
+
const trust = result.keySource === 'pinned'
|
|
187
|
+
? 'pinned issuer key'
|
|
188
|
+
: 'untrusted embedded key (integrity only)';
|
|
145
189
|
if (!quiet) {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
190
|
+
if (asJson) {
|
|
191
|
+
process.stdout.write(JSON.stringify({
|
|
192
|
+
valid: result.valid,
|
|
193
|
+
outcome,
|
|
194
|
+
attestation_id: id,
|
|
195
|
+
key_source: result.keySource ?? null,
|
|
196
|
+
envelope: result.envelope ?? null,
|
|
197
|
+
reason: result.valid ? null : result.reason ?? 'verification failed',
|
|
198
|
+
}) + '\n');
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
let detail = result.valid ? trust : result.reason ?? 'verification failed';
|
|
202
|
+
// Name the envelope when it is not the default, so a valid line never
|
|
203
|
+
// leaves the reader assuming ATTESTATION-v1 rules were applied.
|
|
204
|
+
if (result.valid && result.envelope && result.envelope !== 'ATTESTATION-v1') {
|
|
205
|
+
detail = `${detail}, envelope ${result.envelope}`;
|
|
157
206
|
}
|
|
158
|
-
|
|
159
|
-
|
|
207
|
+
process.stdout.write(compactLine(result.valid, outcome, id, detail) + '\n');
|
|
208
|
+
if (pretty) {
|
|
209
|
+
process.stdout.write(prettyExtra(result.valid) + '\n');
|
|
160
210
|
}
|
|
161
211
|
}
|
|
162
212
|
}
|
|
163
213
|
process.exit(result.valid ? 0 : 1);
|
|
164
214
|
}
|
|
165
215
|
main();
|
|
216
|
+
/**
|
|
217
|
+
* Returns the first member name that appears twice within the same object, or
|
|
218
|
+
* null. Walks the raw text because JSON.parse has already collapsed duplicates
|
|
219
|
+
* by the time a reviver runs.
|
|
220
|
+
*/
|
|
221
|
+
function findDuplicateMemberName(raw) {
|
|
222
|
+
const stack = [];
|
|
223
|
+
let i = 0;
|
|
224
|
+
const readString = () => {
|
|
225
|
+
let out = '';
|
|
226
|
+
i += 1; // opening quote
|
|
227
|
+
while (i < raw.length) {
|
|
228
|
+
const ch = raw[i];
|
|
229
|
+
if (ch === '\\') {
|
|
230
|
+
out += raw.slice(i, i + 2);
|
|
231
|
+
i += 2;
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
if (ch === '"') {
|
|
235
|
+
i += 1;
|
|
236
|
+
// Decode escapes before comparing. Comparing raw source spelling made
|
|
237
|
+
// the check escape-blind, so "outcome" was not seen as a duplicate
|
|
238
|
+
// of "outcome" and the ambiguous receipt verified here while Python
|
|
239
|
+
// rejected it. `out` is a valid JSON string body by construction.
|
|
240
|
+
try {
|
|
241
|
+
return JSON.parse('"' + out + '"');
|
|
242
|
+
}
|
|
243
|
+
catch {
|
|
244
|
+
return out;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
out += ch;
|
|
248
|
+
i += 1;
|
|
249
|
+
}
|
|
250
|
+
return out;
|
|
251
|
+
};
|
|
252
|
+
while (i < raw.length) {
|
|
253
|
+
const ch = raw[i];
|
|
254
|
+
if (ch === '"') {
|
|
255
|
+
const value = readString();
|
|
256
|
+
// A string is a member name only if the next non-space character is a colon
|
|
257
|
+
// and we are directly inside an object.
|
|
258
|
+
let j = i;
|
|
259
|
+
while (j < raw.length && /\s/.test(raw[j]))
|
|
260
|
+
j += 1;
|
|
261
|
+
if (raw[j] === ':' && stack.length > 0) {
|
|
262
|
+
const names = stack[stack.length - 1];
|
|
263
|
+
if (names.has(value))
|
|
264
|
+
return value;
|
|
265
|
+
names.add(value);
|
|
266
|
+
}
|
|
267
|
+
continue;
|
|
268
|
+
}
|
|
269
|
+
if (ch === '{')
|
|
270
|
+
stack.push(new Set());
|
|
271
|
+
else if (ch === '}')
|
|
272
|
+
stack.pop();
|
|
273
|
+
i += 1;
|
|
274
|
+
}
|
|
275
|
+
return null;
|
|
276
|
+
}
|
|
166
277
|
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;;AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -43,6 +43,14 @@ export interface VerifyOptions {
|
|
|
43
43
|
* top-level fields."
|
|
44
44
|
*/
|
|
45
45
|
strictFields?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Name of a non-ATTESTATION-v1 envelope the caller is deliberately
|
|
48
|
+
* verifying. Foreign envelopes carry their own field sets, so none of
|
|
49
|
+
* ATTESTATION-v1's structural or semantic rules apply; naming one here is
|
|
50
|
+
* how a caller says it understands that. Without it, a foreign envelope is
|
|
51
|
+
* rejected rather than silently verified under weaker rules.
|
|
52
|
+
*/
|
|
53
|
+
envelope?: EnvelopeFormat;
|
|
46
54
|
}
|
|
47
55
|
export type KeySource = 'pinned' | 'untrusted';
|
|
48
56
|
export interface VerifyResult {
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IAEpC;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;
|
|
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;IAEvB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B;AAED,MAAM,MAAM,SAAS,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE/C,MAAM,WAAW,YAAY;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oCAAoC;IACpC,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAmGD;;;;;;;;;;;;;;;;;GAiBG;AACH;;;;;;;;GAQG;AACH,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,WAAW,CAAC;AAO5D,mFAAmF;AACnF,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAUtE;AAmFD,wBAAgB,aAAa,CAC3B,OAAO,EAAE,OAAO,EAChB,OAAO,GAAE,aAAkB,GAC1B,YAAY,CAuJd;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,uBAAuB,CAC3C,GAAG,SAA4C,GAC9C,OAAO,CAAC,MAAM,CAAC,CAMjB"}
|
package/dist/index.js
CHANGED
|
@@ -53,13 +53,18 @@ function base64urlDecode(s) {
|
|
|
53
53
|
* array values). It is NOT a general-purpose canonical-JSON library.
|
|
54
54
|
*/
|
|
55
55
|
function canonicalise(payload) {
|
|
56
|
-
|
|
57
|
-
const parts = [];
|
|
58
|
-
for (const k of keys) {
|
|
59
|
-
parts.push(`${JSON.stringify(k)}:${canonicalValue(payload[k])}`);
|
|
60
|
-
}
|
|
61
|
-
return new TextEncoder().encode('{' + parts.join(',') + '}');
|
|
56
|
+
return new TextEncoder().encode(canonicalValue(payload));
|
|
62
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* RFC 3339 with an explicit offset, range-checked without Date.
|
|
60
|
+
*
|
|
61
|
+
* Must stay character-for-character identical to _RFC3339_OFFSET in the Python
|
|
62
|
+
* verifier; the two implementations agreeing on what a timestamp is is the
|
|
63
|
+
* whole point of having two.
|
|
64
|
+
*/
|
|
65
|
+
const RFC3339_OFFSET = /^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])[Tt ]([01]\d|2[0-3]):[0-5]\d:([0-5]\d|60)(\.\d+)?([Zz]|[+-]([01]\d|2[0-3]):[0-5]\d)$/;
|
|
66
|
+
/** Matches an unpaired surrogate, which has no UTF-8 encoding. */
|
|
67
|
+
const LONE_SURROGATE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;
|
|
63
68
|
function canonicalValue(v) {
|
|
64
69
|
if (v === null || v === undefined) {
|
|
65
70
|
return 'null';
|
|
@@ -68,17 +73,38 @@ function canonicalValue(v) {
|
|
|
68
73
|
return '[' + v.map(canonicalValue).join(',') + ']';
|
|
69
74
|
}
|
|
70
75
|
if (typeof v === 'number') {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
//
|
|
77
|
-
|
|
76
|
+
if (!Number.isFinite(v))
|
|
77
|
+
throw new Error('non-finite number');
|
|
78
|
+
// JSON.stringify implements ECMA-262 Number::toString, which is exactly
|
|
79
|
+
// the number grammar RFC 8785 (JCS) 3.2.2.3 specifies. Python's default
|
|
80
|
+
// float repr does not agree with it below 1e-4, so the Python verifier
|
|
81
|
+
// implements this algorithm rather than the reverse.
|
|
82
|
+
return JSON.stringify(v);
|
|
83
|
+
}
|
|
84
|
+
if (typeof v === 'string') {
|
|
85
|
+
// JSON.stringify escapes a lone surrogate to \uXXXX and would happily sign
|
|
86
|
+
// it, while a UTF-8 encoder cannot represent it at all. Rejecting in both
|
|
87
|
+
// implementations is the only way they agree on such a receipt.
|
|
88
|
+
if (LONE_SURROGATE.test(v))
|
|
89
|
+
throw new Error('string contains an unpaired surrogate');
|
|
78
90
|
return JSON.stringify(v);
|
|
79
91
|
}
|
|
80
|
-
|
|
81
|
-
|
|
92
|
+
if (typeof v === 'boolean') {
|
|
93
|
+
return JSON.stringify(v);
|
|
94
|
+
}
|
|
95
|
+
if (typeof v === 'object') {
|
|
96
|
+
// Nested objects sort too. No conformant receipt nests, but Python sorted
|
|
97
|
+
// recursively and this did not, so the two would have diverged the moment
|
|
98
|
+
// a field ever did.
|
|
99
|
+
const o = v;
|
|
100
|
+
return ('{' +
|
|
101
|
+
Object.keys(o)
|
|
102
|
+
.sort()
|
|
103
|
+
.map((k) => `${JSON.stringify(k)}:${canonicalValue(o[k])}`)
|
|
104
|
+
.join(',') +
|
|
105
|
+
'}');
|
|
106
|
+
}
|
|
107
|
+
throw new Error(`not canonicalisable: ${typeof v}`);
|
|
82
108
|
}
|
|
83
109
|
const ENVELOPE_FIELDS = {
|
|
84
110
|
'ATTESTATION-v1': { signature: 'signature', publicKey: 'public_key' },
|
|
@@ -97,6 +123,24 @@ function detectEnvelope(receipt) {
|
|
|
97
123
|
}
|
|
98
124
|
return null;
|
|
99
125
|
}
|
|
126
|
+
/** The Ed25519 group order L, RFC 8032 section 5.1. */
|
|
127
|
+
const ED25519_L = 7237005577332262213973186563042994240857116359379907606001950938285454250989n;
|
|
128
|
+
/**
|
|
129
|
+
* RFC 8032 5.1.7 requires the signature scalar S to decode in [0, L).
|
|
130
|
+
*
|
|
131
|
+
* tweetnacl omits this check, so 16 byte-distinct signatures verified for any
|
|
132
|
+
* one receipt: S, S+L, ... S+15L. No forgery, since producing any of them
|
|
133
|
+
* needs a genuine signature over unchanged content, but the two published
|
|
134
|
+
* verifiers returned different verdicts on identical bytes, and a transparency
|
|
135
|
+
* log that keys a leaf on receipt bytes would see 16 distinct leaves for one
|
|
136
|
+
* decision.
|
|
137
|
+
*/
|
|
138
|
+
function canonicalScalar(sig) {
|
|
139
|
+
let s = 0n;
|
|
140
|
+
for (let i = 63; i >= 32; i--)
|
|
141
|
+
s = (s << 8n) | BigInt(sig[i]);
|
|
142
|
+
return s < ED25519_L;
|
|
143
|
+
}
|
|
100
144
|
/**
|
|
101
145
|
* Signature check shared by every envelope.
|
|
102
146
|
*
|
|
@@ -135,6 +179,9 @@ function verifySignedEnvelope(r, envelope, options) {
|
|
|
135
179
|
return { valid: false, reason: 'signature length != 64 bytes' };
|
|
136
180
|
if (pub.length !== 32)
|
|
137
181
|
return { valid: false, reason: 'public key length != 32 bytes' };
|
|
182
|
+
if (!canonicalScalar(sig)) {
|
|
183
|
+
return { valid: false, reason: 'non-canonical signature scalar' };
|
|
184
|
+
}
|
|
138
185
|
if (!tweetnacl_1.default.sign.detached.verify(canonical, sig, pub)) {
|
|
139
186
|
return { valid: false, reason: 'signature check failed' };
|
|
140
187
|
}
|
|
@@ -162,7 +209,20 @@ function verifyReceipt(receipt, options = {}) {
|
|
|
162
209
|
}
|
|
163
210
|
// Other issuers' envelopes carry their own field sets, so only the signature
|
|
164
211
|
// is checked. The structural rules below are ATTESTATION-v1's alone.
|
|
212
|
+
//
|
|
213
|
+
// Which is why it has to be opted into. Detecting a foreign envelope purely
|
|
214
|
+
// by field name meant any object naming its fields signature_b64 and
|
|
215
|
+
// public_key_b64 skipped every structural and semantic rule: a payload with
|
|
216
|
+
// v:99, outcome:"MAYBE" and request_hash:"nope" verified, and so did an
|
|
217
|
+
// object that was not a receipt at all. Exit 0 then answered "were these
|
|
218
|
+
// bytes signed by that key" rather than "is this a conformant receipt".
|
|
165
219
|
if (envelope !== 'ATTESTATION-v1') {
|
|
220
|
+
if (options.envelope !== envelope) {
|
|
221
|
+
return {
|
|
222
|
+
valid: false,
|
|
223
|
+
reason: `envelope ${envelope} requires explicit opt-in (pass envelope: '${envelope}'); ATTESTATION-v1 rules do not apply to it`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
166
226
|
return verifySignedEnvelope(r, envelope, options);
|
|
167
227
|
}
|
|
168
228
|
// Structural checks
|
|
@@ -191,6 +251,39 @@ function verifyReceipt(receipt, options = {}) {
|
|
|
191
251
|
if (typeof r.request_hash !== 'string' || !/^[0-9a-f]{64}$/.test(r.request_hash)) {
|
|
192
252
|
return { valid: false, reason: 'request_hash must be 64 lowercase hex chars' };
|
|
193
253
|
}
|
|
254
|
+
// The remaining §7 semantic checks. The Python verifier has always applied
|
|
255
|
+
// these; this one did not, so the two reference implementations returned
|
|
256
|
+
// different answers for the same receipt. A format whose verifiers disagree
|
|
257
|
+
// cannot settle a dispute, so they are enforced identically in both.
|
|
258
|
+
if (!r.policy_applied.every((p) => typeof p === 'string')) {
|
|
259
|
+
return { valid: false, reason: 'policy_applied must contain only strings' };
|
|
260
|
+
}
|
|
261
|
+
const sorted = [...r.policy_applied].sort();
|
|
262
|
+
if (r.policy_applied.some((p, i) => p !== sorted[i])) {
|
|
263
|
+
return { valid: false, reason: 'policy_applied must be in lexicographic order' };
|
|
264
|
+
}
|
|
265
|
+
if (typeof r.cost_prevented_eur !== 'number' || !Number.isFinite(r.cost_prevented_eur)) {
|
|
266
|
+
return { valid: false, reason: 'cost_prevented_eur must be a number' };
|
|
267
|
+
}
|
|
268
|
+
if (r.cost_prevented_eur < 0) {
|
|
269
|
+
return { valid: false, reason: 'cost_prevented_eur must be non-negative' };
|
|
270
|
+
}
|
|
271
|
+
// Well-formedness only. Freshness stays informative per CONFORMANCE.md, so
|
|
272
|
+
// an old receipt still verifies offline; a timestamp that is not a datetime
|
|
273
|
+
// with an explicit offset is a malformed field, not a stale one.
|
|
274
|
+
//
|
|
275
|
+
// The range checks live in the pattern rather than in Date.parse. Deferring
|
|
276
|
+
// to V8 made this verifier reject "2016-12-31T23:59:60Z", a real leap second
|
|
277
|
+
// and legal RFC 3339, while still accepting February 30th because V8 rolls it
|
|
278
|
+
// forward. Python had no such clause, so the two disagreed on both. This
|
|
279
|
+
// pattern is character-for-character the one in the Python verifier.
|
|
280
|
+
if (typeof r.timestamp !== 'string' ||
|
|
281
|
+
!RFC3339_OFFSET.test(r.timestamp)) {
|
|
282
|
+
return {
|
|
283
|
+
valid: false,
|
|
284
|
+
reason: 'timestamp must be an RFC 3339 datetime with an explicit offset',
|
|
285
|
+
};
|
|
286
|
+
}
|
|
194
287
|
const pinned = options.trustedPublicKey;
|
|
195
288
|
const allowUntrusted = options.allowUntrustedEmbeddedKey === true;
|
|
196
289
|
if (pinned === undefined && !allowUntrusted) {
|
|
@@ -226,6 +319,9 @@ function verifyReceipt(receipt, options = {}) {
|
|
|
226
319
|
if (pub.length !== 32) {
|
|
227
320
|
return { valid: false, reason: 'public key length != 32 bytes' };
|
|
228
321
|
}
|
|
322
|
+
if (!canonicalScalar(sig)) {
|
|
323
|
+
return { valid: false, reason: 'non-canonical signature scalar' };
|
|
324
|
+
}
|
|
229
325
|
const ok = tweetnacl_1.default.sign.detached.verify(canonical, sig, pub);
|
|
230
326
|
if (!ok) {
|
|
231
327
|
return { valid: false, reason: 'signature check failed' };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aqta-verify-receipt",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.9",
|
|
4
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",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
],
|
|
23
23
|
"scripts": {
|
|
24
24
|
"build": "tsc",
|
|
25
|
-
"test": "node --test dist/index.test.js",
|
|
25
|
+
"test": "node --test dist/index.test.js dist/envelope.test.js",
|
|
26
26
|
"prepublishOnly": "npm run build"
|
|
27
27
|
},
|
|
28
28
|
"keywords": [
|