@zanii/certify 0.8.0 → 0.8.1
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 +154 -145
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,145 +1,154 @@
|
|
|
1
|
-
# @zanii/certify
|
|
2
|
-
|
|
3
|
-
TypeScript SDK and `certify` CLI for Zanii Certify fingerprints, signed certificates,
|
|
4
|
-
status, evidence sharing, runtime assurance and scheme governance. The package uses
|
|
5
|
-
ES modules and requires Node.js 24 or newer. Every public function is exported from the
|
|
6
|
-
package root; the signed formats are defined in the Zanii Certify specification (`spec/`).
|
|
7
|
-
|
|
8
|
-
## Install
|
|
9
|
-
|
|
10
|
-
```sh
|
|
11
|
-
npm install @zanii/certify
|
|
12
|
-
npx certify verify cert.json --online https://lab.zanii.agency
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
Paths in backticks below (`spec/...`, `conformance/...`) are files of the Zanii Certify source repository, which is private; the specification documents are available from Zanii on request (info@zanii.agency).
|
|
16
|
-
|
|
17
|
-
## Use this checkout
|
|
18
|
-
|
|
19
|
-
From the repository root, with the pnpm version declared in the root `package.json`:
|
|
20
|
-
|
|
21
|
-
```sh
|
|
22
|
-
pnpm install --frozen-lockfile
|
|
23
|
-
node packages/certify/src/cli.ts --help-v2
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
The workspace package resolves directly to TypeScript source. Save the following as
|
|
27
|
-
`example.mjs` at the repository root and run `node example.mjs`. It needs no server,
|
|
28
|
-
network access or signing key:
|
|
29
|
-
|
|
30
|
-
```js
|
|
31
|
-
import {
|
|
32
|
-
buildFingerprint, checkFingerprint, promptSha256,
|
|
33
|
-
runtimeRequestHash, sha256Bytes,
|
|
34
|
-
} from "@zanii/certify";
|
|
35
|
-
|
|
36
|
-
const fingerprint = buildFingerprint({
|
|
37
|
-
model: "example-model@1",
|
|
38
|
-
prompt: promptSha256("Answer using the approved policy."),
|
|
39
|
-
tools: null,
|
|
40
|
-
policy: null,
|
|
41
|
-
knowledge: null,
|
|
42
|
-
});
|
|
43
|
-
if (!checkFingerprint(fingerprint)) throw new Error("Invalid fingerprint");
|
|
44
|
-
console.log(fingerprint.id);
|
|
45
|
-
|
|
46
|
-
// Commit the exact request body bytes; this hash alone grants no permission.
|
|
47
|
-
const body = '{"amount_minor":100,"currency":"USD"}';
|
|
48
|
-
console.log(runtimeRequestHash({
|
|
49
|
-
method: "POST",
|
|
50
|
-
url: "https://bank.example/payments",
|
|
51
|
-
body_sha256: sha256Bytes(body),
|
|
52
|
-
}));
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
Fingerprint fields contain hashes or `null`, rather than raw prompts/documents.
|
|
56
|
-
Keep the original bytes: changing whitespace can change a commitment.
|
|
57
|
-
|
|
58
|
-
##
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
1
|
+
# @zanii/certify
|
|
2
|
+
|
|
3
|
+
TypeScript SDK and `certify` CLI for Zanii Certify fingerprints, signed certificates,
|
|
4
|
+
status, evidence sharing, runtime assurance and scheme governance. The package uses
|
|
5
|
+
ES modules and requires Node.js 24 or newer. Every public function is exported from the
|
|
6
|
+
package root; the signed formats are defined in the Zanii Certify specification (`spec/`).
|
|
7
|
+
|
|
8
|
+
## Install
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @zanii/certify
|
|
12
|
+
npx certify verify cert.json --online https://lab.zanii.agency
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Paths in backticks below (`spec/...`, `conformance/...`) are files of the Zanii Certify source repository, which is private; the specification documents are available from Zanii on request (info@zanii.agency).
|
|
16
|
+
|
|
17
|
+
## Use this checkout
|
|
18
|
+
|
|
19
|
+
From the repository root, with the pnpm version declared in the root `package.json`:
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
pnpm install --frozen-lockfile
|
|
23
|
+
node packages/certify/src/cli.ts --help-v2
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The workspace package resolves directly to TypeScript source. Save the following as
|
|
27
|
+
`example.mjs` at the repository root and run `node example.mjs`. It needs no server,
|
|
28
|
+
network access or signing key:
|
|
29
|
+
|
|
30
|
+
```js
|
|
31
|
+
import {
|
|
32
|
+
buildFingerprint, checkFingerprint, promptSha256,
|
|
33
|
+
runtimeRequestHash, sha256Bytes,
|
|
34
|
+
} from "@zanii/certify";
|
|
35
|
+
|
|
36
|
+
const fingerprint = buildFingerprint({
|
|
37
|
+
model: "example-model@1",
|
|
38
|
+
prompt: promptSha256("Answer using the approved policy."),
|
|
39
|
+
tools: null,
|
|
40
|
+
policy: null,
|
|
41
|
+
knowledge: null,
|
|
42
|
+
});
|
|
43
|
+
if (!checkFingerprint(fingerprint)) throw new Error("Invalid fingerprint");
|
|
44
|
+
console.log(fingerprint.id);
|
|
45
|
+
|
|
46
|
+
// Commit the exact request body bytes; this hash alone grants no permission.
|
|
47
|
+
const body = '{"amount_minor":100,"currency":"USD"}';
|
|
48
|
+
console.log(runtimeRequestHash({
|
|
49
|
+
method: "POST",
|
|
50
|
+
url: "https://bank.example/payments",
|
|
51
|
+
body_sha256: sha256Bytes(body),
|
|
52
|
+
}));
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Fingerprint fields contain hashes or `null`, rather than raw prompts/documents.
|
|
56
|
+
Keep the original bytes: changing whitespace can change a commitment.
|
|
57
|
+
|
|
58
|
+
## Your agent's test endpoint
|
|
59
|
+
|
|
60
|
+
The lab tests an agent at the endpoint you register. Two kinds run every test, including the multi-step workflow tests that current profiles require at every level:
|
|
61
|
+
|
|
62
|
+
- **OpenAI-compatible** (`openai`): a Chat Completions URL and model.
|
|
63
|
+
- **HTTP** (`http`): the lab posts `{messages, documents, tools}` and reads `{reply, tool_calls?: [{id?, name, arguments?}]}`. In workflow tests the lab answers each tool call with a `{role: "tool", tool_call_id, content}` message and posts again; a reply without tool calls ends the workflow. Calls without an `id` get one from the lab.
|
|
64
|
+
|
|
65
|
+
MCP and A2A endpoints run single-turn tests only, so the lab refuses applications from them for profiles whose level includes workflow tests (`ENDPOINT_CANNOT_RUN_WORKFLOWS`). A lab that certifies also refuses applications for profiles it has no tests in force for (`PROFILE_NOT_TESTABLE`); the profile list marks those with `testable: false`.
|
|
66
|
+
|
|
67
|
+
## Verification policy
|
|
68
|
+
|
|
69
|
+
`await verifyCertificate(certificate, options)` returns a structured check with
|
|
70
|
+
`ok` and `reasons`. Optional checks run when their inputs/policies are supplied;
|
|
71
|
+
an `ok` result alone does not mean every relying-party requirement was checked.
|
|
72
|
+
|
|
73
|
+
- Supply fresh signed `status` and `revocationList`, the expected `fingerprint`,
|
|
74
|
+
and an explicit verification time (`now`) when reproducibility is required.
|
|
75
|
+
- Supply an independently approved `issuerPolicy` and the corresponding `issuerDoc`.
|
|
76
|
+
A downloaded document cannot choose its own trusted keys. Changed keys/PQ metadata
|
|
77
|
+
require local policy review; `allowNoPq` cannot override this pinned policy.
|
|
78
|
+
- Supply `pq`/`statusPq` when required. For Level 3, supply the audit plus trusted
|
|
79
|
+
bodies or an independently rooted body register. Add witness, licence and release
|
|
80
|
+
policies where the relying party requires them. Strict withdrawal checking needs
|
|
81
|
+
the withdrawal log and `releases.rejectWithdrawn: true`.
|
|
82
|
+
|
|
83
|
+
The complete option types are in certificate.ts (`packages/certify/src/certificate.ts`), and executable
|
|
84
|
+
positive/negative policy examples are in verification-policy.test.ts (`packages/certify/src/verification-policy.test.ts`).
|
|
85
|
+
Legacy optional behavior is retained for compatibility; select your policy explicitly.
|
|
86
|
+
Offline evidence cannot reveal an undisclosed newer checkpoint or revocation.
|
|
87
|
+
|
|
88
|
+
The CLI is offline by default. `--help-v2` lists current audit, witness, release and
|
|
89
|
+
strict-policy inputs. `--online` enables bounded retrieval, including required PQ
|
|
90
|
+
material. A relying party requiring every CLI check should accept only exit code 0;
|
|
91
|
+
exit code 2 means not fully checked. See the CLI contract (`spec/cli.md`).
|
|
92
|
+
|
|
93
|
+
## Contracts and limits
|
|
94
|
+
|
|
95
|
+
| Area | Contract |
|
|
96
|
+
| --- | --- |
|
|
97
|
+
| Fingerprints and certificate verification | Fingerprint (`spec/fingerprint.md`), certificate and pinned policy (`spec/certificate.md`) |
|
|
98
|
+
| Status and freshness | Status v1/v2 (`spec/status.md`), witness checkpoints (`spec/witness.md`), Bitstring Status List (`spec/bitstring-status.md`), assurance withdrawal (`spec/assurance-status.md`) |
|
|
99
|
+
| Runtime releases, mandates, leases and knowledge proofs | Runtime assurance (`spec/runtime.md`) |
|
|
100
|
+
| Scheme releases, exact text and transitions | Scheme (`spec/scheme.md`), immutable text (`spec/scheme-text.md`), checkpointed log (`spec/scheme-log.md`) |
|
|
101
|
+
| Redacted evidence and inclusion proofs | Evidence sharing (`spec/evidence-share.md`) |
|
|
102
|
+
|
|
103
|
+
Builders and verifiers enforce format-specific byte/count limits. Read each contract
|
|
104
|
+
before choosing workload sizes or persisting freshness watermarks. A valid inclusion
|
|
105
|
+
proof establishes commitment to supplied data; it does not establish content truth,
|
|
106
|
+
ACL permission or quality. The Node package also exposes Nitro verification, a runtime
|
|
107
|
+
reporter and a reference gateway; those host integrations are not Python SDK equivalents.
|
|
108
|
+
|
|
109
|
+
## Beacon reporting
|
|
110
|
+
|
|
111
|
+
`startBeacon` sends immediately, then waits the configured interval after each completed
|
|
112
|
+
operation. Intervals must be between 1,000 and 2,147,483,647 milliseconds. Each client allows
|
|
113
|
+
one underlying operation; concurrent `send()` calls return a busy failure without queuing.
|
|
114
|
+
The full operation has a ten second deadline, including fingerprint collection, signing and
|
|
115
|
+
reading the response. Replies are capped at 32KiB; redirects and credentialed URLs are refused.
|
|
116
|
+
|
|
117
|
+
`stop()` disables automatic reporting and aborts the active request. Manual `send()` remains
|
|
118
|
+
available. An injected callback that ignores cancellation keeps its slot until it returns;
|
|
119
|
+
late callbacks cannot submit a report. Result observer exceptions do not interrupt reporting.
|
|
120
|
+
|
|
121
|
+
`startBeacon`, `createRuntimeReporter` and `createRuntimeGateway` accept optional
|
|
122
|
+
`transportKey: process.env.CERTIFY_TRANSPORT_KEY`. Use an agent-bound `ctk_` admission
|
|
123
|
+
credential issued by the owner/admin transport-key controls, never a management API key.
|
|
124
|
+
It travels only in the authority's Authorization header, outside signed documents and
|
|
125
|
+
hashes. The gateway never forwards it to a protected backend. Invalid prefixes and
|
|
126
|
+
non-HTTPS beacon endpoints are refused before I/O, except literal loopback/localhost
|
|
127
|
+
for local development. Runtime reporter/gateway authority URLs keep their existing
|
|
128
|
+
HTTPS requirement. Anonymous signed clients still work; transport admission does not
|
|
129
|
+
replace signatures, approved workload binding or replay checks. Redirects remain refused.
|
|
130
|
+
Callback error messages and beacon response echoes redact the supplied credential.
|
|
131
|
+
|
|
132
|
+
The reporter handles challenge/evidence and the gateway handles consume. Lease request
|
|
133
|
+
builders produce signed documents; this package does not provide a general HTTP lease
|
|
134
|
+
acquisition or management client. Injected transports must keep credentials private and
|
|
135
|
+
honor the same redirect/deadline contract.
|
|
136
|
+
|
|
137
|
+
The package root also exports `JsonFetchResult`, `logPositionOk`,
|
|
138
|
+
`RUNTIME_NITRO_MAX_BYTES` and `RUNTIME_NITRO_MAX_SKEW_SECONDS` for callers validating
|
|
139
|
+
issuer responses, status log positions and raw runtime attestations.
|
|
140
|
+
|
|
141
|
+
## Check changes
|
|
142
|
+
|
|
143
|
+
Run from the repository root:
|
|
144
|
+
|
|
145
|
+
```sh
|
|
146
|
+
pnpm typecheck
|
|
147
|
+
pnpm --filter @zanii/certify test
|
|
148
|
+
node --test packages/certify/src/verification-policy.test.ts
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Shared vectors (`spec/vectors`) and conformance tests (`conformance`)
|
|
152
|
+
check the common TypeScript/Python wire formats. New versioned formats preserve the
|
|
153
|
+
old signed bytes. Local SDK tests do not qualify deployment security or capacity;
|
|
154
|
+
see the readiness report (`docs/readiness-report.md`).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zanii/certify",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.1",
|
|
4
4
|
"description": "Build and verify Zanii Certify certificates for AI agents: fingerprints, signed certificates, status documents, test suites and the certify command.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://zanii.agency",
|