@alter-ai/alter-sdk 0.2.2 → 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/dist/index.d.ts CHANGED
@@ -9,6 +9,14 @@
9
9
  * - TokenResponse: Object.freeze(this) prevents mutation after creation
10
10
  * - toJSON() and toString() exclude access token from serialization
11
11
  */
12
+ /**
13
+ * Actor types for tracking SDK callers.
14
+ */
15
+ declare enum ActorType {
16
+ BACKEND_SERVICE = "backend_service",
17
+ AI_AGENT = "ai_agent",
18
+ MCP_SERVER = "mcp_server"
19
+ }
12
20
  /**
13
21
  * OAuth token response from Alter Vault.
14
22
  *
@@ -34,6 +42,12 @@ declare class TokenResponse {
34
42
  readonly scopes: string[];
35
43
  /** Connection ID that provided this token */
36
44
  readonly connectionId: string;
45
+ /** Provider ID (google, github, etc.) */
46
+ readonly providerId: string;
47
+ /** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
48
+ readonly injectionHeader: string;
49
+ /** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
50
+ readonly injectionFormat: string;
37
51
  constructor(data: {
38
52
  access_token: string;
39
53
  token_type?: string;
@@ -41,6 +55,9 @@ declare class TokenResponse {
41
55
  expires_at?: string | null;
42
56
  scopes?: string[];
43
57
  connection_id: string;
58
+ provider_id?: string;
59
+ injection_header?: string;
60
+ injection_format?: string;
44
61
  });
45
62
  /**
46
63
  * Parse expires_at from ISO string.
@@ -80,7 +97,6 @@ declare class TokenResponse {
80
97
  declare class ConnectionInfo {
81
98
  readonly id: string;
82
99
  readonly providerId: string;
83
- readonly attributes: Record<string, unknown>;
84
100
  readonly scopes: string[];
85
101
  readonly accountIdentifier: string | null;
86
102
  readonly accountDisplayName: string | null;
@@ -91,7 +107,6 @@ declare class ConnectionInfo {
91
107
  constructor(data: {
92
108
  id: string;
93
109
  provider_id: string;
94
- attributes?: Record<string, unknown>;
95
110
  scopes?: string[];
96
111
  account_identifier?: string | null;
97
112
  account_display_name?: string | null;
@@ -231,8 +246,6 @@ declare enum Provider {
231
246
  GOOGLE = "google",
232
247
  GITHUB = "github",
233
248
  SLACK = "slack",
234
- MICROSOFT = "microsoft",
235
- SALESFORCE = "salesforce",
236
249
  SENTRY = "sentry"
237
250
  }
238
251
  /**
@@ -265,14 +278,12 @@ declare enum HttpMethod {
265
278
  interface AlterVaultOptions {
266
279
  /** Alter Vault API key (must start with "alter_key_") */
267
280
  apiKey: string;
268
- /** Base URL for Alter Vault API */
269
- baseUrl?: string;
270
281
  /** HTTP request timeout in milliseconds (default: 30000) */
271
282
  timeout?: number;
272
- /** Actor type ("ai_agent" or "mcp_server") for tracking */
273
- actorType?: string;
283
+ /** Actor type (use ActorType enum: AI_AGENT, MCP_SERVER, BACKEND_SERVICE) */
284
+ actorType: ActorType | string;
274
285
  /** Unique identifier for the actor (e.g., "email-assistant-v2") */
275
- actorIdentifier?: string;
286
+ actorIdentifier: string;
276
287
  /** Human-readable name for the actor */
277
288
  actorName?: string;
278
289
  /** Actor version string (e.g., "1.0.0") */
@@ -286,8 +297,6 @@ interface AlterVaultOptions {
286
297
  * Options for the request() method.
287
298
  */
288
299
  interface RequestOptions {
289
- /** User attributes to match connection (e.g., { user_id: "alice" }) */
290
- user: Record<string, unknown>;
291
300
  /** Optional JSON request body */
292
301
  json?: Record<string, unknown>;
293
302
  /** Optional additional headers */
@@ -326,8 +335,6 @@ interface CreateConnectSessionOptions {
326
335
  email?: string;
327
336
  name?: string;
328
337
  };
329
- /** User attributes for connection matching */
330
- attributes?: Record<string, unknown>;
331
338
  /** Restrict to specific providers (e.g., ["google", "github"]) */
332
339
  allowedProviders?: string[];
333
340
  /** URL to redirect after OAuth completion */
@@ -358,9 +365,8 @@ interface CreateConnectSessionOptions {
358
365
  *
359
366
  * // Make API request (token injected automatically)
360
367
  * const response = await vault.request(
361
- * Provider.GOOGLE, HttpMethod.GET,
368
+ * "connection-uuid-here", HttpMethod.GET,
362
369
  * "https://www.googleapis.com/calendar/v3/calendars/primary/events",
363
- * { user: { user_id: "alice" } },
364
370
  * );
365
371
  * const events = await response.json();
366
372
  *
@@ -382,7 +388,7 @@ declare class AlterVault {
382
388
  * 4. Logs the call for audit (fire-and-forget)
383
389
  * 5. Returns the raw response
384
390
  */
385
- request(provider: Provider | string, method: HttpMethod | string, url: string, options: RequestOptions): Promise<Response>;
391
+ request(connectionId: string, method: HttpMethod | string, url: string, options?: RequestOptions): Promise<Response>;
386
392
  /**
387
393
  * List OAuth connections for this app.
388
394
  *
@@ -440,7 +446,7 @@ declare class PolicyViolationError extends TokenRetrievalError {
440
446
  /**
441
447
  * Raised when OAuth connection not found.
442
448
  *
443
- * This indicates no connection exists for the given provider and attributes.
449
+ * This indicates no connection exists for the given connection_id.
444
450
  */
445
451
  declare class ConnectionNotFoundError extends TokenRetrievalError {
446
452
  constructor(message: string, details?: Record<string, unknown>);
@@ -487,4 +493,4 @@ declare class TimeoutError extends NetworkError {
487
493
  constructor(message: string, details?: Record<string, unknown>);
488
494
  }
489
495
 
490
- export { APICallAuditLog, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
496
+ export { APICallAuditLog, ActorType, AlterSDKError, AlterVault, type AlterVaultOptions, ConnectSession, ConnectionInfo, ConnectionListResult, ConnectionNotFoundError, type CreateConnectSessionOptions, HttpMethod, type ListConnectionsOptions, NetworkError, PolicyViolationError, Provider, ProviderAPIError, type RequestOptions, TimeoutError, TokenExpiredError, TokenResponse, TokenRetrievalError };
package/dist/index.js CHANGED
@@ -1,3 +1,6 @@
1
+ // src/client.ts
2
+ import { createHash, createHmac, randomUUID } from "crypto";
3
+
1
4
  // src/exceptions.ts
2
5
  var AlterSDKError = class extends Error {
3
6
  details;
@@ -66,6 +69,12 @@ var TimeoutError = class extends NetworkError {
66
69
  };
67
70
 
68
71
  // src/models.ts
72
+ var ActorType = /* @__PURE__ */ ((ActorType2) => {
73
+ ActorType2["BACKEND_SERVICE"] = "backend_service";
74
+ ActorType2["AI_AGENT"] = "ai_agent";
75
+ ActorType2["MCP_SERVER"] = "mcp_server";
76
+ return ActorType2;
77
+ })(ActorType || {});
69
78
  var TokenResponse = class _TokenResponse {
70
79
  /** Token type (usually "Bearer") */
71
80
  tokenType;
@@ -77,12 +86,21 @@ var TokenResponse = class _TokenResponse {
77
86
  scopes;
78
87
  /** Connection ID that provided this token */
79
88
  connectionId;
89
+ /** Provider ID (google, github, etc.) */
90
+ providerId;
91
+ /** HTTP header name for credential injection (e.g., "Authorization", "X-API-Key") */
92
+ injectionHeader;
93
+ /** Header value format with {token} placeholder (e.g., "Bearer {token}", "{token}") */
94
+ injectionFormat;
80
95
  constructor(data) {
81
96
  this.tokenType = data.token_type ?? "Bearer";
82
97
  this.expiresIn = data.expires_in ?? null;
83
98
  this.expiresAt = data.expires_at ? _TokenResponse.parseExpiresAt(data.expires_at) : null;
84
99
  this.scopes = data.scopes ?? [];
85
100
  this.connectionId = data.connection_id;
101
+ this.providerId = data.provider_id ?? "";
102
+ this.injectionHeader = data.injection_header ?? "Authorization";
103
+ this.injectionFormat = data.injection_format ?? "Bearer {token}";
86
104
  Object.freeze(this);
87
105
  }
88
106
  /**
@@ -147,7 +165,6 @@ var TokenResponse = class _TokenResponse {
147
165
  var ConnectionInfo = class {
148
166
  id;
149
167
  providerId;
150
- attributes;
151
168
  scopes;
152
169
  accountIdentifier;
153
170
  accountDisplayName;
@@ -158,7 +175,6 @@ var ConnectionInfo = class {
158
175
  constructor(data) {
159
176
  this.id = data.id;
160
177
  this.providerId = data.provider_id;
161
- this.attributes = data.attributes ?? {};
162
178
  this.scopes = data.scopes ?? [];
163
179
  this.accountIdentifier = data.account_identifier ?? null;
164
180
  this.accountDisplayName = data.account_display_name ?? null;
@@ -172,7 +188,6 @@ var ConnectionInfo = class {
172
188
  return {
173
189
  id: this.id,
174
190
  provider_id: this.providerId,
175
- attributes: this.attributes,
176
191
  scopes: this.scopes,
177
192
  account_identifier: this.accountIdentifier,
178
193
  account_display_name: this.accountDisplayName,
@@ -319,9 +334,8 @@ function _extractAccessToken(token) {
319
334
  return value;
320
335
  }
321
336
  var _fetch;
322
- var SDK_VERSION = "0.2.2";
337
+ var SDK_VERSION = "0.3.0";
323
338
  var SDK_USER_AGENT = `alter-sdk-node/${SDK_VERSION}`;
324
- var VALID_ACTOR_TYPES = ["ai_agent", "mcp_server"];
325
339
  var HTTP_FORBIDDEN = 403;
326
340
  var HTTP_NOT_FOUND = 404;
327
341
  var HTTP_BAD_REQUEST = 400;
@@ -401,6 +415,8 @@ var AlterVault = class _AlterVault {
401
415
  // SECURITY LAYER 4: ES2022 private fields — truly private at runtime.
402
416
  // These are NOT accessible via (obj as any), Object.keys(), or prototype.
403
417
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
418
+ /** HMAC signing key (derived from API key using AWS SigV4 pattern, raw bytes) */
419
+ #hmacKey;
404
420
  /** HTTP Client for Alter Backend (has x-api-key) */
405
421
  #alterClient;
406
422
  /** HTTP Client for External Provider APIs (NO x-api-key) */
@@ -438,10 +454,8 @@ var AlterVault = class _AlterVault {
438
454
  for (const [name, value] of actorStrings) {
439
455
  _AlterVault.#validateActorString(value, name);
440
456
  }
441
- this.baseUrl = (options.baseUrl ?? "https://api.alter.com").replace(
442
- /\/+$/,
443
- ""
444
- );
457
+ this.#hmacKey = createHmac("sha256", options.apiKey).update("alter-signing-v1").digest();
458
+ this.baseUrl = (process.env.ALTER_BASE_URL ?? "https://backend.alterai.dev").replace(/\/+$/, "");
445
459
  const timeoutMs = options.timeout ?? 3e4;
446
460
  this.#actorType = options.actorType;
447
461
  this.#actorIdentifier = options.actorIdentifier;
@@ -494,14 +508,20 @@ var AlterVault = class _AlterVault {
494
508
  if (!apiKey.startsWith("alter_key_")) {
495
509
  throw new AlterSDKError("api_key must start with 'alter_key_'");
496
510
  }
497
- if (actorType && !VALID_ACTOR_TYPES.includes(actorType)) {
498
- throw new AlterSDKError("actor_type must be 'ai_agent' or 'mcp_server'");
511
+ if (!actorType) {
512
+ throw new AlterSDKError(
513
+ "actor_type is required (use ActorType.AI_AGENT, ActorType.MCP_SERVER, or ActorType.BACKEND_SERVICE)"
514
+ );
499
515
  }
500
- if (actorType && !actorIdentifier) {
516
+ const validValues = Object.values(ActorType);
517
+ if (!validValues.includes(String(actorType))) {
501
518
  throw new AlterSDKError(
502
- "actor_identifier is required when actor_type is set"
519
+ `actor_type must be one of ${JSON.stringify(validValues.sort())}, got '${String(actorType)}'`
503
520
  );
504
521
  }
522
+ if (!actorIdentifier) {
523
+ throw new AlterSDKError("actor_identifier is required");
524
+ }
505
525
  }
506
526
  /**
507
527
  * Build default headers for the Alter backend HTTP client.
@@ -528,6 +548,28 @@ var AlterVault = class _AlterVault {
528
548
  }
529
549
  return headers;
530
550
  }
551
+ /**
552
+ * Compute HMAC-SHA256 signature headers for an Alter backend request.
553
+ *
554
+ * String-to-sign format: METHOD\nPATH_WITH_SORTED_QUERY\nTIMESTAMP\nCONTENT_HASH
555
+ *
556
+ * The path should include sorted query parameters if present (e.g. "/sdk/endpoint?a=1&b=2").
557
+ * Currently all SDK→backend calls are POSTs without query params, so the path is clean.
558
+ */
559
+ #computeHmacHeaders(method, path, body) {
560
+ const timestamp = String(Math.floor(Date.now() / 1e3));
561
+ const contentHash = createHash("sha256").update(body ?? "").digest("hex");
562
+ const stringToSign = `${method.toUpperCase()}
563
+ ${path}
564
+ ${timestamp}
565
+ ${contentHash}`;
566
+ const signature = createHmac("sha256", this.#hmacKey).update(stringToSign).digest("hex");
567
+ return {
568
+ "X-Alter-Timestamp": timestamp,
569
+ "X-Alter-Content-SHA256": contentHash,
570
+ "X-Alter-Signature": signature
571
+ };
572
+ }
531
573
  /**
532
574
  * Build per-request actor headers for instance tracking.
533
575
  */
@@ -624,7 +666,7 @@ var AlterVault = class _AlterVault {
624
666
  if (response.status === HTTP_NOT_FOUND) {
625
667
  const errorData = await _AlterVault.#safeParseJson(response);
626
668
  throw new ConnectionNotFoundError(
627
- errorData.message ?? "OAuth connection not found for these attributes",
669
+ errorData.message ?? "OAuth connection not found for the given connection_id",
628
670
  errorData
629
671
  );
630
672
  }
@@ -670,22 +712,24 @@ var AlterVault = class _AlterVault {
670
712
  * This is a private method. Tokens are NEVER exposed to developers.
671
713
  * Use request() instead, which handles tokens internally.
672
714
  */
673
- async #getToken(providerId, attributes, reason, requestMetadata, runId, threadId, toolCallId) {
715
+ async #getToken(connectionId, reason, requestMetadata, runId, threadId, toolCallId) {
674
716
  const actorHeaders = this.#getActorRequestHeaders(
675
717
  runId,
676
718
  threadId,
677
719
  toolCallId
678
720
  );
679
721
  let response;
722
+ const tokenBody = {
723
+ connection_id: connectionId,
724
+ reason: reason ?? null,
725
+ request: requestMetadata ?? null
726
+ };
727
+ const tokenPath = "/sdk/token";
728
+ const hmacHeaders = this.#computeHmacHeaders("POST", tokenPath, JSON.stringify(tokenBody));
680
729
  try {
681
- response = await this.#alterClient.post("/oauth/token", {
682
- json: {
683
- provider_id: providerId,
684
- attributes,
685
- reason: reason ?? null,
686
- request: requestMetadata ?? null
687
- },
688
- headers: actorHeaders
730
+ response = await this.#alterClient.post(tokenPath, {
731
+ json: tokenBody,
732
+ headers: { ...actorHeaders, ...hmacHeaders }
689
733
  });
690
734
  } catch (error) {
691
735
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
@@ -702,7 +746,7 @@ var AlterVault = class _AlterVault {
702
746
  }
703
747
  throw new TokenRetrievalError(
704
748
  `Failed to retrieve token: ${error instanceof Error ? error.message : String(error)}`,
705
- { provider_id: providerId, error: String(error) }
749
+ { connection_id: connectionId, error: String(error) }
706
750
  );
707
751
  }
708
752
  this.#cacheActorIdFromResponse(response);
@@ -710,6 +754,18 @@ var AlterVault = class _AlterVault {
710
754
  const tokenData = await response.json();
711
755
  const typedData = tokenData;
712
756
  const tokenResponse = new TokenResponse(typedData);
757
+ if (!/^[A-Za-z][A-Za-z0-9-]*$/.test(tokenResponse.injectionHeader)) {
758
+ throw new TokenRetrievalError(
759
+ `Backend returned invalid injection_header: ${tokenResponse.injectionHeader}`,
760
+ { connectionId: String(connectionId) }
761
+ );
762
+ }
763
+ if (/[\r\n\x00]/.test(tokenResponse.injectionFormat)) {
764
+ throw new TokenRetrievalError(
765
+ `Backend returned invalid injection_format (contains control characters)`,
766
+ { connectionId: String(connectionId) }
767
+ );
768
+ }
713
769
  _storeAccessToken(tokenResponse, typedData.access_token);
714
770
  return tokenResponse;
715
771
  }
@@ -738,10 +794,13 @@ var AlterVault = class _AlterVault {
738
794
  toolCallId: params.toolCallId
739
795
  });
740
796
  const sanitized = auditLog.sanitize();
741
- const actorHeaders = this.#getActorRequestHeaders();
742
- const response = await this.#alterClient.post("/oauth/audit/api-call", {
743
- json: sanitized,
744
- headers: actorHeaders
797
+ const actorHeaders = this.#getActorRequestHeaders(params.runId);
798
+ const auditPath = "/sdk/oauth/audit/api-call";
799
+ const auditBody = sanitized;
800
+ const auditHmac = this.#computeHmacHeaders("POST", auditPath, JSON.stringify(auditBody));
801
+ const response = await this.#alterClient.post(auditPath, {
802
+ json: auditBody,
803
+ headers: { ...actorHeaders, ...auditHmac }
745
804
  });
746
805
  this.#cacheActorIdFromResponse(response);
747
806
  if (!response.ok) {
@@ -807,13 +866,13 @@ var AlterVault = class _AlterVault {
807
866
  * 4. Logs the call for audit (fire-and-forget)
808
867
  * 5. Returns the raw response
809
868
  */
810
- async request(provider, method, url, options) {
869
+ async request(connectionId, method, url, options) {
811
870
  if (this.#closed) {
812
871
  throw new AlterSDKError(
813
872
  "SDK instance has been closed. Create a new AlterVault instance to make requests."
814
873
  );
815
874
  }
816
- const providerStr = String(provider);
875
+ const runId = options?.runId ?? randomUUID();
817
876
  const methodStr = String(method).toUpperCase();
818
877
  const urlLower = url.toLowerCase();
819
878
  if (!ALLOWED_URL_SCHEMES.some((scheme) => urlLower.startsWith(scheme))) {
@@ -821,7 +880,7 @@ var AlterVault = class _AlterVault {
821
880
  `URL must start with https:// or http://, got: ${url.slice(0, 50)}`
822
881
  );
823
882
  }
824
- if (options.pathParams && Object.keys(options.pathParams).length > 0) {
883
+ if (options?.pathParams && Object.keys(options.pathParams).length > 0) {
825
884
  const encodedParams = {};
826
885
  for (const [key, value] of Object.entries(options.pathParams)) {
827
886
  encodedParams[key] = encodeURIComponent(String(value));
@@ -851,22 +910,25 @@ var AlterVault = class _AlterVault {
851
910
  );
852
911
  }
853
912
  }
854
- if (options.extraHeaders && "Authorization" in options.extraHeaders) {
855
- console.warn(
856
- "extraHeaders contains 'Authorization' which will be overwritten with the auto-injected Bearer token"
857
- );
858
- }
859
913
  const tokenResponse = await this.#getToken(
860
- providerStr,
861
- options.user,
862
- options.reason,
914
+ connectionId,
915
+ options?.reason,
863
916
  { method: methodStr, url },
864
- options.runId,
865
- options.threadId,
866
- options.toolCallId
917
+ runId,
918
+ options?.threadId,
919
+ options?.toolCallId
867
920
  );
868
- const requestHeaders = options.extraHeaders ? { ...options.extraHeaders } : {};
869
- requestHeaders["Authorization"] = `Bearer ${_extractAccessToken(tokenResponse)}`;
921
+ const injectionHeaderLower = tokenResponse.injectionHeader.toLowerCase();
922
+ if (options?.extraHeaders && Object.keys(options.extraHeaders).some(
923
+ (k) => k.toLowerCase() === injectionHeaderLower
924
+ )) {
925
+ console.warn(
926
+ `extraHeaders contains '${tokenResponse.injectionHeader}' which will be overwritten with the auto-injected credential`
927
+ );
928
+ }
929
+ const requestHeaders = options?.extraHeaders ? { ...options.extraHeaders } : {};
930
+ const accessToken = _extractAccessToken(tokenResponse);
931
+ requestHeaders[tokenResponse.injectionHeader] = tokenResponse.injectionFormat.replace("{token}", accessToken);
870
932
  if (!requestHeaders["User-Agent"]) {
871
933
  requestHeaders["User-Agent"] = SDK_USER_AGENT;
872
934
  }
@@ -874,16 +936,16 @@ var AlterVault = class _AlterVault {
874
936
  let response;
875
937
  try {
876
938
  response = await this.#providerClient.request(methodStr, url, {
877
- json: options.json,
939
+ json: options?.json,
878
940
  headers: requestHeaders,
879
- params: options.queryParams
941
+ params: options?.queryParams
880
942
  });
881
943
  } catch (error) {
882
944
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
883
945
  throw new TimeoutError(
884
946
  `Provider API request timed out: ${error instanceof Error ? error.message : String(error)}`,
885
947
  {
886
- provider: providerStr,
948
+ connection_id: connectionId,
887
949
  method: methodStr,
888
950
  url
889
951
  }
@@ -892,7 +954,7 @@ var AlterVault = class _AlterVault {
892
954
  throw new NetworkError(
893
955
  `Failed to call provider API: ${error instanceof Error ? error.message : String(error)}`,
894
956
  {
895
- provider: providerStr,
957
+ connection_id: connectionId,
896
958
  method: methodStr,
897
959
  url,
898
960
  error: String(error)
@@ -902,7 +964,7 @@ var AlterVault = class _AlterVault {
902
964
  const latencyMs = Date.now() - startTime;
903
965
  const auditHeaders = {};
904
966
  for (const [key, value] of Object.entries(requestHeaders)) {
905
- if (key.toLowerCase() !== "authorization") {
967
+ if (key.toLowerCase() !== injectionHeaderLower) {
906
968
  auditHeaders[key] = value;
907
969
  }
908
970
  }
@@ -913,19 +975,19 @@ var AlterVault = class _AlterVault {
913
975
  });
914
976
  this.#scheduleAuditLog({
915
977
  connectionId: tokenResponse.connectionId,
916
- providerId: providerStr,
978
+ providerId: tokenResponse.providerId || connectionId,
917
979
  method: methodStr,
918
980
  url,
919
981
  requestHeaders: auditHeaders,
920
- requestBody: options.json ?? null,
982
+ requestBody: options?.json ?? null,
921
983
  responseStatus: response.status,
922
984
  responseHeaders,
923
985
  responseBody,
924
986
  latencyMs,
925
- reason: options.reason ?? null,
926
- runId: options.runId ?? null,
927
- threadId: options.threadId ?? null,
928
- toolCallId: options.toolCallId ?? null
987
+ reason: options?.reason ?? null,
988
+ runId,
989
+ threadId: options?.threadId ?? null,
990
+ toolCallId: options?.toolCallId ?? null
929
991
  });
930
992
  if (response.status >= HTTP_CLIENT_ERROR_START) {
931
993
  throw new ProviderAPIError(
@@ -933,7 +995,7 @@ var AlterVault = class _AlterVault {
933
995
  response.status,
934
996
  responseBody,
935
997
  {
936
- provider: providerStr,
998
+ connection_id: connectionId,
937
999
  method: methodStr,
938
1000
  url
939
1001
  }
@@ -955,14 +1017,17 @@ var AlterVault = class _AlterVault {
955
1017
  }
956
1018
  const actorHeaders = this.#getActorRequestHeaders();
957
1019
  let response;
1020
+ const listBody = {
1021
+ provider_id: options?.providerId ?? null,
1022
+ limit: options?.limit ?? 100,
1023
+ offset: options?.offset ?? 0
1024
+ };
1025
+ const listPath = "/sdk/oauth/connections/list";
1026
+ const listHmac = this.#computeHmacHeaders("POST", listPath, JSON.stringify(listBody));
958
1027
  try {
959
- response = await this.#alterClient.post("/oauth/connections/list", {
960
- json: {
961
- provider_id: options?.providerId ?? null,
962
- limit: options?.limit ?? 100,
963
- offset: options?.offset ?? 0
964
- },
965
- headers: actorHeaders
1028
+ response = await this.#alterClient.post(listPath, {
1029
+ json: listBody,
1030
+ headers: { ...actorHeaders, ...listHmac }
966
1031
  });
967
1032
  } catch (error) {
968
1033
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
@@ -1013,17 +1078,19 @@ var AlterVault = class _AlterVault {
1013
1078
  }
1014
1079
  const actorHeaders = this.#getActorRequestHeaders();
1015
1080
  let response;
1081
+ const sessionBody = {
1082
+ end_user: options.endUser,
1083
+ allowed_providers: options.allowedProviders ?? null,
1084
+ return_url: options.returnUrl ?? null,
1085
+ allowed_origin: options.allowedOrigin ?? null,
1086
+ metadata: options.metadata ?? null
1087
+ };
1088
+ const sessionPath = "/sdk/oauth/connect/session";
1089
+ const sessionHmac = this.#computeHmacHeaders("POST", sessionPath, JSON.stringify(sessionBody));
1016
1090
  try {
1017
- response = await this.#alterClient.post("/oauth/connect/session", {
1018
- json: {
1019
- end_user: options.endUser,
1020
- attributes: options.attributes ?? null,
1021
- allowed_providers: options.allowedProviders ?? null,
1022
- return_url: options.returnUrl ?? null,
1023
- allowed_origin: options.allowedOrigin ?? null,
1024
- metadata: options.metadata ?? null
1025
- },
1026
- headers: actorHeaders
1091
+ response = await this.#alterClient.post(sessionPath, {
1092
+ json: sessionBody,
1093
+ headers: { ...actorHeaders, ...sessionHmac }
1027
1094
  });
1028
1095
  } catch (error) {
1029
1096
  if (_AlterVault.#isTimeoutOrAbortError(error)) {
@@ -1075,8 +1142,6 @@ var Provider = /* @__PURE__ */ ((Provider2) => {
1075
1142
  Provider2["GOOGLE"] = "google";
1076
1143
  Provider2["GITHUB"] = "github";
1077
1144
  Provider2["SLACK"] = "slack";
1078
- Provider2["MICROSOFT"] = "microsoft";
1079
- Provider2["SALESFORCE"] = "salesforce";
1080
1145
  Provider2["SENTRY"] = "sentry";
1081
1146
  return Provider2;
1082
1147
  })(Provider || {});
@@ -1092,6 +1157,7 @@ var HttpMethod = /* @__PURE__ */ ((HttpMethod2) => {
1092
1157
  })(HttpMethod || {});
1093
1158
  export {
1094
1159
  APICallAuditLog,
1160
+ ActorType,
1095
1161
  AlterSDKError,
1096
1162
  AlterVault,
1097
1163
  ConnectSession,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alter-ai/alter-sdk",
3
- "version": "0.2.2",
3
+ "version": "0.3.1",
4
4
  "description": "Official TypeScript SDK for Alter Vault — OAuth token management with policy enforcement",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",