@alter-ai/alter-sdk 0.2.0 → 0.2.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 +57 -24
- package/dist/index.cjs +2 -7
- package/dist/index.d.cts +5 -26
- package/dist/index.d.ts +5 -26
- package/dist/index.js +2 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# Alter SDK for TypeScript / Node.js
|
|
2
2
|
|
|
3
|
-
> **Version**: 0.4.0
|
|
4
|
-
|
|
5
3
|
Official TypeScript SDK for [Alter Vault](https://alterai.dev) — OAuth token management with policy enforcement.
|
|
6
4
|
|
|
7
5
|
## Features
|
|
@@ -13,8 +11,6 @@ Official TypeScript SDK for [Alter Vault](https://alterai.dev) — OAuth token m
|
|
|
13
11
|
- **Automatic Audit Logging**: All API calls logged as fire-and-forget background tasks
|
|
14
12
|
- **Real-time Policy Enforcement**: Every token request checked against current policies
|
|
15
13
|
- **Automatic Token Refresh**: Tokens refreshed transparently by the backend
|
|
16
|
-
- **Dual HTTP Client Security**: Separate clients prevent credential leakage to providers
|
|
17
|
-
- **Security Hardened (v0.4.0)**: Frozen `HttpClient` prototype, `WeakMap` token storage, unexported module-private token accessors, and hardened `fetch` capture prevent rogue agent token extraction
|
|
18
14
|
- **Actor Tracking**: First-class support for AI agent and MCP server observability
|
|
19
15
|
- **Native Promises**: Built on native `fetch` — no heavy dependencies
|
|
20
16
|
|
|
@@ -95,13 +91,14 @@ const response = await vault.request(
|
|
|
95
91
|
|
|
96
92
|
```typescript
|
|
97
93
|
const response = await vault.request(
|
|
98
|
-
|
|
99
|
-
HttpMethod.
|
|
100
|
-
"https://api.
|
|
94
|
+
"notion",
|
|
95
|
+
HttpMethod.POST,
|
|
96
|
+
"https://api.notion.com/v1/databases/{db_id}/query",
|
|
101
97
|
{
|
|
102
98
|
user: { user_id: "alice" },
|
|
103
|
-
|
|
99
|
+
pathParams: { db_id: "abc123" },
|
|
104
100
|
extraHeaders: { "Notion-Version": "2022-06-28" },
|
|
101
|
+
json: { page_size: 10 },
|
|
105
102
|
},
|
|
106
103
|
);
|
|
107
104
|
```
|
|
@@ -126,17 +123,55 @@ const response = await vault.request(
|
|
|
126
123
|
user: { user_id: "alice" },
|
|
127
124
|
runId: "550e8400-e29b-41d4-a716-446655440000",
|
|
128
125
|
threadId: "thread-xyz",
|
|
126
|
+
toolCallId: "call_abc_123",
|
|
129
127
|
},
|
|
130
128
|
);
|
|
131
129
|
```
|
|
132
130
|
|
|
131
|
+
### Multi-Agent Deployments
|
|
132
|
+
|
|
133
|
+
Each agent must create its own `AlterVault` instance with a unique actor identity. Do not share a single instance across agents.
|
|
134
|
+
|
|
135
|
+
```typescript
|
|
136
|
+
// Each agent gets its own vault instance
|
|
137
|
+
const emailAgent = new AlterVault({
|
|
138
|
+
apiKey: "alter_key_...",
|
|
139
|
+
actorType: "ai_agent",
|
|
140
|
+
actorIdentifier: "email-assistant-v2",
|
|
141
|
+
actorName: "Email Assistant",
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
const calendarAgent = new AlterVault({
|
|
145
|
+
apiKey: "alter_key_...",
|
|
146
|
+
actorType: "ai_agent",
|
|
147
|
+
actorIdentifier: "calendar-agent-v1",
|
|
148
|
+
actorName: "Calendar Agent",
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// Audit logs and policies are tracked per agent
|
|
152
|
+
const user = { user_id: "alice" };
|
|
153
|
+
await emailAgent.request(
|
|
154
|
+
Provider.GOOGLE, HttpMethod.GET,
|
|
155
|
+
"https://gmail.googleapis.com/gmail/v1/users/me/messages",
|
|
156
|
+
{ user },
|
|
157
|
+
);
|
|
158
|
+
await calendarAgent.request(
|
|
159
|
+
Provider.GOOGLE, HttpMethod.GET,
|
|
160
|
+
"https://www.googleapis.com/calendar/v3/calendars/primary/events",
|
|
161
|
+
{ user },
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
// Clean up each instance
|
|
165
|
+
await emailAgent.close();
|
|
166
|
+
await calendarAgent.close();
|
|
167
|
+
```
|
|
168
|
+
|
|
133
169
|
## Configuration
|
|
134
170
|
|
|
135
171
|
```typescript
|
|
136
172
|
const vault = new AlterVault({
|
|
137
173
|
apiKey: "alter_key_...", // Required: Alter Vault API key
|
|
138
174
|
baseUrl: "https://api.alter.com", // Optional: Custom API URL
|
|
139
|
-
enableAuditLogging: true, // Optional: Enable audit logs (default: true)
|
|
140
175
|
timeout: 30000, // Optional: HTTP timeout in ms (default: 30000)
|
|
141
176
|
// Actor tracking (optional)
|
|
142
177
|
actorType: "ai_agent", // "ai_agent" or "mcp_server"
|
|
@@ -150,14 +185,14 @@ const vault = new AlterVault({
|
|
|
150
185
|
|
|
151
186
|
## Error Handling
|
|
152
187
|
|
|
153
|
-
> **Note:** Input validation errors (invalid `apiKey`, invalid `actorType`,
|
|
188
|
+
> **Note:** Input validation errors (invalid `apiKey`, invalid `actorType`, invalid URL scheme, missing `pathParams`) throw `AlterSDKError`.
|
|
154
189
|
|
|
155
190
|
```typescript
|
|
156
191
|
import {
|
|
157
192
|
AlterVault,
|
|
158
193
|
Provider,
|
|
159
194
|
HttpMethod,
|
|
160
|
-
AlterSDKError, // Base error (including validation: apiKey, actorType,
|
|
195
|
+
AlterSDKError, // Base error (including validation: apiKey, actorType, URL scheme, pathParams)
|
|
161
196
|
PolicyViolationError,
|
|
162
197
|
ConnectionNotFoundError,
|
|
163
198
|
TokenExpiredError,
|
|
@@ -206,22 +241,20 @@ try {
|
|
|
206
241
|
// Calling request() after close() throws AlterSDKError
|
|
207
242
|
```
|
|
208
243
|
|
|
209
|
-
##
|
|
244
|
+
## Supported Providers
|
|
210
245
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
- Zero token exposure design
|
|
214
|
-
- No SDK-side caching (real-time policy enforcement)
|
|
215
|
-
- SSRF prevention with case-insensitive URL scheme validation
|
|
216
|
-
- Actor tracking and audit logging
|
|
246
|
+
```typescript
|
|
247
|
+
import { Provider } from "@alter-ai/alter-sdk";
|
|
217
248
|
|
|
218
|
-
|
|
249
|
+
Provider.GOOGLE // "google"
|
|
250
|
+
Provider.GITHUB // "github"
|
|
251
|
+
Provider.SLACK // "slack"
|
|
252
|
+
Provider.MICROSOFT // "microsoft"
|
|
253
|
+
Provider.SALESFORCE // "salesforce"
|
|
254
|
+
Provider.SENTRY // "sentry"
|
|
219
255
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
npm run test # Run tests (70 tests)
|
|
223
|
-
npm run typecheck # Type check
|
|
224
|
-
npm run build # Build for distribution
|
|
256
|
+
// Strings also work for any provider
|
|
257
|
+
await vault.request("notion", HttpMethod.GET, url, { user });
|
|
225
258
|
```
|
|
226
259
|
|
|
227
260
|
## Requirements
|
package/dist/index.cjs
CHANGED
|
@@ -276,7 +276,7 @@ function _extractAccessToken(token) {
|
|
|
276
276
|
return value;
|
|
277
277
|
}
|
|
278
278
|
var _fetch;
|
|
279
|
-
var SDK_VERSION = "0.2.
|
|
279
|
+
var SDK_VERSION = "0.2.1";
|
|
280
280
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
281
281
|
var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
|
|
282
282
|
var HTTP_FORBIDDEN = 403;
|
|
@@ -372,7 +372,6 @@ var AlterVault = class _AlterVault {
|
|
|
372
372
|
// Public readonly properties (frozen by Object.freeze)
|
|
373
373
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
374
374
|
baseUrl;
|
|
375
|
-
enableAuditLogging;
|
|
376
375
|
/** Actor tracking configuration (readonly, not secret) */
|
|
377
376
|
#actorType;
|
|
378
377
|
#actorIdentifier;
|
|
@@ -400,7 +399,6 @@ var AlterVault = class _AlterVault {
|
|
|
400
399
|
/\/+$/,
|
|
401
400
|
""
|
|
402
401
|
);
|
|
403
|
-
this.enableAuditLogging = options.enableAuditLogging ?? true;
|
|
404
402
|
const timeoutMs = options.timeout ?? 3e4;
|
|
405
403
|
this.#actorType = options.actorType;
|
|
406
404
|
this.#actorIdentifier = options.actorIdentifier;
|
|
@@ -678,9 +676,6 @@ var AlterVault = class _AlterVault {
|
|
|
678
676
|
* if audit logging fails.
|
|
679
677
|
*/
|
|
680
678
|
async #logApiCall(params) {
|
|
681
|
-
if (!this.enableAuditLogging) {
|
|
682
|
-
return;
|
|
683
|
-
}
|
|
684
679
|
try {
|
|
685
680
|
const auditLog = new APICallAuditLog({
|
|
686
681
|
connectionId: params.connectionId,
|
|
@@ -765,7 +760,7 @@ var AlterVault = class _AlterVault {
|
|
|
765
760
|
* 1. Fetches an OAuth token from Alter backend (never exposed)
|
|
766
761
|
* 2. Injects the token as a Bearer header
|
|
767
762
|
* 3. Calls the provider API
|
|
768
|
-
* 4. Logs the call for audit (
|
|
763
|
+
* 4. Logs the call for audit (fire-and-forget)
|
|
769
764
|
* 5. Returns the raw response
|
|
770
765
|
*/
|
|
771
766
|
async request(provider, method, url, options) {
|
package/dist/index.d.cts
CHANGED
|
@@ -60,17 +60,9 @@ declare enum HttpMethod {
|
|
|
60
60
|
/**
|
|
61
61
|
* Main Alter Vault SDK client.
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* Security Hardening (v0.4.0):
|
|
67
|
-
* - Layer 1: Prototype frozen to prevent subclass method override attacks
|
|
68
|
-
* - Layer 1b: HttpClient.prototype also frozen to prevent request interception
|
|
69
|
-
* - Layer 2: Instance frozen after construction (Object.freeze)
|
|
70
|
-
* - Layer 3: API key not stored as instance property
|
|
71
|
-
* - Layer 4: ES2022 private fields (#) for truly private internal state
|
|
72
|
-
* - Layer 5: (see models.ts) TokenResponse access_token in module-private WeakMap
|
|
73
|
-
* - Layer 6: Test accessors removed from production builds
|
|
63
|
+
* Provides the AlterVault class for OAuth token management with
|
|
64
|
+
* zero token exposure — tokens are retrieved and injected automatically,
|
|
65
|
+
* never returned to the caller.
|
|
74
66
|
*/
|
|
75
67
|
|
|
76
68
|
/**
|
|
@@ -81,8 +73,6 @@ interface AlterVaultOptions {
|
|
|
81
73
|
apiKey: string;
|
|
82
74
|
/** Base URL for Alter Vault API */
|
|
83
75
|
baseUrl?: string;
|
|
84
|
-
/** Whether to send audit logs to backend (default: true) */
|
|
85
|
-
enableAuditLogging?: boolean;
|
|
86
76
|
/** HTTP request timeout in milliseconds (default: 30000) */
|
|
87
77
|
timeout?: number;
|
|
88
78
|
/** Actor type ("ai_agent" or "mcp_server") for tracking */
|
|
@@ -129,17 +119,7 @@ interface RequestOptions {
|
|
|
129
119
|
* - Audit logging of API calls
|
|
130
120
|
* - Actor tracking for AI agents and MCP servers
|
|
131
121
|
*
|
|
132
|
-
*
|
|
133
|
-
* - Tokens are retrieved internally but NEVER exposed to developers
|
|
134
|
-
* - All API calls inject tokens automatically behind the scenes
|
|
135
|
-
* - Developers only see API results, never authentication credentials
|
|
136
|
-
*
|
|
137
|
-
* Security Hardening:
|
|
138
|
-
* - Cannot be effectively subclassed (prototype is frozen)
|
|
139
|
-
* - Instance is frozen after construction (Object.freeze)
|
|
140
|
-
* - API key is NOT stored as an instance property
|
|
141
|
-
* - Internal HTTP clients use ES2022 private fields (#)
|
|
142
|
-
* - Test accessors are removed (no production leak path)
|
|
122
|
+
* Tokens are retrieved and injected automatically — never exposed to callers.
|
|
143
123
|
*
|
|
144
124
|
* @example
|
|
145
125
|
* ```typescript
|
|
@@ -162,7 +142,6 @@ interface RequestOptions {
|
|
|
162
142
|
declare class AlterVault {
|
|
163
143
|
#private;
|
|
164
144
|
readonly baseUrl: string;
|
|
165
|
-
readonly enableAuditLogging: boolean;
|
|
166
145
|
constructor(options: AlterVaultOptions);
|
|
167
146
|
/**
|
|
168
147
|
* Execute an HTTP request to a provider API with automatic token injection.
|
|
@@ -171,7 +150,7 @@ declare class AlterVault {
|
|
|
171
150
|
* 1. Fetches an OAuth token from Alter backend (never exposed)
|
|
172
151
|
* 2. Injects the token as a Bearer header
|
|
173
152
|
* 3. Calls the provider API
|
|
174
|
-
* 4. Logs the call for audit (
|
|
153
|
+
* 4. Logs the call for audit (fire-and-forget)
|
|
175
154
|
* 5. Returns the raw response
|
|
176
155
|
*/
|
|
177
156
|
request(provider: Provider | string, method: HttpMethod | string, url: string, options: RequestOptions): Promise<Response>;
|
package/dist/index.d.ts
CHANGED
|
@@ -60,17 +60,9 @@ declare enum HttpMethod {
|
|
|
60
60
|
/**
|
|
61
61
|
* Main Alter Vault SDK client.
|
|
62
62
|
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
* Security Hardening (v0.4.0):
|
|
67
|
-
* - Layer 1: Prototype frozen to prevent subclass method override attacks
|
|
68
|
-
* - Layer 1b: HttpClient.prototype also frozen to prevent request interception
|
|
69
|
-
* - Layer 2: Instance frozen after construction (Object.freeze)
|
|
70
|
-
* - Layer 3: API key not stored as instance property
|
|
71
|
-
* - Layer 4: ES2022 private fields (#) for truly private internal state
|
|
72
|
-
* - Layer 5: (see models.ts) TokenResponse access_token in module-private WeakMap
|
|
73
|
-
* - Layer 6: Test accessors removed from production builds
|
|
63
|
+
* Provides the AlterVault class for OAuth token management with
|
|
64
|
+
* zero token exposure — tokens are retrieved and injected automatically,
|
|
65
|
+
* never returned to the caller.
|
|
74
66
|
*/
|
|
75
67
|
|
|
76
68
|
/**
|
|
@@ -81,8 +73,6 @@ interface AlterVaultOptions {
|
|
|
81
73
|
apiKey: string;
|
|
82
74
|
/** Base URL for Alter Vault API */
|
|
83
75
|
baseUrl?: string;
|
|
84
|
-
/** Whether to send audit logs to backend (default: true) */
|
|
85
|
-
enableAuditLogging?: boolean;
|
|
86
76
|
/** HTTP request timeout in milliseconds (default: 30000) */
|
|
87
77
|
timeout?: number;
|
|
88
78
|
/** Actor type ("ai_agent" or "mcp_server") for tracking */
|
|
@@ -129,17 +119,7 @@ interface RequestOptions {
|
|
|
129
119
|
* - Audit logging of API calls
|
|
130
120
|
* - Actor tracking for AI agents and MCP servers
|
|
131
121
|
*
|
|
132
|
-
*
|
|
133
|
-
* - Tokens are retrieved internally but NEVER exposed to developers
|
|
134
|
-
* - All API calls inject tokens automatically behind the scenes
|
|
135
|
-
* - Developers only see API results, never authentication credentials
|
|
136
|
-
*
|
|
137
|
-
* Security Hardening:
|
|
138
|
-
* - Cannot be effectively subclassed (prototype is frozen)
|
|
139
|
-
* - Instance is frozen after construction (Object.freeze)
|
|
140
|
-
* - API key is NOT stored as an instance property
|
|
141
|
-
* - Internal HTTP clients use ES2022 private fields (#)
|
|
142
|
-
* - Test accessors are removed (no production leak path)
|
|
122
|
+
* Tokens are retrieved and injected automatically — never exposed to callers.
|
|
143
123
|
*
|
|
144
124
|
* @example
|
|
145
125
|
* ```typescript
|
|
@@ -162,7 +142,6 @@ interface RequestOptions {
|
|
|
162
142
|
declare class AlterVault {
|
|
163
143
|
#private;
|
|
164
144
|
readonly baseUrl: string;
|
|
165
|
-
readonly enableAuditLogging: boolean;
|
|
166
145
|
constructor(options: AlterVaultOptions);
|
|
167
146
|
/**
|
|
168
147
|
* Execute an HTTP request to a provider API with automatic token injection.
|
|
@@ -171,7 +150,7 @@ declare class AlterVault {
|
|
|
171
150
|
* 1. Fetches an OAuth token from Alter backend (never exposed)
|
|
172
151
|
* 2. Injects the token as a Bearer header
|
|
173
152
|
* 3. Calls the provider API
|
|
174
|
-
* 4. Logs the call for audit (
|
|
153
|
+
* 4. Logs the call for audit (fire-and-forget)
|
|
175
154
|
* 5. Returns the raw response
|
|
176
155
|
*/
|
|
177
156
|
request(provider: Provider | string, method: HttpMethod | string, url: string, options: RequestOptions): Promise<Response>;
|
package/dist/index.js
CHANGED
|
@@ -238,7 +238,7 @@ function _extractAccessToken(token) {
|
|
|
238
238
|
return value;
|
|
239
239
|
}
|
|
240
240
|
var _fetch;
|
|
241
|
-
var SDK_VERSION = "0.2.
|
|
241
|
+
var SDK_VERSION = "0.2.1";
|
|
242
242
|
var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
|
|
243
243
|
var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
|
|
244
244
|
var HTTP_FORBIDDEN = 403;
|
|
@@ -334,7 +334,6 @@ var AlterVault = class _AlterVault {
|
|
|
334
334
|
// Public readonly properties (frozen by Object.freeze)
|
|
335
335
|
// ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
336
336
|
baseUrl;
|
|
337
|
-
enableAuditLogging;
|
|
338
337
|
/** Actor tracking configuration (readonly, not secret) */
|
|
339
338
|
#actorType;
|
|
340
339
|
#actorIdentifier;
|
|
@@ -362,7 +361,6 @@ var AlterVault = class _AlterVault {
|
|
|
362
361
|
/\/+$/,
|
|
363
362
|
""
|
|
364
363
|
);
|
|
365
|
-
this.enableAuditLogging = options.enableAuditLogging ?? true;
|
|
366
364
|
const timeoutMs = options.timeout ?? 3e4;
|
|
367
365
|
this.#actorType = options.actorType;
|
|
368
366
|
this.#actorIdentifier = options.actorIdentifier;
|
|
@@ -640,9 +638,6 @@ var AlterVault = class _AlterVault {
|
|
|
640
638
|
* if audit logging fails.
|
|
641
639
|
*/
|
|
642
640
|
async #logApiCall(params) {
|
|
643
|
-
if (!this.enableAuditLogging) {
|
|
644
|
-
return;
|
|
645
|
-
}
|
|
646
641
|
try {
|
|
647
642
|
const auditLog = new APICallAuditLog({
|
|
648
643
|
connectionId: params.connectionId,
|
|
@@ -727,7 +722,7 @@ var AlterVault = class _AlterVault {
|
|
|
727
722
|
* 1. Fetches an OAuth token from Alter backend (never exposed)
|
|
728
723
|
* 2. Injects the token as a Bearer header
|
|
729
724
|
* 3. Calls the provider API
|
|
730
|
-
* 4. Logs the call for audit (
|
|
725
|
+
* 4. Logs the call for audit (fire-and-forget)
|
|
731
726
|
* 5. Returns the raw response
|
|
732
727
|
*/
|
|
733
728
|
async request(provider, method, url, options) {
|