@adastracomputing/ink 0.1.0-alpha.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.
Files changed (48) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/CODE_OF_CONDUCT.md +42 -0
  3. package/LICENSE-APACHE +201 -0
  4. package/LICENSE-MIT +21 -0
  5. package/README.md +133 -0
  6. package/SECURITY.md +57 -0
  7. package/docs/key-rotation-rule.md +108 -0
  8. package/docs/logo.svg +8 -0
  9. package/docs/maturity.md +81 -0
  10. package/docs/threat-model.md +150 -0
  11. package/package.json +72 -0
  12. package/specs/ink-agent-containment-and-governance-extension-spec.md +508 -0
  13. package/specs/ink-auditability.md +652 -0
  14. package/specs/ink-authorization-chain.md +242 -0
  15. package/specs/ink-compatibility-policy.md +263 -0
  16. package/specs/ink-compliance-checklist.md +309 -0
  17. package/specs/ink-containment-phase1-implementation-spec.md +593 -0
  18. package/specs/ink-introduction-receipts-extension.md +501 -0
  19. package/specs/ink-key-rotation-spec.md +535 -0
  20. package/src/crypto/ink.ts +902 -0
  21. package/src/crypto/keys.ts +211 -0
  22. package/src/crypto/multi-key-verify.ts +170 -0
  23. package/src/crypto/sign.ts +155 -0
  24. package/src/crypto/verify.ts +1 -0
  25. package/src/discovery/agent-card.ts +508 -0
  26. package/src/index.ts +59 -0
  27. package/src/ink/checkpoint.ts +75 -0
  28. package/src/ink/discovery-gating.ts +147 -0
  29. package/src/ink/handshake-budget.ts +413 -0
  30. package/src/ink/receipts.ts +114 -0
  31. package/src/ink/transport-auth.ts +96 -0
  32. package/src/middleware/ink-auth.ts +263 -0
  33. package/src/models/agent-card.ts +63 -0
  34. package/src/models/ink-audit.ts +205 -0
  35. package/src/models/ink-handshake.ts +123 -0
  36. package/src/models/intent.ts +201 -0
  37. package/src/models/key-entry.ts +52 -0
  38. package/src/models/profile.ts +31 -0
  39. package/test-vectors/README.md +129 -0
  40. package/test-vectors/encryption.json +90 -0
  41. package/test-vectors/handshake.json +482 -0
  42. package/test-vectors/jcs.json +30 -0
  43. package/test-vectors/key-rotation.json +101 -0
  44. package/test-vectors/keys.json +32 -0
  45. package/test-vectors/receipts-and-audit.json +142 -0
  46. package/test-vectors/replay.json +88 -0
  47. package/test-vectors/signing.json +61 -0
  48. package/test-vectors/witness.json +394 -0
@@ -0,0 +1,81 @@
1
+ # Maturity Notice
2
+
3
+ > INK v0.1 is **experimental**. Wire formats, trust semantics and APIs
4
+ > may change without backward-compatible migration before v1.0. Do not
5
+ > use for load-bearing production traffic without your own review.
6
+
7
+ ## What "experimental" means here
8
+
9
+ - The repository has **not** undergone an independent security audit.
10
+ It has been through structured internal review covering signature
11
+ handling, key rotation, replay protection, SSRF defenses on
12
+ agent-card fetch, and DoS-amplification surfaces. Internal review is
13
+ not a substitute for a third-party audit, treat the security
14
+ posture accordingly.
15
+ - Interop vectors (`../test-vectors/`) are authoritative for v0.1 but may
16
+ be added to or revised between v0.1 patch releases. Mismatched
17
+ implementations should report discrepancies as issues.
18
+ - The protocol is in use by one production integrator (Tulpa). That is
19
+ one data point, not a guarantee of robustness at scale.
20
+ - The reference implementation in `src/` runs on any runtime providing
21
+ standard Web Crypto (`crypto.subtle`) and `fetch`, modern Node, Deno,
22
+ Bun, and edge runtimes. Browser use is feasible but not exercised by
23
+ the maintainers.
24
+
25
+ ## What is stable in v0.1
26
+
27
+ - Envelope structure (fields, canonicalization with JCS / RFC 8785)
28
+ - Ed25519 signing base: `ink/0.1\nMETHOD\nPATH\nrecipientDid\nJCS(body)\ntimestamp`
29
+ - Agent Card schema for `keys.signing` and `keys.encryption`
30
+ - Key rotation authority rule (see `key-rotation-rule.md`)
31
+ - Timestamp freshness semantics: 5 min past tolerance, 30 s future
32
+ tolerance. Nonce cache TTL is integrator-defined (the witness
33
+ reference uses 10 min); INK does not mandate it.
34
+ - Receipt envelope structure
35
+
36
+ ## What may still change
37
+
38
+ - Authorization chain attenuation semantics, currently spec'd as
39
+ scope-subset-only delegation; may gain time-bounded or usage-bounded
40
+ variants.
41
+ - Containment vocabulary (capability-gated visibility, sender budgets,
42
+ backoff hints), the current shape is deliberately minimal; a v0.2
43
+ may formalize policy expression.
44
+ - Third-party witness submission API, currently a reference client
45
+ only. The submission envelope may move to a signed-bundle format in
46
+ the future.
47
+ - Encryption envelope AAD composition, the current AAD is
48
+ `ink/0.1:envelope\n` followed by the JCS canonicalization of
49
+ `{protocol, type, from, ephemeralKey, nonce, timestamp, messageNonce}`.
50
+ Future versions may include the recipient DID or evolve the field set.
51
+
52
+ ## Versioning
53
+
54
+ Pre-1.0 releases follow `0.Y.Z` semantics:
55
+
56
+ - `0.Y.0`, Minor version bump indicates a wire-format change. Receivers
57
+ must support at least one prior minor during a transition window.
58
+ - `0.Y.Z` (Z > 0), Patch bumps fix bugs in the reference implementation
59
+ and update test vectors where needed. They do not change wire format.
60
+
61
+ Breaking changes before v1.0 will be announced in the repository
62
+ changelog with at least 30 days of overlap support in the reference
63
+ implementation.
64
+
65
+ ## How to evaluate for your use
66
+
67
+ Before adopting INK for any use where signature forgery or replay would
68
+ be a real incident:
69
+
70
+ 1. Read [`threat-model.md`](./threat-model.md). Make sure your use case
71
+ falls inside the in-scope protections and you accept the out-of-scope
72
+ limits.
73
+ 2. Run `../test-vectors/*` against your implementation.
74
+ 3. Fuzz your envelope parser. The reference implementation's tests are
75
+ not a substitute.
76
+ 4. Pen-test the rotation and revocation flows specifically. The
77
+ authority rule is the single most security-sensitive piece and the
78
+ most common place to introduce a shadowing bug.
79
+ 5. If your integration accepts delegation tokens or other capability
80
+ handoffs, design their trust model explicitly, INK v0.1 does not
81
+ specify one.
@@ -0,0 +1,150 @@
1
+ # Threat Model
2
+
3
+ This document describes what INK v0.1 aims to protect against and what it
4
+ does not. It is deliberately conservative. Treat every "not protected"
5
+ statement as a real limit of the current design.
6
+
7
+ ## In-scope protections
8
+
9
+ ### 1. Request authenticity
10
+ A signed INK message cannot be forged without one of the sender's currently
11
+ accepted signing keys under the key-rotation authority rule: any `active`
12
+ or `retired` key inside the validity window verifies, revoked keys never
13
+ verify. Endpoints that require a still-trusted key (writes, capability
14
+ grants) can pass `requireActiveKey: true` to `verifyInkAuth` to reject
15
+ retired-key signatures. The signing base covers method, path, recipient
16
+ DID, canonical JSON of the body, and timestamp; an attacker who can
17
+ replay body bytes but mutate any of those fields cannot produce a valid
18
+ signature.
19
+
20
+ ### 2. Replay protection (narrow window)
21
+ Each INK message body carries a `nonce` and `timestamp` (the latter is
22
+ also covered by the signing base). Receivers reject any timestamp more
23
+ than 5 minutes old or more than 30 seconds in the future (clock-skew
24
+ tolerance). Within that window, nonces are single-use per (sender,
25
+ receiver), a nonce that was already accepted is rejected. This means a
26
+ captured message can only be replayed within ~5 minutes on a receiver
27
+ that has not seen its nonce. Two enforcement paths are available:
28
+ `verifyInkAuth` enforces nonce single-use after signature verification
29
+ when passed a `NonceStore`; passing `"deferred"` is an explicit
30
+ acknowledgement that the caller will run `checkReplay` (or an
31
+ equivalent gate) elsewhere in the pipeline. Omitting `nonceStore`
32
+ returns `nonce_handling_required` so misconfigured deployments fail
33
+ loudly. Nonce backing storage and TTL policy are the integrator's
34
+ choice.
35
+
36
+ ### 3. Key rotation authority
37
+ See [`key-rotation-rule.md`](./key-rotation-rule.md). Revoked keys can
38
+ never verify. Retired keys can verify only during grace periods. The Card
39
+ signing set wins over locally-cached copies. Bootstrap keys are
40
+ first-contact only.
41
+
42
+ ### 4. Authorization chain integrity
43
+ A delegation from agent A to agent B is signed by A over A's identity,
44
+ B's identity, and the allowed scope. B cannot invent authorization B was
45
+ not given. See
46
+ [`../specs/ink-authorization-chain.md`](../specs/ink-authorization-chain.md).
47
+
48
+ ### 5. Receipt / audit envelope integrity
49
+ Delivery and read receipts are Ed25519-signed by the agent that issued
50
+ them. A receiver that stores receipts for audit can later prove the
51
+ counterparty acknowledged delivery without needing to trust INK itself.
52
+ Receipts do not verify using `revoked` keys.
53
+
54
+ ### 6. Capability-gated Agent Card discovery
55
+ An agent whose Card visibility is `network_only` or `capability_gated`
56
+ returns a redacted Card to anonymous queries. The redacted Card preserves
57
+ public signing keys (so rotation discovery still works) but hides
58
+ capabilities, endpoints, availability and profile.
59
+
60
+ ### 7. Handshake-budget DoS resistance
61
+ Per-sender and per-recipient budgets throttle how many failing handshakes
62
+ an unknown sender can force a recipient to process. Over-budget senders
63
+ receive a signed backoff hint; persistently abusive senders are
64
+ rate-limited at the transport layer.
65
+
66
+ ## Out of scope (known limits)
67
+
68
+ ### Identity proof
69
+ INK does not prove *who* an agent is in the real world. Identity-system
70
+ compromise (a malicious PDS returning a fabricated DID document, a
71
+ compromised registration service) is the identity system's problem.
72
+ Receivers authenticate *the cryptographic continuity* of a senderId ↔
73
+ Agent Card binding; they cannot authenticate that the human behind the
74
+ agent is who they claim.
75
+
76
+ ### Compromised endpoints
77
+ If a sender's private keys are exfiltrated, an attacker can sign anything
78
+ the legitimate sender could until the key is revoked. INK's rotation rule
79
+ bounds the damage window but does not eliminate it. Key custody is out of
80
+ scope.
81
+
82
+ ### Malicious marketplace extensions (if you integrate one)
83
+ The reference implementation does not include an extension/marketplace
84
+ layer. A product that integrates INK and adds a delegation-token layer
85
+ (for third-party agents to act on behalf of users) must design its own
86
+ trust model for the marketplace, manifest review, and capability
87
+ attenuation. INK v0.1 deliberately excludes this surface.
88
+
89
+ ### Timing side-channels
90
+ `@noble/ed25519` is believed to be constant-time, but this has not been
91
+ independently audited in the INK context. Attacks that rely on very
92
+ precise timing of verification against a candidate key set are not
93
+ currently mitigated beyond what the underlying library provides.
94
+
95
+ ### Traffic analysis
96
+ INK messages reveal their type, sender, recipient, and approximate size
97
+ even when the payload is encrypted (`ink_encrypted`). A passive observer
98
+ on the network path can enumerate agent relationships over time. Mixnets,
99
+ onion routing, and other unlinkability mechanisms are not part of INK.
100
+
101
+ ### Side-channels in the agent itself
102
+ An agent that signs an INK message has seen the full plaintext. If the
103
+ agent is compromised, no amount of INK-layer protection helps. This is
104
+ especially important for agents that delegate to LLMs, prompt-injection
105
+ attacks against the agent's model can result in INK messages that are
106
+ cryptographically valid but semantically wrong (the model sent what the
107
+ attacker coaxed, not what the user wanted). INK does not address this.
108
+
109
+ ### Audit finality
110
+ INK supports witness submission for tamper-evident audit logs (see
111
+ [`../specs/ink-auditability.md`](../specs/ink-auditability.md)), but
112
+ does not by itself provide consensus or finality. Two honest receivers
113
+ that disagree about a message's receipt status cannot be reconciled by
114
+ INK alone.
115
+
116
+ ### Denial of service at the TCP/IP layer
117
+ INK's handshake budget protects against L7 DoS from known-pending senders.
118
+ It does not protect against L3/L4 floods, resource-exhaustion attacks on
119
+ the HTTP stack, or amplification attacks. Those remain the transport
120
+ operator's responsibility.
121
+
122
+ ### Cryptographic primitives
123
+ Ed25519 signatures, X25519 key exchange, AES-GCM for payload encryption.
124
+ If any of those primitives fails (future quantum attacks, implementation
125
+ flaws in `@noble/*` libraries), INK v0.1 has no fallback. A v1.0 might
126
+ specify algorithm agility.
127
+
128
+ ## Assumptions the protocol relies on
129
+
130
+ - TLS to the transport endpoint is correctly configured. INK signs at
131
+ the application layer but assumes confidentiality during transport.
132
+ - Server clocks are within 5 minutes of real time. Both the ±5-minute
133
+ timestamp window and the nonce TTL depend on this.
134
+ - The identity-system `senderId → Agent Card` resolution returns the
135
+ current Card within acceptable latency (receivers may cache with a
136
+ reasonable TTL, typically minutes).
137
+ - Receivers persist nonces durably enough to enforce the no-replay
138
+ window. A receiver that loses its nonce cache during a restart MAY see
139
+ duplicate accepts, this is a transient failure, not a protocol break.
140
+
141
+ ## Recommended receiver defaults
142
+
143
+ | Setting | Default |
144
+ |----------------------------------|------------------------|
145
+ | Timestamp max age | 5 minutes |
146
+ | Timestamp future skew tolerance | 30 seconds |
147
+ | Nonce TTL | 10 minutes |
148
+ | Agent Card cache TTL | 5 minutes |
149
+ | Unknown-sender handshake budget | 20 per hour per sender |
150
+ | Retired-key acceptance grace | Up to 30 days |
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@adastracomputing/ink",
3
+ "version": "0.1.0-alpha.0",
4
+ "description": "Reference implementation and specification of the INK (Inter-agent Networking Kernel) protocol",
5
+ "license": "MIT OR Apache-2.0",
6
+ "author": "Ad Astra Computing Inc.",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "https://github.com/Ad-Astra-Computing/ink.git"
10
+ },
11
+ "homepage": "https://ink.tulpa.network",
12
+ "bugs": {
13
+ "url": "https://github.com/Ad-Astra-Computing/ink/issues"
14
+ },
15
+ "type": "module",
16
+ "main": "./src/index.ts",
17
+ "types": "./src/index.ts",
18
+ "exports": {
19
+ ".": {
20
+ "types": "./src/index.ts",
21
+ "default": "./src/index.ts"
22
+ },
23
+ "./package.json": "./package.json"
24
+ },
25
+ "sideEffects": false,
26
+ "engines": {
27
+ "node": ">=22"
28
+ },
29
+ "files": [
30
+ "src/",
31
+ "specs/",
32
+ "docs/",
33
+ "test-vectors/",
34
+ "LICENSE-MIT",
35
+ "LICENSE-APACHE",
36
+ "README.md",
37
+ "SECURITY.md",
38
+ "CHANGELOG.md",
39
+ "CODE_OF_CONDUCT.md"
40
+ ],
41
+ "scripts": {
42
+ "test": "vitest run",
43
+ "typecheck": "tsc --noEmit",
44
+ "lint": "eslint src/ test/ scripts/",
45
+ "check:surface": "tsx scripts/check-public-surface.ts"
46
+ },
47
+ "dependencies": {
48
+ "@noble/curves": "^2.2.0",
49
+ "@noble/ed25519": "^2.1.0",
50
+ "@noble/hashes": "^1.8.0",
51
+ "canonicalize": "^2.1.0",
52
+ "zod": "^3.23.0"
53
+ },
54
+ "devDependencies": {
55
+ "@cloudflare/workers-types": "^4.20260418.1",
56
+ "@types/node": "^22.0.0",
57
+ "@typescript-eslint/eslint-plugin": "^8.60.0",
58
+ "@typescript-eslint/parser": "^8.60.0",
59
+ "eslint": "^10.4.0",
60
+ "tsx": "^4.22.3",
61
+ "typescript": "^5.6.0",
62
+ "vitest": "^4.1.7"
63
+ },
64
+ "keywords": [
65
+ "ink",
66
+ "agent-protocol",
67
+ "ed25519",
68
+ "atproto",
69
+ "agent-to-agent",
70
+ "reference-implementation"
71
+ ]
72
+ }