@kya-os/mcp 1.10.0 → 1.11.0
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/AUDITABILITY.md +441 -0
- package/CHANGELOG.md +104 -0
- package/CONFORMANCE.md +598 -0
- package/README.md +67 -4
- package/SPEC.md +1827 -0
- package/dist/audit/adapters/legacy-audit-log.d.ts +20 -0
- package/dist/audit/adapters/legacy-audit-log.d.ts.map +1 -0
- package/dist/audit/adapters/legacy-audit-log.js +56 -0
- package/dist/audit/adapters/legacy-audit-log.js.map +1 -0
- package/dist/audit/adapters/mcp.d.ts +105 -0
- package/dist/audit/adapters/mcp.d.ts.map +1 -0
- package/dist/audit/adapters/mcp.js +213 -0
- package/dist/audit/adapters/mcp.js.map +1 -0
- package/dist/audit/assurance.d.ts +22 -0
- package/dist/audit/assurance.d.ts.map +1 -0
- package/dist/audit/assurance.js +39 -0
- package/dist/audit/assurance.js.map +1 -0
- package/dist/audit/checkpoint-coordinator.d.ts +51 -0
- package/dist/audit/checkpoint-coordinator.d.ts.map +1 -0
- package/dist/audit/checkpoint-coordinator.js +112 -0
- package/dist/audit/checkpoint-coordinator.js.map +1 -0
- package/dist/audit/checkpoint.d.ts +59 -0
- package/dist/audit/checkpoint.d.ts.map +1 -0
- package/dist/audit/checkpoint.js +219 -0
- package/dist/audit/checkpoint.js.map +1 -0
- package/dist/audit/cli.d.ts +8 -0
- package/dist/audit/cli.d.ts.map +1 -0
- package/dist/audit/cli.js +85 -0
- package/dist/audit/cli.js.map +1 -0
- package/dist/audit/crypto.d.ts +37 -0
- package/dist/audit/crypto.d.ts.map +1 -0
- package/dist/audit/crypto.js +68 -0
- package/dist/audit/crypto.js.map +1 -0
- package/dist/audit/errors.d.ts +29 -0
- package/dist/audit/errors.d.ts.map +1 -0
- package/dist/audit/errors.js +33 -0
- package/dist/audit/errors.js.map +1 -0
- package/dist/audit/evidence.d.ts +45 -0
- package/dist/audit/evidence.d.ts.map +1 -0
- package/dist/audit/evidence.js +151 -0
- package/dist/audit/evidence.js.map +1 -0
- package/dist/audit/index.d.ts +27 -0
- package/dist/audit/index.d.ts.map +1 -0
- package/dist/audit/index.js +27 -0
- package/dist/audit/index.js.map +1 -0
- package/dist/audit/integrity.d.ts +19 -0
- package/dist/audit/integrity.d.ts.map +1 -0
- package/dist/audit/integrity.js +64 -0
- package/dist/audit/integrity.js.map +1 -0
- package/dist/audit/merkle.d.ts +31 -0
- package/dist/audit/merkle.d.ts.map +1 -0
- package/dist/audit/merkle.js +195 -0
- package/dist/audit/merkle.js.map +1 -0
- package/dist/audit/mirror-service.d.ts +19 -0
- package/dist/audit/mirror-service.d.ts.map +1 -0
- package/dist/audit/mirror-service.js +54 -0
- package/dist/audit/mirror-service.js.map +1 -0
- package/dist/audit/projection.d.ts +90 -0
- package/dist/audit/projection.d.ts.map +1 -0
- package/dist/audit/projection.js +142 -0
- package/dist/audit/projection.js.map +1 -0
- package/dist/audit/providers/anchor.d.ts +23 -0
- package/dist/audit/providers/anchor.d.ts.map +1 -0
- package/dist/audit/providers/anchor.js +25 -0
- package/dist/audit/providers/anchor.js.map +1 -0
- package/dist/audit/providers/evidence.d.ts +36 -0
- package/dist/audit/providers/evidence.d.ts.map +1 -0
- package/dist/audit/providers/evidence.js +2 -0
- package/dist/audit/providers/evidence.js.map +1 -0
- package/dist/audit/providers/journal.d.ts +35 -0
- package/dist/audit/providers/journal.d.ts.map +1 -0
- package/dist/audit/providers/journal.js +2 -0
- package/dist/audit/providers/journal.js.map +1 -0
- package/dist/audit/providers/memory-journal.d.ts +24 -0
- package/dist/audit/providers/memory-journal.d.ts.map +1 -0
- package/dist/audit/providers/memory-journal.js +73 -0
- package/dist/audit/providers/memory-journal.js.map +1 -0
- package/dist/audit/providers/observer.d.ts +30 -0
- package/dist/audit/providers/observer.d.ts.map +1 -0
- package/dist/audit/providers/observer.js +100 -0
- package/dist/audit/providers/observer.js.map +1 -0
- package/dist/audit/providers/outbox.d.ts +37 -0
- package/dist/audit/providers/outbox.d.ts.map +1 -0
- package/dist/audit/providers/outbox.js +52 -0
- package/dist/audit/providers/outbox.js.map +1 -0
- package/dist/audit/providers/recorder-client.d.ts +22 -0
- package/dist/audit/providers/recorder-client.d.ts.map +1 -0
- package/dist/audit/providers/recorder-client.js +17 -0
- package/dist/audit/providers/recorder-client.js.map +1 -0
- package/dist/audit/providers/source-state.d.ts +37 -0
- package/dist/audit/providers/source-state.d.ts.map +1 -0
- package/dist/audit/providers/source-state.js +94 -0
- package/dist/audit/providers/source-state.js.map +1 -0
- package/dist/audit/recorder-service.d.ts +78 -0
- package/dist/audit/recorder-service.d.ts.map +1 -0
- package/dist/audit/recorder-service.js +331 -0
- package/dist/audit/recorder-service.js.map +1 -0
- package/dist/audit/replay-bundle.d.ts +52 -0
- package/dist/audit/replay-bundle.d.ts.map +1 -0
- package/dist/audit/replay-bundle.js +551 -0
- package/dist/audit/replay-bundle.js.map +1 -0
- package/dist/audit/schemas.d.ts +1144 -0
- package/dist/audit/schemas.d.ts.map +1 -0
- package/dist/audit/schemas.js +483 -0
- package/dist/audit/schemas.js.map +1 -0
- package/dist/audit/service.d.ts +91 -0
- package/dist/audit/service.d.ts.map +1 -0
- package/dist/audit/service.js +222 -0
- package/dist/audit/service.js.map +1 -0
- package/dist/audit/testing/index.d.ts +2 -0
- package/dist/audit/testing/index.d.ts.map +1 -0
- package/dist/audit/testing/index.js +2 -0
- package/dist/audit/testing/index.js.map +1 -0
- package/dist/audit/testing/provider-contracts.d.ts +51 -0
- package/dist/audit/testing/provider-contracts.d.ts.map +1 -0
- package/dist/audit/testing/provider-contracts.js +391 -0
- package/dist/audit/testing/provider-contracts.js.map +1 -0
- package/dist/audit/types.d.ts +356 -0
- package/dist/audit/types.d.ts.map +1 -0
- package/dist/audit/types.js +49 -0
- package/dist/audit/types.js.map +1 -0
- package/dist/audit/verifier.d.ts +73 -0
- package/dist/audit/verifier.d.ts.map +1 -0
- package/dist/audit/verifier.js +322 -0
- package/dist/audit/verifier.js.map +1 -0
- package/dist/card/proof/canonical.d.ts.map +1 -1
- package/dist/card/proof/canonical.js +19 -1
- package/dist/card/proof/canonical.js.map +1 -1
- package/dist/delegation/delegation-graph.d.ts +4 -0
- package/dist/delegation/delegation-graph.d.ts.map +1 -1
- package/dist/delegation/delegation-graph.js +28 -2
- package/dist/delegation/delegation-graph.js.map +1 -1
- package/dist/delegation/statuslist-manager.d.ts +5 -0
- package/dist/delegation/statuslist-manager.d.ts.map +1 -1
- package/dist/delegation/statuslist-manager.js.map +1 -1
- package/dist/delegation/storage/memory-graph-storage.d.ts +4 -2
- package/dist/delegation/storage/memory-graph-storage.d.ts.map +1 -1
- package/dist/delegation/storage/memory-graph-storage.js +18 -0
- package/dist/delegation/storage/memory-graph-storage.js.map +1 -1
- package/dist/delegation/storage/memory-statuslist-storage.d.ts +5 -2
- package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +1 -1
- package/dist/delegation/storage/memory-statuslist-storage.js +21 -2
- package/dist/delegation/storage/memory-statuslist-storage.js.map +1 -1
- package/dist/delegation/utils.d.ts.map +1 -1
- package/dist/delegation/utils.js +2 -42
- package/dist/delegation/utils.js.map +1 -1
- package/dist/delegation/vc-verifier.d.ts +4 -0
- package/dist/delegation/vc-verifier.d.ts.map +1 -1
- package/dist/delegation/vc-verifier.js +44 -13
- package/dist/delegation/vc-verifier.js.map +1 -1
- package/dist/errors.d.ts +1 -1
- package/dist/errors.js +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/middleware/kya-os-transport.d.ts.map +1 -1
- package/dist/middleware/kya-os-transport.js +10 -3
- package/dist/middleware/kya-os-transport.js.map +1 -1
- package/dist/middleware/with-kya-os-server.d.ts +6 -0
- package/dist/middleware/with-kya-os-server.d.ts.map +1 -1
- package/dist/middleware/with-kya-os-server.js +2 -0
- package/dist/middleware/with-kya-os-server.js.map +1 -1
- package/dist/middleware/with-kya-os.config-types.d.ts +15 -0
- package/dist/middleware/with-kya-os.config-types.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.config-types.js.map +1 -1
- package/dist/middleware/with-kya-os.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.delegation-gate.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.delegation-gate.js +96 -3
- package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.deps.d.ts +2 -0
- package/dist/middleware/with-kya-os.deps.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.js +23 -0
- package/dist/middleware/with-kya-os.js.map +1 -1
- package/dist/middleware/with-kya-os.policy-gate.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.policy-gate.js +29 -4
- package/dist/middleware/with-kya-os.policy-gate.js.map +1 -1
- package/dist/middleware/with-kya-os.protocol.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.protocol.js +10 -0
- package/dist/middleware/with-kya-os.protocol.js.map +1 -1
- package/dist/middleware/with-kya-os.session.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.session.js +208 -2
- package/dist/middleware/with-kya-os.session.js.map +1 -1
- package/dist/middleware/with-kya-os.types.d.ts +6 -0
- package/dist/middleware/with-kya-os.types.d.ts.map +1 -1
- package/dist/middleware/with-kya-os.types.js.map +1 -1
- package/dist/proof/generator.d.ts.map +1 -1
- package/dist/proof/generator.js +6 -5
- package/dist/proof/generator.js.map +1 -1
- package/dist/proof/verifier.d.ts +12 -0
- package/dist/proof/verifier.d.ts.map +1 -1
- package/dist/proof/verifier.js +35 -4
- package/dist/proof/verifier.js.map +1 -1
- package/dist/session/manager.js +1 -1
- package/dist/session/manager.js.map +1 -1
- package/dist/utils/canonical-json.d.ts +15 -0
- package/dist/utils/canonical-json.d.ts.map +1 -0
- package/dist/utils/canonical-json.js +109 -0
- package/dist/utils/canonical-json.js.map +1 -0
- package/dist/utils/crypto-service.d.ts.map +1 -1
- package/dist/utils/crypto-service.js +5 -0
- package/dist/utils/crypto-service.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/safe-fetch-transports.d.ts +15 -2
- package/dist/utils/safe-fetch-transports.d.ts.map +1 -1
- package/dist/utils/safe-fetch-transports.js +66 -32
- package/dist/utils/safe-fetch-transports.js.map +1 -1
- package/package.json +29 -11
- package/schemas/README.md +27 -1
- package/schemas/audit-anchor-receipt.schema.json +16 -0
- package/schemas/audit-bundle-manifest.schema.json +71 -0
- package/schemas/audit-checkpoint.schema.json +37 -0
- package/schemas/audit-consistency-proof.schema.json +17 -0
- package/schemas/audit-entry.schema.json +33 -0
- package/schemas/audit-event.schema.json +168 -0
- package/schemas/audit-inclusion-proof.schema.json +17 -0
- package/schemas/audit-observation.schema.json +40 -0
- package/schemas/audit-receipt.schema.json +32 -0
- package/schemas/audit-verification-policy.schema.json +71 -0
- package/schemas/audit-verification-report.schema.json +29 -0
- package/schemas/well-known-mcpi.json +17 -0
package/AUDITABILITY.md
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
# KYA-OS Auditability Protocol
|
|
2
|
+
|
|
3
|
+
This document is the implementation and operations guide for the auditability
|
|
4
|
+
domain exported by `@kya-os/mcp/audit`. The normative wire objects are the JSON
|
|
5
|
+
schemas under [`schemas/`](./schemas/), while this guide explains how the pieces
|
|
6
|
+
compose and what an assurance claim actually means.
|
|
7
|
+
|
|
8
|
+
The protocol provides evidence that supports audit, incident-response, and
|
|
9
|
+
regulatory-control workflows. It does not itself make an application compliant,
|
|
10
|
+
prove that an uninstrumented event never happened, or turn a storage receipt into
|
|
11
|
+
an independent non-equivocation guarantee.
|
|
12
|
+
|
|
13
|
+
## The result
|
|
14
|
+
|
|
15
|
+
The audit service combines four deliberately separate layers:
|
|
16
|
+
|
|
17
|
+
1. A privacy-minimal, strictly typed producer event.
|
|
18
|
+
2. An authoritative recorder that atomically assigns epoch, sequence,
|
|
19
|
+
predecessor, service time, and a signed receipt.
|
|
20
|
+
3. RFC 9162 Merkle checkpoints, independently observed heads, and optional
|
|
21
|
+
supporting WORM/RFC 3161/SCITT receipts.
|
|
22
|
+
4. A signed-inventory replay bundle verified against trust and authorization
|
|
23
|
+
policy supplied outside that bundle.
|
|
24
|
+
|
|
25
|
+
Detached tool proofs remain origin evidence. They are not overloaded with log
|
|
26
|
+
state, and they do not assign chain position. The recorder envelope composes
|
|
27
|
+
proofs, authorization collateral, outcomes, and administrative events into one
|
|
28
|
+
replayable history.
|
|
29
|
+
|
|
30
|
+
## Public modules
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import {
|
|
34
|
+
createAuditTrail,
|
|
35
|
+
createLocalAuditRecorder,
|
|
36
|
+
AuditRecorderService,
|
|
37
|
+
AuditCheckpointBuilder,
|
|
38
|
+
AuditCheckpointCoordinator,
|
|
39
|
+
AuditArtifactVerifier,
|
|
40
|
+
AuditReplayBundleExporter,
|
|
41
|
+
verifyAuditBundle,
|
|
42
|
+
} from '@kya-os/mcp/audit';
|
|
43
|
+
|
|
44
|
+
import {
|
|
45
|
+
evaluateAuditJournalProviderContract,
|
|
46
|
+
assertAuditProviderContract,
|
|
47
|
+
} from '@kya-os/mcp/audit/testing';
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
`@kya-os/mcp/audit` contains runtime contracts and reference implementations.
|
|
51
|
+
`@kya-os/mcp/audit/testing` is framework-neutral: adapter packages can run the
|
|
52
|
+
same executable provider contracts under Vitest, Jest, Node test, or their own
|
|
53
|
+
harness without taking a production dependency on a test framework.
|
|
54
|
+
|
|
55
|
+
## Local composition
|
|
56
|
+
|
|
57
|
+
The smallest complete topology runs the authoritative recorder in process. The
|
|
58
|
+
memory implementations are intentionally ephemeral and appropriate only for
|
|
59
|
+
tests, examples, and local development.
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
import { generateKeyPair } from 'jose';
|
|
63
|
+
import { NodeCryptoProvider } from '@kya-os/mcp';
|
|
64
|
+
import {
|
|
65
|
+
CompactJwsAuditSigner,
|
|
66
|
+
CryptoProviderAuditHasher,
|
|
67
|
+
MemoryAuditJournal,
|
|
68
|
+
createLocalAuditRecorder,
|
|
69
|
+
createAuditTrail,
|
|
70
|
+
} from '@kya-os/mcp/audit';
|
|
71
|
+
|
|
72
|
+
const crypto = new NodeCryptoProvider();
|
|
73
|
+
const hasher = new CryptoProviderAuditHasher(crypto);
|
|
74
|
+
const { privateKey } = await generateKeyPair('EdDSA');
|
|
75
|
+
const recorderRef = {
|
|
76
|
+
did: 'did:web:audit.example',
|
|
77
|
+
kid: 'did:web:audit.example#recorder-2026-01',
|
|
78
|
+
alg: 'EdDSA',
|
|
79
|
+
} as const;
|
|
80
|
+
const journal = new MemoryAuditJournal();
|
|
81
|
+
const signer = new CompactJwsAuditSigner(recorderRef, privateKey);
|
|
82
|
+
|
|
83
|
+
const recorder = createLocalAuditRecorder({
|
|
84
|
+
ledgerId: 'kya:tenant-opaque:prod:primary',
|
|
85
|
+
ledgerEpochId: 'epoch-2026-07',
|
|
86
|
+
tenantRef: {
|
|
87
|
+
kind: 'keyed_commitment',
|
|
88
|
+
value: `sha256:${'0'.repeat(64)}`,
|
|
89
|
+
keyId: 'tenant-index-key-v3',
|
|
90
|
+
},
|
|
91
|
+
binding: 'urn:kya-os:audit-binding:mcp:2025-11-25',
|
|
92
|
+
sourceId: 'authoritative-recorder',
|
|
93
|
+
journal,
|
|
94
|
+
signer,
|
|
95
|
+
hasher,
|
|
96
|
+
clock: Date,
|
|
97
|
+
}, () => ({
|
|
98
|
+
producerAuthority: 'did:web:mcp.example',
|
|
99
|
+
tenantAuthority: 'tenant-opaque',
|
|
100
|
+
}));
|
|
101
|
+
|
|
102
|
+
const audit = createAuditTrail({
|
|
103
|
+
recorder,
|
|
104
|
+
delivery: 'required',
|
|
105
|
+
hasher,
|
|
106
|
+
ledgerId: 'kya:tenant-opaque:prod:primary',
|
|
107
|
+
expectedLedgerEpochId: 'epoch-2026-07',
|
|
108
|
+
tenantRef: {
|
|
109
|
+
kind: 'keyed_commitment',
|
|
110
|
+
value: `sha256:${'0'.repeat(64)}`,
|
|
111
|
+
keyId: 'tenant-index-key-v3',
|
|
112
|
+
},
|
|
113
|
+
producer: { kind: 'pairwise_did', did: 'did:key:zProducer' },
|
|
114
|
+
sourceId: 'mcp-server-1',
|
|
115
|
+
binding: 'urn:kya-os:audit-binding:mcp:2025-11-25',
|
|
116
|
+
privacy: { classification: 'internal', retentionClass: 'audit-365d' },
|
|
117
|
+
clock: Date,
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
await audit.record({
|
|
121
|
+
eventType: 'tool.call.completed',
|
|
122
|
+
action: { category: 'tool.call' },
|
|
123
|
+
outcome: 'succeeded',
|
|
124
|
+
evidence: [],
|
|
125
|
+
details: { family: 'tool', phase: 'completed', attempt: '1' },
|
|
126
|
+
});
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Pass `audit` to `withKyaOs(server, { crypto, audit })` or
|
|
130
|
+
`createKyaOsMiddleware({ identity, audit })`. Audit capability and profile data
|
|
131
|
+
are returned by the `_kyaos` identity action. `audit: false` advertises AAP-0.
|
|
132
|
+
The legacy `auditLog` option remains a migration-only capture sink; configuring
|
|
133
|
+
both old and new paths is rejected to prevent double counting.
|
|
134
|
+
|
|
135
|
+
See [`examples/audit-trail/`](./examples/audit-trail/) for an executable local
|
|
136
|
+
walkthrough.
|
|
137
|
+
|
|
138
|
+
## Recorder authority and topology
|
|
139
|
+
|
|
140
|
+
Exactly one logical authority assigns sequence and signs receipts for a
|
|
141
|
+
`(ledgerId, ledgerEpochId)` pair.
|
|
142
|
+
|
|
143
|
+
- In managed mode, a remote Checkpoint recorder implements
|
|
144
|
+
`AuditRecorderClient`. Producers send only a frozen event and encrypted
|
|
145
|
+
evidence; they cannot choose recorder time, sequence, predecessor, epoch, or
|
|
146
|
+
signature.
|
|
147
|
+
- In self-hosted mode, `AuditRecorderService` is backed by a transactional
|
|
148
|
+
journal owned by the tenant.
|
|
149
|
+
- In mirror mode, `AuditMirrorService` verifies and stores the exact signed
|
|
150
|
+
envelope. A mirror never resequences, resigns, or promotes itself silently.
|
|
151
|
+
|
|
152
|
+
Failover, key rotation that changes authority, and sealed retention rollover
|
|
153
|
+
create a new `ledgerEpochId`. The new genesis commits the previous epoch ID and
|
|
154
|
+
terminal checkpoint digest. Logical-ledger idempotency remains scoped by
|
|
155
|
+
authenticated producer authority, source ID, and event ID across retained
|
|
156
|
+
epochs, so a retry cannot become a new event after rollover. The recorder
|
|
157
|
+
resolves that idempotency before enforcing the epoch envelope: a redelivered
|
|
158
|
+
submission still pinned to a retained earlier epoch resolves to its original
|
|
159
|
+
entry, and `expectedLedgerEpochId` fences only new appends. The producer
|
|
160
|
+
never pins buffered outbox submissions, because a durable item may be
|
|
161
|
+
delivered after rollover, where the idempotency scope above, not epoch
|
|
162
|
+
pinning, carries the retry guarantee.
|
|
163
|
+
|
|
164
|
+
## Atomic journal contract
|
|
165
|
+
|
|
166
|
+
`AuditJournalProvider` is purpose-specific. Generic CRUD is insufficient. A
|
|
167
|
+
production adapter must provide:
|
|
168
|
+
|
|
169
|
+
- one serialization point for expected-head comparison plus exact append;
|
|
170
|
+
- unique epoch sequence and logical-ledger idempotency constraints;
|
|
171
|
+
- same-ID/same-content return of the original stored receipt;
|
|
172
|
+
- same-ID/different-content rejection;
|
|
173
|
+
- ordered, snapshot-stable range reads;
|
|
174
|
+
- no ordinary update or delete operation;
|
|
175
|
+
- truthful durability and atomicity capabilities.
|
|
176
|
+
|
|
177
|
+
Run the provider contract kit for every adapter:
|
|
178
|
+
|
|
179
|
+
```ts
|
|
180
|
+
const report = await evaluateAuditJournalProviderContract(
|
|
181
|
+
() => new PostgresAuditJournal(pool),
|
|
182
|
+
);
|
|
183
|
+
assertAuditProviderContract(report);
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The package also includes distinct evidence, observer, and supporting-anchor
|
|
187
|
+
contract suites. Passing the anchor suite never qualifies an adapter as an
|
|
188
|
+
independent observer.
|
|
189
|
+
|
|
190
|
+
For PostgreSQL, use a ledger-head row plus entry/idempotency unique constraints
|
|
191
|
+
inside one transaction. For Cloudflare, route one epoch to one Durable Object
|
|
192
|
+
serialization point. R2, KV, object lock, and a broker partition are useful
|
|
193
|
+
behind the design, but none alone satisfies authoritative compare-and-append.
|
|
194
|
+
|
|
195
|
+
## Delivery semantics
|
|
196
|
+
|
|
197
|
+
The producer declares one of three modes:
|
|
198
|
+
|
|
199
|
+
| Mode | Response boundary | Maximum honest claim |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| `best-effort` | append attempted | AAP-1 / capture only |
|
|
202
|
+
| `buffered` | durable producer outbox acknowledged | pending until receipt reconciliation |
|
|
203
|
+
| `required` | authoritative signed receipt obtained | chained/transparency profiles |
|
|
204
|
+
|
|
205
|
+
Buffered mode refuses an ephemeral outbox at startup. Required mode propagates
|
|
206
|
+
intent-append failure before the wrapped handler runs. If a terminal append
|
|
207
|
+
fails after an external side effect, middleware returns a degraded audit marker
|
|
208
|
+
instead of pretending the lifecycle is complete. Exactly-once behavior across
|
|
209
|
+
arbitrary external systems is not claimed; use a transactional outbox where the
|
|
210
|
+
host and producer outbox share a database, otherwise use intent, terminal event,
|
|
211
|
+
stable idempotency, and reconciliation.
|
|
212
|
+
|
|
213
|
+
Direct-mode retries are idempotent only when the rebuilt event is byte-stable:
|
|
214
|
+
a caller that retries `record()` with a stable event ID must also pin
|
|
215
|
+
`occurredAt`, otherwise the recorder rejects the drifted content as an
|
|
216
|
+
event-identity conflict. Buffered outbox redelivery is always byte-stable, and
|
|
217
|
+
`flush()` receipts each delivered item against the item's own producer source.
|
|
218
|
+
|
|
219
|
+
Evidence is persisted write-ahead of its committing entry. If the append then
|
|
220
|
+
permanently fails, the recorder best-effort disposes the orphaned ciphertext
|
|
221
|
+
after re-confirming that no committed entry claims the event identity; a
|
|
222
|
+
disposal failure retains the orphan for operator retention tooling rather than
|
|
223
|
+
risking a racing committed reference.
|
|
224
|
+
|
|
225
|
+
The outbox contract persists an `attempts` count and yields only delivery-eligible
|
|
226
|
+
items. Retry cadence, attempt caps, and dead-letter routing are provider policy,
|
|
227
|
+
because they depend on the host's queue and operational controls. A durable
|
|
228
|
+
adapter must remove dead-lettered items from `pending()` while retaining them for
|
|
229
|
+
operator inspection and recovery; the in-memory development adapter intentionally
|
|
230
|
+
has no retry cap.
|
|
231
|
+
|
|
232
|
+
Each producer event receives an atomically claimed source sequence. Consecutive
|
|
233
|
+
events also carry `previousSourceEventDigest`. `recordSourceHighWater()` emits
|
|
234
|
+
the producer's current high-water mark through the same recorder path. The
|
|
235
|
+
source-state provider tracks highest emitted, highest contiguously receipted,
|
|
236
|
+
and explicit pending gaps. AAP-3 requires durable source state.
|
|
237
|
+
|
|
238
|
+
## Event and privacy model
|
|
239
|
+
|
|
240
|
+
The event catalog is the `AUDIT_EVENT_TYPES` constant. It covers session, tool,
|
|
241
|
+
proof, delegation, authorization, consent/credential, key/configuration,
|
|
242
|
+
ledger/checkpoint, evidence/projection, and administrative lifecycle events.
|
|
243
|
+
Every detail payload is a strict discriminated union. Arbitrary integrity-core
|
|
244
|
+
metadata and unknown fields fail closed.
|
|
245
|
+
|
|
246
|
+
The MCP adapter excludes raw arguments, response bodies, error text, and tool
|
|
247
|
+
names by default. `includeToolNames` is an explicit policy decision. Identity
|
|
248
|
+
and resource references declare their privacy form:
|
|
249
|
+
|
|
250
|
+
- `public_did` for intentionally public correlation;
|
|
251
|
+
- `pairwise_did` for relationship-specific identity;
|
|
252
|
+
- `keyed_commitment` for tenant-keyed indexing resistant to low-entropy
|
|
253
|
+
dictionary attacks;
|
|
254
|
+
- `evidence_ref` for an encrypted object in a separate vault.
|
|
255
|
+
|
|
256
|
+
Do not put API keys, prompts, raw tool arguments, responses, access tokens, or
|
|
257
|
+
free-form exception text in the event core. Store allowed exact payloads as
|
|
258
|
+
encrypted evidence and commit only `EvidenceRef` metadata.
|
|
259
|
+
|
|
260
|
+
## Evidence, retention, and access
|
|
261
|
+
|
|
262
|
+
`WebCryptoEvidenceEncryptor` uses randomized AES-256-GCM, a random opaque object
|
|
263
|
+
ID, a 96-bit random nonce, authenticated-data digest, ciphertext digest, and key
|
|
264
|
+
version. Encryption and decryption reject empty AAD; callers must bind at least
|
|
265
|
+
the tenant/entity and evidence purpose into authenticated data. It does not use
|
|
266
|
+
convergent encryption. The producer and recorder both
|
|
267
|
+
reject encrypted objects that do not exactly match a unique reference in the
|
|
268
|
+
frozen event.
|
|
269
|
+
|
|
270
|
+
`AuditEvidenceProvider` separates ciphertext access from ledger verification.
|
|
271
|
+
Its retention commands support disposal, legal hold, and hold release. The
|
|
272
|
+
reference memory provider returns defensive byte copies, rejects object-ID
|
|
273
|
+
collisions, blocks disposal under legal hold, and can enforce an injected
|
|
274
|
+
actor/purpose access policy. Production retention schedulers translate a
|
|
275
|
+
deployment's retention classes into these explicit commands and append the
|
|
276
|
+
corresponding administration event.
|
|
277
|
+
|
|
278
|
+
Disposal removes ciphertext, not its commitment. Historical integrity remains
|
|
279
|
+
verifiable, while evidence availability becomes explicitly disposed,
|
|
280
|
+
redacted, unavailable, or policy-excluded in a bundle inventory.
|
|
281
|
+
|
|
282
|
+
## Checkpoints, observations, and anchors
|
|
283
|
+
|
|
284
|
+
`AuditCheckpointBuilder` takes a stable journal head, derives an RFC 9162 tree
|
|
285
|
+
over entry digests, signs an immutable checkpoint, and stores it with
|
|
286
|
+
put-if-absent conflict detection. It produces and verifies inclusion and
|
|
287
|
+
consistency proofs. Checkpoint lifecycle events are appended only after the
|
|
288
|
+
snapshot is signed, so they can appear in a later checkpoint and cannot recurse
|
|
289
|
+
into the checkpoint they describe.
|
|
290
|
+
|
|
291
|
+
`AuditCheckpointCoordinator` publishes a committed checkpoint to independent
|
|
292
|
+
observers and supporting anchors. Publication is retryable and may enforce a
|
|
293
|
+
minimum observer count and required anchor kinds. Failure does not roll back the
|
|
294
|
+
signed checkpoint.
|
|
295
|
+
|
|
296
|
+
The roles are not interchangeable:
|
|
297
|
+
|
|
298
|
+
- An independent observer validates, retains, chains, and compares checkpoint
|
|
299
|
+
views. It detects rollback and conflicting same-size roots relative to the
|
|
300
|
+
views it has independently learned. An observer that missed intermediate
|
|
301
|
+
publications catches up on any gapped extension whose tree consistency with
|
|
302
|
+
its last observation verifies; the consistency proof, not direct checkpoint
|
|
303
|
+
chain linkage, is the split-view guarantee.
|
|
304
|
+
- A WORM, RFC 3161, or SCITT adapter provides supporting durability,
|
|
305
|
+
registration, or time evidence. It does not by itself detect a split view.
|
|
306
|
+
|
|
307
|
+
## Replay bundles and offline verification
|
|
308
|
+
|
|
309
|
+
`AuditReplayBundleExporter` sorts component paths, canonicalizes included
|
|
310
|
+
content, records size and digest for every included item, records an explicit
|
|
311
|
+
disposition and reason for every omission, signs the manifest core, and binds
|
|
312
|
+
the verification-policy digest. Safe relative paths and duplicate inventory
|
|
313
|
+
entries are rejected.
|
|
314
|
+
|
|
315
|
+
`verifyAuditBundle()` is an offline, fail-closed verifier. It does not read live
|
|
316
|
+
nonce caches. It verifies:
|
|
317
|
+
|
|
318
|
+
- bundle schema, signed inventory, component bytes, scope, purpose, and exporter
|
|
319
|
+
authority;
|
|
320
|
+
- strict event/entry/receipt schema, domain-separated hashes, signatures,
|
|
321
|
+
recorder trust intervals, sequence, predecessor, and genesis;
|
|
322
|
+
- independent epoch sequence reset and predecessor-epoch checkpoint commitment;
|
|
323
|
+
- checkpoint root/range/signature, predecessor chain, fork conflicts, and
|
|
324
|
+
bundle-bound inclusion/consistency proofs;
|
|
325
|
+
- observer trust/signature/freshness/receipt chain;
|
|
326
|
+
- supporting-anchor trust and an injected adapter verifier;
|
|
327
|
+
- declared range completeness and explicit omission dispositions.
|
|
328
|
+
|
|
329
|
+
The report keeps these dimensions separate: cryptographic integrity, chain
|
|
330
|
+
integrity, checkpoint integrity, anchor/observation integrity, committed-scope
|
|
331
|
+
completeness, authorization as observed, and current authorization. Missing
|
|
332
|
+
collateral is `indeterminate`, never silently `valid`. Historical and current
|
|
333
|
+
authorization are separate injected policy ports because revocation today does
|
|
334
|
+
not rewrite what was observed at execution time.
|
|
335
|
+
|
|
336
|
+
Trust is always out of band. A bundle-supplied recorder key, observer key,
|
|
337
|
+
exporter key, DID document, genesis, or checkpoint cannot authorize itself.
|
|
338
|
+
|
|
339
|
+
CLI usage:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
kya-audit verify bundle.json \
|
|
343
|
+
--policy verification-policy.json \
|
|
344
|
+
--keys trusted-public-keys.json
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
Exit code `0` means no dimension is invalid, `1` means at least one invalid
|
|
348
|
+
dimension, and `2` means usage/configuration/input processing failed. An
|
|
349
|
+
`indeterminate` dimension remains visible in the JSON report and must be handled
|
|
350
|
+
by the relying party's policy.
|
|
351
|
+
|
|
352
|
+
## Projections and Checkpoint integration
|
|
353
|
+
|
|
354
|
+
`AuditProjectionWorker` derives a minimal timeline projection with an atomic
|
|
355
|
+
offset. It supports incremental synchronization, deterministic reset/rebuild,
|
|
356
|
+
and head reconciliation with four honest states: `empty`, `pending`,
|
|
357
|
+
`verified`, and `gap_detected`. The projection is disposable. The journal plus
|
|
358
|
+
declared enrichment inputs remain the source of truth.
|
|
359
|
+
|
|
360
|
+
Checkpoint should ingest exact signed envelopes through the mirror or recorder
|
|
361
|
+
path, store raw integrity objects separately from query projections, and expose
|
|
362
|
+
legacy records as `unverified_legacy`. It should never convert old capture rows
|
|
363
|
+
into retroactively chained history. Bundle verification in the dashboard should
|
|
364
|
+
call the same pure verifier used by the CLI.
|
|
365
|
+
|
|
366
|
+
## Assurance profiles
|
|
367
|
+
|
|
368
|
+
Capabilities are machine-readable and validated at startup:
|
|
369
|
+
|
|
370
|
+
| Profile | Required basis | Claim |
|
|
371
|
+
|---|---|---|
|
|
372
|
+
| AAP-0 | audit disabled | no audit assurance |
|
|
373
|
+
| AAP-1 Recorded | typed capture | delivered instrumented events were recorded |
|
|
374
|
+
| AAP-2 Chained | durable atomic journal and non-best-effort delivery | ordered tamper-evident accepted history |
|
|
375
|
+
| AAP-3 Transparent | AAP-2, durable source high-water, RFC 9162 checkpoints | inclusion, consistency, and declared source-gap evidence |
|
|
376
|
+
| AAP-4 Observed | AAP-3, independent observation, supporting receipt | conflicting known views are detectable relative to independently retained checkpoints |
|
|
377
|
+
|
|
378
|
+
`assertAuditCapabilities()` rejects profiles whose configured mechanics do not
|
|
379
|
+
support their claim. A memory journal advertises `ephemeral`; a mirror advertises
|
|
380
|
+
`verified-mirror`; a supporting anchor never advertises independent observation.
|
|
381
|
+
|
|
382
|
+
## Cryptographic suites
|
|
383
|
+
|
|
384
|
+
All integrity-critical JSON is validated before RFC 8785 JCS. Unknown critical
|
|
385
|
+
fields, accessors, cycles, non-finite numbers, unsafe integers, sparse arrays,
|
|
386
|
+
and non-JSON values are rejected. Digest inputs are domain separated with the
|
|
387
|
+
UTF-8 bytes of `<domain> + NUL + JCS(value)`.
|
|
388
|
+
|
|
389
|
+
The initial domains and suites are exported constants:
|
|
390
|
+
|
|
391
|
+
- `org.kya-os.audit.event.v1`
|
|
392
|
+
- `org.kya-os.audit.entry.v1`
|
|
393
|
+
- `org.kya-os.audit.evidence-manifest.v1`
|
|
394
|
+
- `org.kya-os.audit.idempotency.v1`
|
|
395
|
+
- `org.kya-os.audit.checkpoint.v1`
|
|
396
|
+
- `org.kya-os.audit.observation.v1`
|
|
397
|
+
- `org.kya-os.audit.bundle-manifest.v1`
|
|
398
|
+
- `KYA-AUDIT-JCS-SHA256-JWS-2026`
|
|
399
|
+
- `KYA-AUDIT-RFC9162-SHA256-JWS-2026`
|
|
400
|
+
- `KYA-AUDIT-BUNDLE-JCS-SHA256-JWS-2026`
|
|
401
|
+
|
|
402
|
+
The conformance harness contains positive and negative vectors for event JCS,
|
|
403
|
+
the domain-separated event digest, RFC 9162 root, inclusion, and consistency.
|
|
404
|
+
The Python standard-library verifier independently reproduces the positive
|
|
405
|
+
values.
|
|
406
|
+
|
|
407
|
+
## Migration
|
|
408
|
+
|
|
409
|
+
`LegacyAuditSinkAdapter` translates legacy `AuditLogProvider` capture into an
|
|
410
|
+
explicit `legacy-capture` boundary without copying raw request/response content
|
|
411
|
+
or claiming chain history. It does not deduplicate by session, so multiple calls
|
|
412
|
+
in one session remain multiple events. During migration:
|
|
413
|
+
|
|
414
|
+
1. deploy new event emission in shadow validation;
|
|
415
|
+
2. compare lifecycle counts and semantic outcomes;
|
|
416
|
+
3. move the authoritative writer to the new recorder;
|
|
417
|
+
4. retain a signed import boundary and show old data as `unverified_legacy`;
|
|
418
|
+
5. remove `auditLog` only after parity and retention obligations are met.
|
|
419
|
+
|
|
420
|
+
## Production checklist
|
|
421
|
+
|
|
422
|
+
- Run every provider contract suite and 100+ concurrent recorder submissions.
|
|
423
|
+
- Exercise commit-before-response, retry, stale-head, restart, outbox backlog,
|
|
424
|
+
and DLQ recovery in the platform adapter repository.
|
|
425
|
+
- Pin recorder, observer, and exporter keys in an independently managed policy;
|
|
426
|
+
define validity and compromise boundaries.
|
|
427
|
+
- Configure a durable source-state provider for AAP-3 and reconcile high-water
|
|
428
|
+
gaps.
|
|
429
|
+
- Define checkpoint cadence, observer freshness, anchor retry, and alert bounds.
|
|
430
|
+
- Use pairwise/keyed references and an encrypted evidence vault with explicit
|
|
431
|
+
access policy, retention, legal hold, and crypto-shredding procedures.
|
|
432
|
+
- Monitor append/duplicate/conflict/error rates, receipt latency, outbox depth
|
|
433
|
+
and age, source gaps, checkpoint age, observer freshness, projection lag,
|
|
434
|
+
evidence dispositions, exports/access, and signer expiry.
|
|
435
|
+
- Maintain runbooks for corruption, compromised keys, split views, failed
|
|
436
|
+
anchors, evidence exposure, projection rebuild, legal hold, and offboarding.
|
|
437
|
+
|
|
438
|
+
The architecture supports evidence for controls such as NIST SP 800-53 AU,
|
|
439
|
+
SOC 2 logging/monitoring, ISO 27001 logging, and regulated recordkeeping. Any
|
|
440
|
+
compliance conclusion still depends on deployment, governance, access control,
|
|
441
|
+
retention, operating effectiveness, and the relying auditor.
|
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,110 @@ Versioning: https://semver.org/spec/v2.0.0.html
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [1.11.0] - 2026-07-22
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **Verifiable auditability protocol and `@kya-os/mcp/audit`.** Adds strict,
|
|
15
|
+
versioned, privacy-minimal events; an authoritative recorder with signed
|
|
16
|
+
append receipts, atomic compare-and-append, logical-ledger idempotency, and
|
|
17
|
+
epoch transitions; producer delivery modes and source high-water evidence;
|
|
18
|
+
RFC 9162 Merkle checkpoints, inclusion/consistency proofs, independent
|
|
19
|
+
observation, and supporting anchors; encrypted evidence lifecycle; pure
|
|
20
|
+
historical verification; signed replay bundles; rebuildable projections; and
|
|
21
|
+
the `kya-audit` offline verification CLI.
|
|
22
|
+
- **Provider contract kit.** `@kya-os/mcp/audit/testing` supplies executable,
|
|
23
|
+
framework-neutral journal, evidence, observer, and anchor contracts. Memory
|
|
24
|
+
reference providers cover concurrency, stale heads, duplicates, snapshots,
|
|
25
|
+
legal holds, disposal, observation conflicts, and role separation.
|
|
26
|
+
- **MCP audit instrumentation and capability discovery.** Typed lifecycle events
|
|
27
|
+
cover calls, errors, denials, step-up/authorization challenges, handshake
|
|
28
|
+
rejection, replay rejection, consent/credential/key/config/policy changes,
|
|
29
|
+
checkpoints, evidence, projections, exports, retention, and administration.
|
|
30
|
+
- **Audit schemas and conformance.** Publishes JSON Schemas for all portable
|
|
31
|
+
audit artifacts, an `audit-integrity` vector category, independent Python
|
|
32
|
+
verification of audit JCS/domain-separated hashes/RFC 9162 proofs, an
|
|
33
|
+
end-to-end walkthrough, and the normative `AUDITABILITY.md` operations guide.
|
|
34
|
+
|
|
35
|
+
### Fixed
|
|
36
|
+
|
|
37
|
+
- **Entity Card spec corrections from working-group review.** Three defects raised
|
|
38
|
+
against SPEC-ENTITY-CARD.md are resolved. (1) The Status section said the
|
|
39
|
+
`org.kya-os/proof@1` and legacy proofs share one `_meta` key discriminated by
|
|
40
|
+
`prf`; they ride separate keys (`org.kya-os/proof@1` vs `org.kya-os/proof`), as
|
|
41
|
+
§8.1 and the implementation always had it, and the Status text now matches.
|
|
42
|
+
(2) §8.3 now specifies the exact pre-signing transformation for `requestHash`:
|
|
43
|
+
the `_meta` member of `params` (the proof's own carrier) is removed before JCS
|
|
44
|
+
canonicalization, on both the mint and verify sides. Without that rule the
|
|
45
|
+
definition was circular for MCP requests, where the proof travels inside
|
|
46
|
+
`params._meta`. (3) Terminology now distinguishes the self-contained proof
|
|
47
|
+
object from stateful replay prevention: a verifier still needs a nonce store
|
|
48
|
+
and fails closed (`nonce_seam_missing`) without one, so the spec no longer
|
|
49
|
+
describes verification as stateless.
|
|
50
|
+
- **`computeRequestHash` applies the §8.3 transformation itself.** The card
|
|
51
|
+
hasher removes `params._meta` before canonicalizing, so a verifier handed the
|
|
52
|
+
raw inbound request (proof still attached) recomputes the hash the minter
|
|
53
|
+
signed instead of failing on a self-referential body. Requests without
|
|
54
|
+
`params._meta` hash byte-identically to before; all golden vectors are
|
|
55
|
+
unchanged.
|
|
56
|
+
- Historical proof verification no longer consumes live nonce state or applies
|
|
57
|
+
present-time freshness rules, and protected JWS `kid` values are bound to the
|
|
58
|
+
expected verification key.
|
|
59
|
+
- Failed child-delegation registration can no longer leave an orphan graph node,
|
|
60
|
+
and cached VC results cannot be reused across differing trust/status inputs.
|
|
61
|
+
|
|
62
|
+
### Changed
|
|
63
|
+
|
|
64
|
+
- **SPEC-ENTITY-CARD.md editorial pass.** Tightened the abstract and framing
|
|
65
|
+
sections, replaced em dashes with plain punctuation throughout, clarified that
|
|
66
|
+
a declared capability name conveys no authority (authority travels only in the
|
|
67
|
+
delegation chain), noted that a verifying resource should assert itself as the
|
|
68
|
+
expected `invocationTarget` when evaluating a chain, and updated the
|
|
69
|
+
reference-implementation version pointer.
|
|
70
|
+
- **The delegation profile moved into the core specification's delegation
|
|
71
|
+
chapter.** Working-group review made the case that an extended description of
|
|
72
|
+
delegation does not belong in the Entity Card specification: the card asserts
|
|
73
|
+
locators, so the card document should point at the delegation profile rather
|
|
74
|
+
than contain it. SPEC-ENTITY-CARD.md section 10 is now a compact section
|
|
75
|
+
holding only what card verification consumes directly (the two recomputed
|
|
76
|
+
accountability equalities, the meaning of the `revocation` field, and the
|
|
77
|
+
KYC/KYB surface). The full profile (the VC 2.0 + ZCAP-LD credential shape,
|
|
78
|
+
delegate rules, attenuation invariants, Bitstring revocation mechanics, and
|
|
79
|
+
the KYC/KYB shape) now lives in SPEC.md section 6.10, beside the legacy
|
|
80
|
+
credential shape it succeeds, so delegation has one home. The chain
|
|
81
|
+
attenuation rules are now called attenuation invariants to end a naming
|
|
82
|
+
collision with the CRISP constraint envelope of SPEC.md section 6.3. Content
|
|
83
|
+
moved verbatim; wire shapes, schemas, and all other section numbering are
|
|
84
|
+
unchanged, and every cross-reference was updated. A candidate card field
|
|
85
|
+
naming the access-control mechanisms an entity supports is recorded as an
|
|
86
|
+
open coordination item (section 15.7).
|
|
87
|
+
- Proof generation now uses a fresh cryptographic nonce for every proof artifact
|
|
88
|
+
while preserving the session nonce as session-establishment evidence.
|
|
89
|
+
- Canonical JSON handling is shared and strict RFC 8785, rejecting unsafe
|
|
90
|
+
integers, cycles, sparse arrays, accessors, and unsupported values before
|
|
91
|
+
hashing or signing.
|
|
92
|
+
- Delegation graph registration supports atomic parent validation, status-list
|
|
93
|
+
history is retained for historical decisions, and VC verification cache keys
|
|
94
|
+
bind all decision inputs.
|
|
95
|
+
- Replayed handshake nonces now report the precise `nonce_replay` protocol code,
|
|
96
|
+
allowing audit instrumentation to classify replay rejection independently.
|
|
97
|
+
|
|
98
|
+
## [1.10.1] - 2026-07-08
|
|
99
|
+
|
|
100
|
+
### Fixed
|
|
101
|
+
|
|
102
|
+
- **Cloudflare Worker / workerd bundle compatibility.** `safe-fetch-transports`
|
|
103
|
+
statically imported `node:dns/promises` and `node:https` at the module top
|
|
104
|
+
level, so anything that builds a `SafeFetch` — including the Entity Card /
|
|
105
|
+
VC-JWT verification path (card resolution + status-list revocation) — required
|
|
106
|
+
those node built-ins at bundle time and broke workerd builds. They now load
|
|
107
|
+
**lazily** (only when a node code path actually runs), so the module bundles
|
|
108
|
+
cleanly for workerd / browser. `selectDefaultTransport` transparently falls
|
|
109
|
+
back to `fetchTransport` where `node:https` is absent. The SSRF policy
|
|
110
|
+
(resolve-and-pin, private-range denial, redirect + size + timeout guards) is
|
|
111
|
+
unchanged; a Worker injects its own DNS seam (or uses trusted origins +
|
|
112
|
+
`fetchTransport`) to avoid `node:dns` at runtime.
|
|
113
|
+
|
|
10
114
|
## [1.10.0] - 2026-07-08
|
|
11
115
|
|
|
12
116
|
### Added
|