@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.
- package/LICENSE +10 -0
- package/README.md +159 -0
- package/index.d.ts +1271 -0
- package/index.js +370 -0
- 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
|