contracts: Receipt v1 schema, canonicalization, verify rules, test vectors
This commit is contained in:
14
test_vectors/README.md
Normal file
14
test_vectors/README.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Receipt v1 Test Vectors
|
||||
|
||||
Each receipt JSON file is a full v1 envelope with `blake3` and `sha256` set to the
|
||||
expected canonical hashes.
|
||||
|
||||
`manifest.json` repeats the expected canonical digests for convenience.
|
||||
Signature fields in `receipt_v1_signed.json` are placeholders and are not
|
||||
expected to verify unless explicitly noted in `manifest.json`.
|
||||
|
||||
Canonical bytes are computed by:
|
||||
- removing hash and signature fields (`hash_alg`, `blake3`, `sha256`, `sig_alg`,
|
||||
`signer_pub`, `signature`, `signed_at`)
|
||||
- recursively sorting object keys
|
||||
- serializing as compact UTF-8 JSON (no trailing newline)
|
||||
16
test_vectors/manifest.json
Normal file
16
test_vectors/manifest.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"version": 1,
|
||||
"vectors": [
|
||||
{
|
||||
"file": "receipt_v1_basic.json",
|
||||
"canonical_blake3_hex": "be1bf3fd91c6b78220ebd0c6a6d330bca04d3aa0de318e515bc1dbd5c9f64506",
|
||||
"canonical_sha256_hex": "43691cfe210f42b4b2fc4eb9b39a4bf8d35d75c2e42805d3f42aa89ad2d04aa5"
|
||||
},
|
||||
{
|
||||
"file": "receipt_v1_signed.json",
|
||||
"canonical_blake3_hex": "7b25a1668e700c0096dcca33467b89d22cdf7ea635d59f3c692e97153459672a",
|
||||
"canonical_sha256_hex": "237c298f88821d4938f8909012dd8128d062245e480285d605ad146a868bec14",
|
||||
"signature_valid": false
|
||||
}
|
||||
]
|
||||
}
|
||||
51
test_vectors/receipt_v1_basic.json
Normal file
51
test_vectors/receipt_v1_basic.json
Normal file
@@ -0,0 +1,51 @@
|
||||
{
|
||||
"action": "servers.labels",
|
||||
"receipt_version": "1",
|
||||
"created_at": "2025-01-01T00:00:00.000Z",
|
||||
"source": "vmc",
|
||||
"reason": "test vector basic",
|
||||
"target": {
|
||||
"name": "alpha",
|
||||
"ip": "1.2.3.4",
|
||||
"id": 123
|
||||
},
|
||||
"request": {
|
||||
"path": "/servers/123",
|
||||
"method": "PUT",
|
||||
"body": {
|
||||
"labels": {
|
||||
"b": "2",
|
||||
"a": "1"
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"ok": true,
|
||||
"status": 200,
|
||||
"data": {
|
||||
"result": "ok"
|
||||
},
|
||||
"raw": "{\"result\":\"ok\"}"
|
||||
},
|
||||
"prev_blake3": null,
|
||||
"hash_alg": "blake3+sha256",
|
||||
"blake3": "be1bf3fd91c6b78220ebd0c6a6d330bca04d3aa0de318e515bc1dbd5c9f64506",
|
||||
"sha256": "43691cfe210f42b4b2fc4eb9b39a4bf8d35d75c2e42805d3f42aa89ad2d04aa5",
|
||||
"plan_file": null,
|
||||
"plan_sha256": null,
|
||||
"plan_blake3": null,
|
||||
"lock_file": null,
|
||||
"lock_started_at": null,
|
||||
"force": false,
|
||||
"cwd": "/tmp/vm",
|
||||
"user": "tester",
|
||||
"hostname": "vector-host",
|
||||
"argv": [
|
||||
"vmc",
|
||||
"servers",
|
||||
"labels",
|
||||
"alpha",
|
||||
"a=1",
|
||||
"b=2"
|
||||
]
|
||||
}
|
||||
61
test_vectors/receipt_v1_signed.json
Normal file
61
test_vectors/receipt_v1_signed.json
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"reason": "test vector signed",
|
||||
"receipt_version": "1",
|
||||
"created_at": "2025-01-02T03:04:05.000Z",
|
||||
"source": "mcp",
|
||||
"action": "plans.apply",
|
||||
"target": {
|
||||
"id": "srv-9",
|
||||
"ip": null,
|
||||
"name": "beta"
|
||||
},
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"path": "/apply",
|
||||
"body": {
|
||||
"plan": {
|
||||
"steps": [
|
||||
{
|
||||
"value": "prod",
|
||||
"path": "/labels/env",
|
||||
"op": "set"
|
||||
},
|
||||
{
|
||||
"path": "/labels/tmp",
|
||||
"op": "delete"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"data": {
|
||||
"applied": true
|
||||
},
|
||||
"status": 201,
|
||||
"ok": true,
|
||||
"raw": "{\"applied\":true}"
|
||||
},
|
||||
"prev_blake3": null,
|
||||
"hash_alg": "blake3+sha256",
|
||||
"blake3": "7b25a1668e700c0096dcca33467b89d22cdf7ea635d59f3c692e97153459672a",
|
||||
"sha256": "237c298f88821d4938f8909012dd8128d062245e480285d605ad146a868bec14",
|
||||
"plan_file": "plans/test.json",
|
||||
"plan_blake3": "1111111111111111111111111111111111111111111111111111111111111111",
|
||||
"plan_sha256": "2222222222222222222222222222222222222222222222222222222222222222",
|
||||
"lock_file": "/tmp/vm.lock",
|
||||
"lock_started_at": "2025-01-02T03:00:00.000Z",
|
||||
"force": true,
|
||||
"cwd": "/work",
|
||||
"user": "builder",
|
||||
"hostname": "vector-host",
|
||||
"argv": [
|
||||
"mcp",
|
||||
"apply",
|
||||
"--force"
|
||||
],
|
||||
"sig_alg": "ed25519",
|
||||
"signer_pub": "8ac2f516b7138e99a183e56196d3f332e44ff15d8fd388f1807db0db5dc2eaac",
|
||||
"signature": "041e36a549623bd8e342bf8363f466e7d49de6de673ab4747bd3f4b2396e075f8b3f311293f64fd1faf6e8c49b267808e3542095adad87f74bf1e2722d629605",
|
||||
"signed_at": "2025-01-02T03:04:06.000Z"
|
||||
}
|
||||
Reference in New Issue
Block a user