@attest-dev/sdk 0.1.0-beta.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 ADDED
@@ -0,0 +1,119 @@
1
+ # @attest-dev/sdk
2
+
3
+ TypeScript SDK for [Attest](https://github.com/attest-dev/attest) — cryptographic credentials for AI agent pipelines.
4
+
5
+ Attest issues RS256-signed JWTs to agents carrying scope, delegation lineage, and task provenance. Every handoff narrows scope, every action is auditable, and the entire task tree can be revoked in one call.
6
+
7
+ > **Beta** — self-host the [Attest server](https://github.com/attest-dev/attest) or point at your own instance. Hosted service coming soon.
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @attest-dev/sdk@beta
13
+ ```
14
+
15
+ ## Quickstart
16
+
17
+ ```ts
18
+ import { AttestClient } from "@attest-dev/sdk";
19
+
20
+ const client = new AttestClient({
21
+ baseUrl: "http://localhost:8080",
22
+ apiKey: "your-api-key",
23
+ });
24
+
25
+ // Issue a root credential for an orchestrator agent
26
+ const { token, claims } = await client.issue({
27
+ agent_id: "orchestrator-v1",
28
+ user_id: "usr_alice",
29
+ scope: ["research:read", "gmail:send"],
30
+ instruction: "Research competitors and email the board",
31
+ });
32
+
33
+ // Delegate a narrowed credential to a sub-agent
34
+ const { token: childToken } = await client.delegate({
35
+ parent_token: token,
36
+ child_agent: "email-agent-v1",
37
+ child_scope: ["gmail:send"], // must be a subset of parent — enforced server-side
38
+ });
39
+
40
+ // Verify offline (no network call after JWKS is fetched once)
41
+ const jwks = await client.fetchJWKS();
42
+ const result = await client.verify(childToken, jwks);
43
+ console.log(result.valid, result.warnings);
44
+
45
+ // Revoke the entire task tree in one call
46
+ await client.revoke(claims.jti);
47
+
48
+ // Retrieve the tamper-evident audit chain
49
+ const chain = await client.audit(claims.att_tid);
50
+ chain.events.forEach(e => console.log(e.event_type, e.jti, e.created_at));
51
+ ```
52
+
53
+ ## MCP middleware
54
+
55
+ Enforce Attest credentials on every tool call in an MCP server — two lines:
56
+
57
+ ```ts
58
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
59
+ import { withAttest } from "@attest-dev/sdk/mcp";
60
+
61
+ const server = new McpServer({ name: "my-tools", version: "1.0.0" });
62
+ const protectedServer = withAttest(server, {
63
+ issuerUri: "http://localhost:8080",
64
+ });
65
+
66
+ // Register tools exactly as before — every call is now credential-gated
67
+ protectedServer.tool("send_email", schema, handler);
68
+ ```
69
+
70
+ Tool names map to scope strings automatically (`send_email` → `email:send`, `read_file` → `file:read`). Override per tool:
71
+
72
+ ```ts
73
+ protectedServer.tool("gh_create_issue", schema, handler, {
74
+ requiredScope: "github:write",
75
+ });
76
+ ```
77
+
78
+ Expose a discovery endpoint so orchestrators know what scopes to request:
79
+
80
+ ```ts
81
+ import { getAttestScopes } from "@attest-dev/sdk/mcp";
82
+
83
+ app.get("/.well-known/attest-scopes", (_req, res) => {
84
+ res.json({ tools: getAttestScopes(protectedServer) });
85
+ });
86
+ ```
87
+
88
+ See [`mcp/README.md`](./mcp/README.md) for the full MCP middleware reference.
89
+
90
+ ## Scope syntax
91
+
92
+ Scopes follow `resource:action`. Either field may be `*` as a wildcard.
93
+
94
+ | Expression | Meaning |
95
+ |---|---|
96
+ | `gmail:send` | Send via Gmail only |
97
+ | `gmail:*` | All Gmail actions |
98
+ | `*:read` | Read access to any resource |
99
+ | `*:*` | Full access (root credentials only) |
100
+
101
+ Delegation enforces that child scope is a strict subset of parent scope — server-side, cryptographically.
102
+
103
+ ## Self-hosting
104
+
105
+ ```bash
106
+ # Clone and start (Docker required)
107
+ git clone https://github.com/attest-dev/attest
108
+ cd attest
109
+ docker compose up
110
+
111
+ # Or run without Docker (ephemeral key, in-memory storage)
112
+ cd server && go run ./cmd/attest
113
+ ```
114
+
115
+ Server starts on `http://localhost:8080`.
116
+
117
+ ## License
118
+
119
+ Apache-2.0
@@ -0,0 +1,127 @@
1
+ /**
2
+ * @attest-dev/sdk — TypeScript client for the Attest credential service.
3
+ *
4
+ * Offline JWT verification uses `jose` (no network call needed after
5
+ * fetchJWKS). All network calls go through the Attest server REST API.
6
+ */
7
+ import { type JWTPayload } from 'jose';
8
+ /** Standard JWT claims plus every att_* Attest extension. */
9
+ export interface AttestClaims extends JWTPayload {
10
+ /** Task tree ID shared across the entire delegation chain. */
11
+ att_tid: string;
12
+ /** Parent credential jti (absent on root credentials). */
13
+ att_pid?: string;
14
+ /** Delegation depth (0 = root). */
15
+ att_depth: number;
16
+ /** Granted permission scopes in "resource:action" form. */
17
+ att_scope: string[];
18
+ /** SHA-256 hex of the original instruction that initiated the task. */
19
+ att_intent: string;
20
+ /** Ordered jti ancestry list from root to this credential. */
21
+ att_chain: string[];
22
+ /** Human principal who initiated the task. */
23
+ att_uid: string;
24
+ }
25
+ /** A root credential returned by issue(). */
26
+ export interface AttestToken {
27
+ token: string;
28
+ claims: AttestClaims;
29
+ }
30
+ /** A delegated child credential returned by delegate(). */
31
+ export interface DelegatedToken {
32
+ token: string;
33
+ claims: AttestClaims;
34
+ }
35
+ /** Returned by verify(). Valid is false if any check fails. */
36
+ export interface VerifyResult {
37
+ valid: boolean;
38
+ claims?: AttestClaims;
39
+ warnings: string[];
40
+ }
41
+ /** A complete audit trail for a task tree. */
42
+ export interface AuditChain {
43
+ taskId: string;
44
+ events: AuditEvent[];
45
+ }
46
+ /** A single entry in the audit log. */
47
+ export interface AuditEvent {
48
+ id?: number;
49
+ prev_hash: string;
50
+ entry_hash: string;
51
+ event_type: 'issued' | 'delegated' | 'verified' | 'revoked' | 'expired';
52
+ jti: string;
53
+ att_tid: string;
54
+ att_uid: string;
55
+ agent_id: string;
56
+ scope: string[];
57
+ meta?: Record<string, string>;
58
+ created_at: string;
59
+ }
60
+ /** Subset of a JWKS response sufficient for RS256 verification. */
61
+ export interface JWKSResponse {
62
+ keys: JWK[];
63
+ }
64
+ export interface JWK {
65
+ kty: string;
66
+ use?: string;
67
+ alg?: string;
68
+ n: string;
69
+ e: string;
70
+ kid?: string;
71
+ }
72
+ /** Parameters for issuing a root credential. */
73
+ export interface IssueParams {
74
+ agent_id: string;
75
+ user_id: string;
76
+ scope: string[];
77
+ instruction: string;
78
+ ttl_seconds?: number;
79
+ }
80
+ /** Parameters for delegating to a child agent. */
81
+ export interface DelegateParams {
82
+ parent_token: string;
83
+ child_agent: string;
84
+ child_scope: string[];
85
+ ttl_seconds?: number;
86
+ }
87
+ export declare class AttestClient {
88
+ private readonly baseUrl;
89
+ private readonly headers;
90
+ constructor({ baseUrl, apiKey }: {
91
+ baseUrl?: string;
92
+ apiKey: string;
93
+ });
94
+ /** Issue a root credential for the given agent and instruction. */
95
+ issue(params: IssueParams): Promise<AttestToken>;
96
+ /** Delegate a narrowed child credential from a parent token. */
97
+ delegate(params: DelegateParams): Promise<DelegatedToken>;
98
+ /**
99
+ * Offline verification — validates RS256 signature, expiry, chain length
100
+ * (must equal depth + 1), and chain tail (must equal jti).
101
+ *
102
+ * Pass a JWKSResponse previously fetched with fetchJWKS(). No network call
103
+ * is made during verification itself.
104
+ */
105
+ verify(token: string, jwks: JWKSResponse): Promise<VerifyResult>;
106
+ /** Revoke a credential and cascade to all descendants. */
107
+ revoke(jti: string, revokedBy?: string): Promise<void>;
108
+ /** Fetch the full audit chain for a task tree. */
109
+ audit(taskId: string): Promise<AuditChain>;
110
+ /** Fetch the server's public key set for offline verification. */
111
+ fetchJWKS(): Promise<JWKSResponse>;
112
+ }
113
+ /**
114
+ * Returns true if every entry in childScope is covered by at least one entry
115
+ * in parentScope. Wildcards ("*") match any resource or action.
116
+ *
117
+ * @example
118
+ * isScopeSubset(["gmail:*"], ["gmail:send"]) // true
119
+ * isScopeSubset(["gmail:send"], ["database:delete"]) // false
120
+ */
121
+ export declare function isScopeSubset(parentScope: string[], childScope: string[]): boolean;
122
+ /**
123
+ * Decodes a Attest JWT without verifying the signature.
124
+ * Use verify() for trusted access to claims.
125
+ */
126
+ export declare function decodeToken(token: string): AttestClaims;
127
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ /**
3
+ * @attest-dev/sdk — TypeScript client for the Attest credential service.
4
+ *
5
+ * Offline JWT verification uses `jose` (no network call needed after
6
+ * fetchJWKS). All network calls go through the Attest server REST API.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.AttestClient = void 0;
10
+ exports.isScopeSubset = isScopeSubset;
11
+ exports.decodeToken = decodeToken;
12
+ const jose_1 = require("jose");
13
+ // ── AttestClient ─────────────────────────────────────────────────────────────
14
+ class AttestClient {
15
+ baseUrl;
16
+ headers;
17
+ constructor({ baseUrl = 'http://localhost:8080', apiKey }) {
18
+ this.baseUrl = baseUrl.replace(/\/$/, '');
19
+ this.headers = {
20
+ 'Content-Type': 'application/json',
21
+ Authorization: `Bearer ${apiKey}`,
22
+ };
23
+ }
24
+ /** Issue a root credential for the given agent and instruction. */
25
+ async issue(params) {
26
+ const res = await fetch(`${this.baseUrl}/v1/credentials`, {
27
+ method: 'POST',
28
+ headers: this.headers,
29
+ body: JSON.stringify(params),
30
+ });
31
+ if (!res.ok)
32
+ await throwFromResponse(res);
33
+ return res.json();
34
+ }
35
+ /** Delegate a narrowed child credential from a parent token. */
36
+ async delegate(params) {
37
+ const res = await fetch(`${this.baseUrl}/v1/credentials/delegate`, {
38
+ method: 'POST',
39
+ headers: this.headers,
40
+ body: JSON.stringify(params),
41
+ });
42
+ if (!res.ok)
43
+ await throwFromResponse(res);
44
+ return res.json();
45
+ }
46
+ /**
47
+ * Offline verification — validates RS256 signature, expiry, chain length
48
+ * (must equal depth + 1), and chain tail (must equal jti).
49
+ *
50
+ * Pass a JWKSResponse previously fetched with fetchJWKS(). No network call
51
+ * is made during verification itself.
52
+ */
53
+ async verify(token, jwks) {
54
+ const warnings = [];
55
+ // Build a JWKS key source from the raw key objects by round-tripping
56
+ // through a data URL so jose can parse it without a network request.
57
+ const jwksData = JSON.stringify(jwks);
58
+ const dataUrl = `data:application/json,${encodeURIComponent(jwksData)}`;
59
+ let payload;
60
+ try {
61
+ const keySet = (0, jose_1.createRemoteJWKSet)(new URL(dataUrl));
62
+ const { payload: raw } = await (0, jose_1.jwtVerify)(token, keySet, {
63
+ algorithms: ['RS256'],
64
+ });
65
+ payload = raw;
66
+ }
67
+ catch (err) {
68
+ return { valid: false, warnings: [`signature/expiry check failed: ${String(err)}`] };
69
+ }
70
+ // Chain length must equal depth + 1 (root depth=0 → chain=[jti]).
71
+ const expectedLen = (payload.att_depth ?? 0) + 1;
72
+ if (!payload.att_chain || payload.att_chain.length !== expectedLen) {
73
+ warnings.push(`chain length ${payload.att_chain?.length} does not match depth ${payload.att_depth} (expected ${expectedLen})`);
74
+ }
75
+ // Chain tail must match jti.
76
+ const chain = payload.att_chain ?? [];
77
+ if (chain.length > 0 && chain[chain.length - 1] !== payload.jti) {
78
+ warnings.push(`chain tail "${chain[chain.length - 1]}" does not match jti "${payload.jti}"`);
79
+ }
80
+ return {
81
+ valid: warnings.length === 0,
82
+ claims: payload,
83
+ warnings,
84
+ };
85
+ }
86
+ /** Revoke a credential and cascade to all descendants. */
87
+ async revoke(jti, revokedBy = 'sdk') {
88
+ const res = await fetch(`${this.baseUrl}/v1/credentials/${encodeURIComponent(jti)}`, {
89
+ method: 'DELETE',
90
+ headers: this.headers,
91
+ body: JSON.stringify({ revoked_by: revokedBy }),
92
+ });
93
+ if (!res.ok && res.status !== 204)
94
+ await throwFromResponse(res);
95
+ }
96
+ /** Fetch the full audit chain for a task tree. */
97
+ async audit(taskId) {
98
+ const res = await fetch(`${this.baseUrl}/v1/tasks/${encodeURIComponent(taskId)}/audit`, { headers: this.headers });
99
+ if (!res.ok)
100
+ await throwFromResponse(res);
101
+ const events = (await res.json());
102
+ return { taskId, events };
103
+ }
104
+ /** Fetch the server's public key set for offline verification. */
105
+ async fetchJWKS() {
106
+ const res = await fetch(`${this.baseUrl}/.well-known/jwks.json`, {
107
+ headers: this.headers,
108
+ });
109
+ if (!res.ok)
110
+ await throwFromResponse(res);
111
+ return res.json();
112
+ }
113
+ }
114
+ exports.AttestClient = AttestClient;
115
+ // ── Exported utilities ────────────────────────────────────────────────────────
116
+ /**
117
+ * Returns true if every entry in childScope is covered by at least one entry
118
+ * in parentScope. Wildcards ("*") match any resource or action.
119
+ *
120
+ * @example
121
+ * isScopeSubset(["gmail:*"], ["gmail:send"]) // true
122
+ * isScopeSubset(["gmail:send"], ["database:delete"]) // false
123
+ */
124
+ function isScopeSubset(parentScope, childScope) {
125
+ for (const childEntry of childScope) {
126
+ const child = parseScope(childEntry);
127
+ if (!child)
128
+ return false;
129
+ const covered = parentScope.some(parentEntry => {
130
+ const parent = parseScope(parentEntry);
131
+ if (!parent)
132
+ return false;
133
+ const resourceOK = parent.resource === '*' || parent.resource === child.resource;
134
+ const actionOK = parent.action === '*' || parent.action === child.action;
135
+ return resourceOK && actionOK;
136
+ });
137
+ if (!covered)
138
+ return false;
139
+ }
140
+ return true;
141
+ }
142
+ /**
143
+ * Decodes a Attest JWT without verifying the signature.
144
+ * Use verify() for trusted access to claims.
145
+ */
146
+ function decodeToken(token) {
147
+ return (0, jose_1.decodeJwt)(token);
148
+ }
149
+ function parseScope(s) {
150
+ const parts = s.split(':');
151
+ if (parts.length !== 2 || !parts[0] || !parts[1])
152
+ return null;
153
+ return { resource: parts[0], action: parts[1] };
154
+ }
155
+ async function throwFromResponse(res) {
156
+ let message = `HTTP ${res.status}`;
157
+ try {
158
+ const body = (await res.json());
159
+ if (body.error)
160
+ message += `: ${body.error}`;
161
+ }
162
+ catch {
163
+ // ignore parse failure
164
+ }
165
+ throw new Error(message);
166
+ }
167
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}