@alter-ai/alter-sdk 0.2.1 → 0.3.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 +145 -51
- package/dist/index.cjs +315 -53
- package/dist/index.d.cts +262 -137
- package/dist/index.d.ts +262 -137
- package/dist/index.js +311 -53
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# Alter SDK for TypeScript / Node.js
|
|
2
2
|
|
|
3
|
-
Official TypeScript SDK for [Alter Vault](https://alterai.dev) —
|
|
3
|
+
Official TypeScript SDK for [Alter Vault](https://alterai.dev) — Credential management for agents with policy enforcement.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
7
|
- **Zero Token Exposure**: Tokens are never exposed to developers — injected automatically
|
|
8
8
|
- **Single Entry Point**: One method (`vault.request()`) for all provider APIs
|
|
9
|
-
- **Type-Safe Enums**: `
|
|
9
|
+
- **Type-Safe Enums**: `HttpMethod` enums with autocomplete
|
|
10
10
|
- **URL Templating**: Path parameter substitution with automatic URL encoding
|
|
11
|
-
- **Automatic Audit Logging**: All API calls logged
|
|
11
|
+
- **Automatic Audit Logging**: All API calls logged with request metadata (HTTP method and URL) for full audit trail
|
|
12
12
|
- **Real-time Policy Enforcement**: Every token request checked against current policies
|
|
13
13
|
- **Automatic Token Refresh**: Tokens refreshed transparently by the backend
|
|
14
|
+
- **API Key and Custom Credential Support**: Handles OAuth tokens, API keys, and custom credential formats automatically
|
|
14
15
|
- **Actor Tracking**: First-class support for AI agent and MCP server observability
|
|
16
|
+
- **HMAC Request Signing**: All SDK-to-backend requests are signed with a derived HMAC-SHA256 key for integrity, authenticity, and replay protection
|
|
15
17
|
- **Native Promises**: Built on native `fetch` — no heavy dependencies
|
|
16
18
|
|
|
17
19
|
## Installation
|
|
@@ -23,17 +25,20 @@ npm install @alter-ai/alter-sdk
|
|
|
23
25
|
## Quick Start
|
|
24
26
|
|
|
25
27
|
```typescript
|
|
26
|
-
import { AlterVault, Provider, HttpMethod } from "@alter-ai/alter-sdk";
|
|
28
|
+
import { AlterVault, ActorType, Provider, HttpMethod } from "@alter-ai/alter-sdk";
|
|
27
29
|
|
|
28
|
-
const vault = new AlterVault({
|
|
30
|
+
const vault = new AlterVault({
|
|
31
|
+
apiKey: "alter_key_...",
|
|
32
|
+
actorType: ActorType.AI_AGENT,
|
|
33
|
+
actorIdentifier: "my-agent",
|
|
34
|
+
});
|
|
29
35
|
|
|
30
36
|
// Make API request — token injected automatically, never exposed
|
|
31
37
|
const response = await vault.request(
|
|
32
|
-
|
|
38
|
+
"CONNECTION_ID", // from Alter Connect (see below)
|
|
33
39
|
HttpMethod.GET,
|
|
34
40
|
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
35
41
|
{
|
|
36
|
-
user: { user_id: "alice" },
|
|
37
42
|
queryParams: { maxResults: "10" },
|
|
38
43
|
},
|
|
39
44
|
);
|
|
@@ -44,16 +49,38 @@ console.log(events);
|
|
|
44
49
|
await vault.close();
|
|
45
50
|
```
|
|
46
51
|
|
|
52
|
+
### Where does `connectionId` come from?
|
|
53
|
+
|
|
54
|
+
**OAuth connections:**
|
|
55
|
+
1. User completes OAuth via [Alter Connect](https://docs.alterai.dev/sdks/javascript/quickstart) (frontend widget)
|
|
56
|
+
2. The `onSuccess` callback returns a `connectionId` (UUID)
|
|
57
|
+
3. You save it in your database, mapped to your user
|
|
58
|
+
4. You pass it to `vault.request()` when making API calls
|
|
59
|
+
|
|
60
|
+
**Managed secrets** (API keys, service tokens):
|
|
61
|
+
1. Store credentials in the [Developer Portal](https://portal.alterai.dev) under **Managed Secrets**
|
|
62
|
+
2. Copy the `connectionId` returned
|
|
63
|
+
3. Use the same `vault.request()` — credentials are injected automatically
|
|
64
|
+
|
|
65
|
+
```typescript
|
|
66
|
+
// You can also discover connectionIds programmatically:
|
|
67
|
+
const result = await vault.listConnections({ providerId: "google" });
|
|
68
|
+
for (const conn of result.connections) {
|
|
69
|
+
console.log(`${conn.id}: ${conn.accountDisplayName}`);
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
47
73
|
## Usage
|
|
48
74
|
|
|
75
|
+
The `request()` method returns the raw `Response` object. The token is injected automatically and never exposed. The backend token response includes `connectionId` and `providerId` for audit correlation.
|
|
76
|
+
|
|
49
77
|
### Simple GET Request
|
|
50
78
|
|
|
51
79
|
```typescript
|
|
52
80
|
const response = await vault.request(
|
|
53
|
-
|
|
81
|
+
connectionId,
|
|
54
82
|
HttpMethod.GET,
|
|
55
83
|
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
56
|
-
{ user: { user_id: "alice" } },
|
|
57
84
|
);
|
|
58
85
|
```
|
|
59
86
|
|
|
@@ -61,11 +88,10 @@ const response = await vault.request(
|
|
|
61
88
|
|
|
62
89
|
```typescript
|
|
63
90
|
const response = await vault.request(
|
|
64
|
-
|
|
91
|
+
connectionId,
|
|
65
92
|
HttpMethod.POST,
|
|
66
93
|
"https://api.example.com/v1/items",
|
|
67
94
|
{
|
|
68
|
-
user: { user_id: "alice" },
|
|
69
95
|
json: { name: "New Item", price: 99.99 },
|
|
70
96
|
reason: "Creating new item",
|
|
71
97
|
},
|
|
@@ -76,11 +102,10 @@ const response = await vault.request(
|
|
|
76
102
|
|
|
77
103
|
```typescript
|
|
78
104
|
const response = await vault.request(
|
|
79
|
-
|
|
105
|
+
connectionId,
|
|
80
106
|
HttpMethod.PUT,
|
|
81
107
|
"https://api.example.com/v1/items/{item_id}",
|
|
82
108
|
{
|
|
83
|
-
user: { user_id: "alice" },
|
|
84
109
|
pathParams: { item_id: "123" },
|
|
85
110
|
json: { price: 89.99 },
|
|
86
111
|
},
|
|
@@ -91,11 +116,10 @@ const response = await vault.request(
|
|
|
91
116
|
|
|
92
117
|
```typescript
|
|
93
118
|
const response = await vault.request(
|
|
94
|
-
|
|
119
|
+
connectionId,
|
|
95
120
|
HttpMethod.POST,
|
|
96
121
|
"https://api.notion.com/v1/databases/{db_id}/query",
|
|
97
122
|
{
|
|
98
|
-
user: { user_id: "alice" },
|
|
99
123
|
pathParams: { db_id: "abc123" },
|
|
100
124
|
extraHeaders: { "Notion-Version": "2022-06-28" },
|
|
101
125
|
json: { page_size: 10 },
|
|
@@ -103,12 +127,87 @@ const response = await vault.request(
|
|
|
103
127
|
);
|
|
104
128
|
```
|
|
105
129
|
|
|
130
|
+
### Using Managed Secrets
|
|
131
|
+
|
|
132
|
+
For your own APIs with API keys or service tokens (no OAuth flow needed):
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
const vault = new AlterVault({
|
|
136
|
+
apiKey: "alter_key_...",
|
|
137
|
+
actorType: ActorType.BACKEND_SERVICE,
|
|
138
|
+
actorIdentifier: "my-service",
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
const response = await vault.request(
|
|
142
|
+
"MANAGED_SECRET_CONNECTION_ID", // from Developer Portal
|
|
143
|
+
HttpMethod.GET,
|
|
144
|
+
"https://api.internal.com/v1/data",
|
|
145
|
+
);
|
|
146
|
+
|
|
147
|
+
await vault.close();
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
The credential is injected automatically as the configured header type (Bearer, API Key, Basic Auth).
|
|
151
|
+
|
|
152
|
+
### Connection Management
|
|
153
|
+
|
|
154
|
+
#### List Connections
|
|
155
|
+
|
|
156
|
+
Retrieve OAuth connections for your app, optionally filtered by provider:
|
|
157
|
+
|
|
158
|
+
```typescript
|
|
159
|
+
const result = await vault.listConnections();
|
|
160
|
+
for (const conn of result.connections) {
|
|
161
|
+
console.log(`${conn.providerId}: ${conn.accountDisplayName} (${conn.status})`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Filter by provider with pagination
|
|
165
|
+
const googleConns = await vault.listConnections({
|
|
166
|
+
providerId: "google",
|
|
167
|
+
limit: 10,
|
|
168
|
+
offset: 0,
|
|
169
|
+
});
|
|
170
|
+
console.log(`Total: ${googleConns.total}, Has more: ${googleConns.hasMore}`);
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
| Parameter | Type | Default | Description |
|
|
174
|
+
|-----------|------|---------|-------------|
|
|
175
|
+
| `providerId` | `string` | - | Filter by provider (e.g., `"google"`) |
|
|
176
|
+
| `limit` | `number` | `100` | Max connections to return |
|
|
177
|
+
| `offset` | `number` | `0` | Pagination offset |
|
|
178
|
+
|
|
179
|
+
Returns `ConnectionListResult` with: `connections` (`ConnectionInfo[]`), `total`, `limit`, `offset`, `hasMore`.
|
|
180
|
+
|
|
181
|
+
#### Create Connect Session
|
|
182
|
+
|
|
183
|
+
Generate a session URL for end-users to authenticate with OAuth providers:
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const session = await vault.createConnectSession({
|
|
187
|
+
endUser: { id: "alice" },
|
|
188
|
+
allowedProviders: ["google", "github"],
|
|
189
|
+
returnUrl: "https://myapp.com/callback",
|
|
190
|
+
});
|
|
191
|
+
console.log(`Connect URL: ${session.connectUrl}`);
|
|
192
|
+
console.log(`Expires in: ${session.expiresIn}s`);
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
| Parameter | Type | Default | Description |
|
|
196
|
+
|-----------|------|---------|-------------|
|
|
197
|
+
| `endUser` | `{ id: string }` | *required* | End user identity |
|
|
198
|
+
| `allowedProviders` | `string[]` | - | Restrict to specific providers |
|
|
199
|
+
| `returnUrl` | `string` | - | Redirect URL after OAuth flow |
|
|
200
|
+
|
|
201
|
+
Returns `ConnectSession` with: `sessionToken`, `connectUrl`, `expiresIn`, `expiresAt`.
|
|
202
|
+
|
|
106
203
|
### AI Agent Actor Tracking
|
|
107
204
|
|
|
108
205
|
```typescript
|
|
206
|
+
import { AlterVault, ActorType, Provider, HttpMethod } from "@alter-ai/alter-sdk";
|
|
207
|
+
|
|
109
208
|
const vault = new AlterVault({
|
|
110
209
|
apiKey: "alter_key_...",
|
|
111
|
-
actorType:
|
|
210
|
+
actorType: ActorType.AI_AGENT,
|
|
112
211
|
actorIdentifier: "email-assistant-v2",
|
|
113
212
|
actorName: "Email Assistant",
|
|
114
213
|
actorVersion: "2.0.0",
|
|
@@ -116,18 +215,19 @@ const vault = new AlterVault({
|
|
|
116
215
|
});
|
|
117
216
|
|
|
118
217
|
const response = await vault.request(
|
|
119
|
-
|
|
218
|
+
connectionId,
|
|
120
219
|
HttpMethod.GET,
|
|
121
220
|
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
122
221
|
{
|
|
123
|
-
|
|
124
|
-
runId: "550e8400-e29b-41d4-a716-446655440000",
|
|
222
|
+
runId: "550e8400-e29b-41d4-a716-446655440000", // auto-generated UUID if omitted
|
|
125
223
|
threadId: "thread-xyz",
|
|
126
224
|
toolCallId: "call_abc_123",
|
|
127
225
|
},
|
|
128
226
|
);
|
|
129
227
|
```
|
|
130
228
|
|
|
229
|
+
> **Note**: `runId` is auto-generated as a UUID v4 if not provided. All sub-actions within a single `request()` call share the same `runId` for audit log grouping.
|
|
230
|
+
|
|
131
231
|
### Multi-Agent Deployments
|
|
132
232
|
|
|
133
233
|
Each agent must create its own `AlterVault` instance with a unique actor identity. Do not share a single instance across agents.
|
|
@@ -136,29 +236,28 @@ Each agent must create its own `AlterVault` instance with a unique actor identit
|
|
|
136
236
|
// Each agent gets its own vault instance
|
|
137
237
|
const emailAgent = new AlterVault({
|
|
138
238
|
apiKey: "alter_key_...",
|
|
139
|
-
actorType:
|
|
239
|
+
actorType: ActorType.AI_AGENT,
|
|
140
240
|
actorIdentifier: "email-assistant-v2",
|
|
141
241
|
actorName: "Email Assistant",
|
|
142
242
|
});
|
|
143
243
|
|
|
144
244
|
const calendarAgent = new AlterVault({
|
|
145
245
|
apiKey: "alter_key_...",
|
|
146
|
-
actorType:
|
|
246
|
+
actorType: ActorType.AI_AGENT,
|
|
147
247
|
actorIdentifier: "calendar-agent-v1",
|
|
148
248
|
actorName: "Calendar Agent",
|
|
149
249
|
});
|
|
150
250
|
|
|
151
251
|
// Audit logs and policies are tracked per agent
|
|
152
|
-
const user = { user_id: "alice" };
|
|
153
252
|
await emailAgent.request(
|
|
154
|
-
|
|
253
|
+
gmailConnectionId, // from Alter Connect
|
|
254
|
+
HttpMethod.GET,
|
|
155
255
|
"https://gmail.googleapis.com/gmail/v1/users/me/messages",
|
|
156
|
-
{ user },
|
|
157
256
|
);
|
|
158
257
|
await calendarAgent.request(
|
|
159
|
-
|
|
258
|
+
calendarConnectionId, // from Alter Connect
|
|
259
|
+
HttpMethod.GET,
|
|
160
260
|
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
161
|
-
{ user },
|
|
162
261
|
);
|
|
163
262
|
|
|
164
263
|
// Clean up each instance
|
|
@@ -169,30 +268,29 @@ await calendarAgent.close();
|
|
|
169
268
|
## Configuration
|
|
170
269
|
|
|
171
270
|
```typescript
|
|
271
|
+
import { AlterVault, ActorType } from "@alter-ai/alter-sdk";
|
|
272
|
+
|
|
172
273
|
const vault = new AlterVault({
|
|
173
274
|
apiKey: "alter_key_...", // Required: Alter Vault API key
|
|
174
|
-
|
|
275
|
+
actorType: ActorType.AI_AGENT, // Required: ActorType enum
|
|
276
|
+
actorIdentifier: "my-agent", // Required: Unique identifier
|
|
175
277
|
timeout: 30000, // Optional: HTTP timeout in ms (default: 30000)
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
actorVersion: "1.0.0", // Version string
|
|
181
|
-
framework: "langgraph", // AI framework
|
|
182
|
-
clientType: "cursor", // MCP client type
|
|
278
|
+
actorName: "My Agent", // Optional: Human-readable name
|
|
279
|
+
actorVersion: "1.0.0", // Optional: Version string
|
|
280
|
+
framework: "langgraph", // Optional: AI framework
|
|
281
|
+
clientType: "cursor", // Optional: MCP client type
|
|
183
282
|
});
|
|
184
283
|
```
|
|
185
284
|
|
|
186
285
|
## Error Handling
|
|
187
286
|
|
|
188
|
-
> **Note:** Input validation errors (invalid `apiKey`, invalid `actorType`, invalid URL scheme, missing `pathParams`) throw `AlterSDKError`.
|
|
287
|
+
> **Note:** Input validation errors (invalid `apiKey`, invalid/missing `actorType`, missing `actorIdentifier`, invalid URL scheme, missing `pathParams`) throw `AlterSDKError`.
|
|
189
288
|
|
|
190
289
|
```typescript
|
|
191
290
|
import {
|
|
192
291
|
AlterVault,
|
|
193
|
-
Provider,
|
|
194
292
|
HttpMethod,
|
|
195
|
-
AlterSDKError, // Base error (including validation: apiKey, actorType, URL scheme, pathParams)
|
|
293
|
+
AlterSDKError, // Base error (including validation: apiKey, actorType, actorIdentifier, URL scheme, pathParams)
|
|
196
294
|
PolicyViolationError,
|
|
197
295
|
ConnectionNotFoundError,
|
|
198
296
|
TokenExpiredError,
|
|
@@ -204,10 +302,9 @@ import {
|
|
|
204
302
|
|
|
205
303
|
try {
|
|
206
304
|
const response = await vault.request(
|
|
207
|
-
|
|
305
|
+
connectionId,
|
|
208
306
|
HttpMethod.GET,
|
|
209
307
|
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
210
|
-
{ user: { user_id: "alice" } },
|
|
211
308
|
);
|
|
212
309
|
} catch (error) {
|
|
213
310
|
if (error instanceof PolicyViolationError) {
|
|
@@ -230,7 +327,11 @@ try {
|
|
|
230
327
|
|
|
231
328
|
```typescript
|
|
232
329
|
// Manual cleanup (recommended)
|
|
233
|
-
const vault = new AlterVault({
|
|
330
|
+
const vault = new AlterVault({
|
|
331
|
+
apiKey: "alter_key_...",
|
|
332
|
+
actorType: ActorType.BACKEND_SERVICE,
|
|
333
|
+
actorIdentifier: "my-service",
|
|
334
|
+
});
|
|
234
335
|
try {
|
|
235
336
|
const response = await vault.request(...);
|
|
236
337
|
} finally {
|
|
@@ -243,18 +344,11 @@ try {
|
|
|
243
344
|
|
|
244
345
|
## Supported Providers
|
|
245
346
|
|
|
246
|
-
|
|
247
|
-
import { Provider } from "@alter-ai/alter-sdk";
|
|
248
|
-
|
|
249
|
-
Provider.GOOGLE // "google"
|
|
250
|
-
Provider.GITHUB // "github"
|
|
251
|
-
Provider.SLACK // "slack"
|
|
252
|
-
Provider.MICROSOFT // "microsoft"
|
|
253
|
-
Provider.SALESFORCE // "salesforce"
|
|
254
|
-
Provider.SENTRY // "sentry"
|
|
347
|
+
The SDK works with any OAuth provider configured in your Alter Vault dashboard. The first parameter to `vault.request()` is the `connection_id` (UUID) returned when a user connects via Alter Connect.
|
|
255
348
|
|
|
256
|
-
|
|
257
|
-
|
|
349
|
+
```typescript
|
|
350
|
+
// Use the connection_id from Alter Connect
|
|
351
|
+
await vault.request("550e8400-e29b-41d4-a716-446655440000", HttpMethod.GET, url);
|
|
258
352
|
```
|
|
259
353
|
|
|
260
354
|
## Requirements
|