@agentcreds/sdk 0.1.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 (5) hide show
  1. package/LICENSE +10 -0
  2. package/README.md +159 -0
  3. package/index.d.ts +1271 -0
  4. package/index.js +370 -0
  5. package/package.json +45 -0
package/LICENSE ADDED
@@ -0,0 +1,10 @@
1
+ Apache License, Version 2.0
2
+ SPDX-License-Identifier: Apache-2.0
3
+
4
+ Copyright (c) AgentCreds and contributors.
5
+
6
+ This package is part of the AgentCreds SDK and is licensed under the Apache
7
+ License, Version 2.0. The full canonical license text is published at
8
+ https://www.apache.org/licenses/LICENSE-2.0 and is written into this file by
9
+ `scripts/fetch-licenses.sh` (run before publishing). The SPDX identifier above
10
+ and the package manifest's `license` field are authoritative.
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # @agentcreds/sdk (Node.js / TypeScript)
2
+
3
+ Node.js bindings for **AgentCreds** - verifiable, attenuable delegation for autonomous AI agents, verified offline.
4
+
5
+ > **Scope.** This SDK is at parity with the Python core binding - identities,
6
+ > credentials, tokens, presentations, revocation, key history, ADRs including
7
+ > accountability and R10 verdicts. The **runtime enforcement** layer is different:
8
+ > `@agentcreds/runtime` is **A2A-only by design** and is
9
+ > not an MCP policy enforcement point. R10 execution-time gates, step-up approval and
10
+ > the MCP enforcer are Python-only. A Node *agent* can talk to a Python PEP over the
11
+ > wire; a Node service cannot host one.
12
+
13
+ These bindings wrap the `agentcreds-core` Rust engine via [napi-rs](https://napi.rs).
14
+
15
+ ## A note on async
16
+
17
+ Every operation in this SDK is **synchronous** - there is no `Promise`/
18
+ `async`/`await` anywhere in this API. The underlying Rust operations (DID
19
+ generation, credential issuance/verification, token minting/attenuation/
20
+ verification, revocation checks) all complete in well under a millisecond,
21
+ so wrapping them in promises would add overhead without benefit. This is a
22
+ deliberate deviation from async-styled quickstarts you may see elsewhere in
23
+ the AgentCreds docs.
24
+
25
+ ## Installation
26
+
27
+ ```bash
28
+ npm install @agentcreds/sdk
29
+ ```
30
+
31
+ (or, building from source: `npm run build`, which invokes `napi build
32
+ --platform --release`)
33
+
34
+ ## Quick start
35
+
36
+ ```typescript
37
+ import * as ac from "@agentcreds/sdk";
38
+
39
+ // 1. Org trust anchor (in production: keys live in an HSM)
40
+ const anchor = ac.TrustAnchor.generate();
41
+
42
+ // 2. Agent enrolled at deploy time
43
+ const agent = ac.AgentIdentity.createDidKey();
44
+
45
+ // 3. Issue a capability credential
46
+ const claims = new ac.CapabilityClaims({
47
+ tools: ["tool:search", "tool:email"],
48
+ maxDelegationDepth: 3,
49
+ validForSecs: 3600, // valid for 1 hour
50
+ });
51
+ const vc = ac.CapabilityCredential.issue(anchor, agent.did, claims);
52
+
53
+ // 4. Mint a short-lived runtime token (valid 5 minutes)
54
+ const scope = new ac.Scope({ tools: ["tool:search"], budgetUsd: 100, maxDepth: 2 });
55
+ const token = ac.DelegationToken.mint(vc, scope, 300, agent);
56
+
57
+ // 5. Verify at every tool call boundary (<1ms)
58
+ const action = new ac.Action("tool:search", "q=agentcreds");
59
+ token.verify(action);
60
+
61
+ // 6. Delegate to a sub-agent (scope can only narrow)
62
+ const subAgent = ac.AgentIdentity.createDidKey();
63
+ const narrow = new ac.Scope({ tools: ["tool:search"], budgetUsd: 10, maxDepth: 1 });
64
+ const childToken = token.attenuate(narrow, 60, subAgent);
65
+ ```
66
+
67
+ ## Cross-org verification
68
+
69
+ ```typescript
70
+ import * as ac from "@agentcreds/sdk";
71
+
72
+ // Org B registers Org A's trust anchor (resolved from a TRAIL registry in production)
73
+ const registry = new ac.TrustRegistry();
74
+ registry.register(new ac.TrustEntry(
75
+ orgAAnchor.did,
76
+ "Organization A",
77
+ orgAAnchor.publicKey,
78
+ "verified",
79
+ ));
80
+
81
+ // Verify Org A's credential WITHOUT calling back to Org A
82
+ const entry = registry.verifyCredential(vcFromOrgA);
83
+ console.log(`Verified by ${entry.orgName} (${entry.trustLevel})`);
84
+ ```
85
+
86
+ ## Revocation
87
+
88
+ ```typescript
89
+ import * as ac from "@agentcreds/sdk";
90
+
91
+ // Create an OAuth Token Status List (131,072 entries by default)
92
+ const revocationList = new ac.RevocationList("https://registry.example.com/status/1", anchor);
93
+
94
+ // Revoke credential at index 42 (propagates in <30s in production)
95
+ revocationList.revoke(42, anchor);
96
+
97
+ // Check revocation status (<0.1ms, no network call)
98
+ console.assert(revocationList.isRevoked(42));
99
+ ```
100
+
101
+ ## Error handling
102
+
103
+ Every error thrown by this SDK is a JS `Error` whose `message` is prefixed
104
+ with an error kind, mirroring the exception hierarchy of the Python
105
+ bindings (`agentcreds.AgentCredsError` and its subclasses). Branch on the
106
+ prefix with `error.message.startsWith(...)`:
107
+
108
+ ```typescript
109
+ import * as ac from "@agentcreds/sdk";
110
+
111
+ try {
112
+ token.verify(new ac.Action("tool:delete-everything", ""));
113
+ } catch (e) {
114
+ const message = e instanceof Error ? e.message : String(e);
115
+ if (message.startsWith("ActionDeniedError")) {
116
+ console.log(`denied: ${message}`);
117
+ } else if (message.startsWith("TokenExpiredError")) {
118
+ console.log(`expired: ${message}`);
119
+ } else {
120
+ console.log(`other agentcreds error: ${message}`);
121
+ }
122
+ }
123
+ ```
124
+
125
+ | Message prefix | Raised when |
126
+ |---|---|
127
+ | `DidError` | DID resolution, signature, or key-material problems |
128
+ | `CredentialError` | Malformed claims, issuer mismatch, invalid proof |
129
+ | `CredentialExpiredError` | A credential's `expirationDate` has passed |
130
+ | `CredentialRevokedError` | A credential's index is set in a revocation list |
131
+ | `DelegationError` | Token chain integrity / depth-limit problems |
132
+ | `ScopeWideningError` | An attenuation attempt would widen scope |
133
+ | `TokenExpiredError` | A delegation token (or one of its blocks) has expired |
134
+ | `ActionDeniedError` | The requested tool is not in the leaf block's scope |
135
+ | `RevocationError` | Revocation list index out of bounds / bad signature |
136
+ | `SerializationError` | JSON / CBOR / base64 (de)serialization failure |
137
+ | `ValidationError` | A field value is missing, out of bounds, or of the wrong sign (e.g. a negative index) |
138
+
139
+ Arguments rejected directly by the binding layer (e.g. a negative
140
+ `validForSecs`) throw with `error.code === "InvalidArg"`; errors propagated
141
+ from `agentcreds-core` throw with `error.code === "GenericFailure"`. In
142
+ both cases the `message` prefix table above applies.
143
+
144
+ ## Type declarations
145
+
146
+ A hand-written `index.d.ts` ships with this package for editor/IDE
147
+ autocomplete and TypeScript type checking. Running `napi build` regenerates
148
+ this file directly from the Rust `#[napi]` annotations in `src/`.
149
+
150
+ ## Building
151
+
152
+ ```bash
153
+ npm run build # napi build --platform --release
154
+ cargo test --manifest-path ../agentcreds-core/Cargo.toml
155
+ ```
156
+
157
+ ## License
158
+
159
+ Apache-2.0