@anthropic-ai/sdk 0.91.1 → 0.93.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/CHANGELOG.md +28 -0
- package/client.d.mts +73 -0
- package/client.d.mts.map +1 -1
- package/client.d.ts +73 -0
- package/client.d.ts.map +1 -1
- package/client.js +269 -9
- package/client.js.map +1 -1
- package/client.mjs +269 -9
- package/client.mjs.map +1 -1
- package/core/credentials.d.mts +111 -0
- package/core/credentials.d.mts.map +1 -0
- package/core/credentials.d.ts +111 -0
- package/core/credentials.d.ts.map +1 -0
- package/core/credentials.js +298 -0
- package/core/credentials.js.map +1 -0
- package/core/credentials.mjs +259 -0
- package/core/credentials.mjs.map +1 -0
- package/internal/types.d.mts +12 -6
- package/internal/types.d.ts +12 -6
- package/internal/utils/time.d.mts +3 -0
- package/internal/utils/time.d.mts.map +1 -0
- package/internal/utils/time.d.ts +3 -0
- package/internal/utils/time.d.ts.map +1 -0
- package/internal/utils/time.js +8 -0
- package/internal/utils/time.js.map +1 -0
- package/internal/utils/time.mjs +5 -0
- package/internal/utils/time.mjs.map +1 -0
- package/lib/credentials/credential-chain.d.mts +39 -0
- package/lib/credentials/credential-chain.d.mts.map +1 -0
- package/lib/credentials/credential-chain.d.ts +39 -0
- package/lib/credentials/credential-chain.d.ts.map +1 -0
- package/lib/credentials/credential-chain.js +237 -0
- package/lib/credentials/credential-chain.js.map +1 -0
- package/lib/credentials/credential-chain.mjs +200 -0
- package/lib/credentials/credential-chain.mjs.map +1 -0
- package/lib/credentials/identity-token.d.mts +11 -0
- package/lib/credentials/identity-token.d.mts.map +1 -0
- package/lib/credentials/identity-token.d.ts +11 -0
- package/lib/credentials/identity-token.d.ts.map +1 -0
- package/lib/credentials/identity-token.js +72 -0
- package/lib/credentials/identity-token.js.map +1 -0
- package/lib/credentials/identity-token.mjs +35 -0
- package/lib/credentials/identity-token.mjs.map +1 -0
- package/lib/credentials/oidc-federation.d.mts +28 -0
- package/lib/credentials/oidc-federation.d.mts.map +1 -0
- package/lib/credentials/oidc-federation.d.ts +28 -0
- package/lib/credentials/oidc-federation.d.ts.map +1 -0
- package/lib/credentials/oidc-federation.js +69 -0
- package/lib/credentials/oidc-federation.js.map +1 -0
- package/lib/credentials/oidc-federation.mjs +66 -0
- package/lib/credentials/oidc-federation.mjs.map +1 -0
- package/lib/credentials/token-cache.d.mts +54 -0
- package/lib/credentials/token-cache.d.mts.map +1 -0
- package/lib/credentials/token-cache.d.ts +54 -0
- package/lib/credentials/token-cache.d.ts.map +1 -0
- package/lib/credentials/token-cache.js +112 -0
- package/lib/credentials/token-cache.js.map +1 -0
- package/lib/credentials/token-cache.mjs +108 -0
- package/lib/credentials/token-cache.mjs.map +1 -0
- package/lib/credentials/types.d.mts +96 -0
- package/lib/credentials/types.d.mts.map +1 -0
- package/lib/credentials/types.d.ts +96 -0
- package/lib/credentials/types.d.ts.map +1 -0
- package/lib/credentials/types.js +266 -0
- package/lib/credentials/types.js.map +1 -0
- package/lib/credentials/types.mjs +224 -0
- package/lib/credentials/types.mjs.map +1 -0
- package/lib/credentials/user-oauth.d.mts +21 -0
- package/lib/credentials/user-oauth.d.mts.map +1 -0
- package/lib/credentials/user-oauth.d.ts +21 -0
- package/lib/credentials/user-oauth.d.ts.map +1 -0
- package/lib/credentials/user-oauth.js +130 -0
- package/lib/credentials/user-oauth.js.map +1 -0
- package/lib/credentials/user-oauth.mjs +94 -0
- package/lib/credentials/user-oauth.mjs.map +1 -0
- package/lib/credentials.d.mts +4 -0
- package/lib/credentials.d.mts.map +1 -0
- package/lib/credentials.d.ts +4 -0
- package/lib/credentials.d.ts.map +1 -0
- package/lib/credentials.js +8 -0
- package/lib/credentials.js.map +1 -0
- package/lib/credentials.mjs +3 -0
- package/lib/credentials.mjs.map +1 -0
- package/package.json +1 -1
- package/resources/beta/environments.d.mts +1 -1
- package/resources/beta/environments.d.ts +1 -1
- package/resources/beta/index.d.mts +1 -1
- package/resources/beta/index.d.mts.map +1 -1
- package/resources/beta/index.d.ts +1 -1
- package/resources/beta/index.d.ts.map +1 -1
- package/resources/beta/index.js.map +1 -1
- package/resources/beta/index.mjs.map +1 -1
- package/resources/beta/memory-stores/memories.d.mts +126 -11
- package/resources/beta/memory-stores/memories.d.mts.map +1 -1
- package/resources/beta/memory-stores/memories.d.ts +126 -11
- package/resources/beta/memory-stores/memories.d.ts.map +1 -1
- package/resources/beta/memory-stores/memories.js +5 -5
- package/resources/beta/memory-stores/memories.mjs +5 -5
- package/resources/beta/memory-stores/memory-stores.d.mts +58 -14
- package/resources/beta/memory-stores/memory-stores.d.mts.map +1 -1
- package/resources/beta/memory-stores/memory-stores.d.ts +58 -14
- package/resources/beta/memory-stores/memory-stores.d.ts.map +1 -1
- package/resources/beta/memory-stores/memory-stores.js +6 -6
- package/resources/beta/memory-stores/memory-stores.js.map +1 -1
- package/resources/beta/memory-stores/memory-stores.mjs +6 -6
- package/resources/beta/memory-stores/memory-stores.mjs.map +1 -1
- package/resources/beta/memory-stores/memory-versions.d.mts +88 -5
- package/resources/beta/memory-stores/memory-versions.d.mts.map +1 -1
- package/resources/beta/memory-stores/memory-versions.d.ts +88 -5
- package/resources/beta/memory-stores/memory-versions.d.ts.map +1 -1
- package/resources/beta/memory-stores/memory-versions.js +3 -3
- package/resources/beta/memory-stores/memory-versions.mjs +3 -3
- package/resources/beta/messages/batches.d.mts +4 -0
- package/resources/beta/messages/batches.d.mts.map +1 -1
- package/resources/beta/messages/batches.d.ts +4 -0
- package/resources/beta/messages/batches.d.ts.map +1 -1
- package/resources/beta/messages/index.d.mts +1 -1
- package/resources/beta/messages/index.d.mts.map +1 -1
- package/resources/beta/messages/index.d.ts +1 -1
- package/resources/beta/messages/index.d.ts.map +1 -1
- package/resources/beta/messages/index.js.map +1 -1
- package/resources/beta/messages/index.mjs.map +1 -1
- package/resources/beta/messages/messages.d.mts +5 -1
- package/resources/beta/messages/messages.d.mts.map +1 -1
- package/resources/beta/messages/messages.d.ts +5 -1
- package/resources/beta/messages/messages.d.ts.map +1 -1
- package/resources/beta/messages/messages.js +1 -1
- package/resources/beta/messages/messages.js.map +1 -1
- package/resources/beta/messages/messages.mjs +1 -1
- package/resources/beta/messages/messages.mjs.map +1 -1
- package/resources/beta/sessions/sessions.d.mts +5 -0
- package/resources/beta/sessions/sessions.d.mts.map +1 -1
- package/resources/beta/sessions/sessions.d.ts +5 -0
- package/resources/beta/sessions/sessions.d.ts.map +1 -1
- package/resources/beta/sessions/sessions.js.map +1 -1
- package/resources/beta/sessions/sessions.mjs.map +1 -1
- package/resources/messages/messages.d.mts +4 -0
- package/resources/messages/messages.d.mts.map +1 -1
- package/resources/messages/messages.d.ts +4 -0
- package/resources/messages/messages.d.ts.map +1 -1
- package/resources/messages/messages.js.map +1 -1
- package/resources/messages/messages.mjs.map +1 -1
- package/src/client.ts +354 -14
- package/src/core/credentials.ts +349 -0
- package/src/internal/utils/time.ts +4 -0
- package/src/lib/credentials/credential-chain.ts +284 -0
- package/src/lib/credentials/identity-token.ts +37 -0
- package/src/lib/credentials/oidc-federation.ts +112 -0
- package/src/lib/credentials/token-cache.ts +130 -0
- package/src/lib/credentials/types.ts +295 -0
- package/src/lib/credentials/user-oauth.ts +144 -0
- package/src/lib/credentials.ts +3 -0
- package/src/resources/beta/environments.ts +1 -1
- package/src/resources/beta/index.ts +1 -0
- package/src/resources/beta/memory-stores/memories.ts +126 -11
- package/src/resources/beta/memory-stores/memory-stores.ts +58 -14
- package/src/resources/beta/memory-stores/memory-versions.ts +88 -5
- package/src/resources/beta/messages/batches.ts +4 -0
- package/src/resources/beta/messages/index.ts +1 -0
- package/src/resources/beta/messages/messages.ts +5 -1
- package/src/resources/beta/sessions/sessions.ts +6 -0
- package/src/resources/messages/messages.ts +4 -0
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { AnthropicError } from "../../core/error.js";
|
|
2
|
+
export type AccessToken = {
|
|
3
|
+
token: string;
|
|
4
|
+
/** Unix epoch seconds. `null` means no expiry (cache forever). */
|
|
5
|
+
expiresAt: number | null;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Mints or returns a cached access token.
|
|
9
|
+
*
|
|
10
|
+
* The optional `opts.forceRefresh` flag, set by {@link TokenCache.invalidate}
|
|
11
|
+
* after a 401, tells providers with on-disk caches (user_oauth, cachedExchange)
|
|
12
|
+
* to bypass their freshness short-circuit and always fetch fresh. Providers
|
|
13
|
+
* without a cache can ignore it.
|
|
14
|
+
*/
|
|
15
|
+
export type AccessTokenProvider = (opts?: {
|
|
16
|
+
forceRefresh?: boolean;
|
|
17
|
+
}) => Promise<AccessToken>;
|
|
18
|
+
export type IdentityTokenProvider = () => string | Promise<string>;
|
|
19
|
+
export type CredentialResult = {
|
|
20
|
+
provider: AccessTokenProvider;
|
|
21
|
+
extraHeaders: Record<string, string>;
|
|
22
|
+
/**
|
|
23
|
+
* The `base_url` from the resolved config/profile, if any. The client
|
|
24
|
+
* applies this to outbound API requests when no explicit `baseURL` (constructor
|
|
25
|
+
* option or `ANTHROPIC_BASE_URL` env) was given, so a profile pointing at a
|
|
26
|
+
* non-default API host both mints its token against that host AND sends
|
|
27
|
+
* subsequent API requests there.
|
|
28
|
+
*/
|
|
29
|
+
baseURL?: string | undefined;
|
|
30
|
+
};
|
|
31
|
+
/** Response body from `POST /v1/oauth/token`. */
|
|
32
|
+
export type TokenEndpointResponse = {
|
|
33
|
+
access_token?: string;
|
|
34
|
+
expires_in?: number;
|
|
35
|
+
refresh_token?: string;
|
|
36
|
+
};
|
|
37
|
+
export declare const GRANT_TYPE_JWT_BEARER = "urn:ietf:params:oauth:grant-type:jwt-bearer";
|
|
38
|
+
export declare const GRANT_TYPE_REFRESH_TOKEN = "refresh_token";
|
|
39
|
+
export declare const TOKEN_ENDPOINT = "/v1/oauth/token";
|
|
40
|
+
/**
|
|
41
|
+
* `anthropic-beta` value required on authenticated API requests using an
|
|
42
|
+
* OAuth bearer token, and on `refresh_token` grants against the token endpoint.
|
|
43
|
+
*/
|
|
44
|
+
export declare const OAUTH_API_BETA_HEADER = "oauth-2025-04-20";
|
|
45
|
+
/**
|
|
46
|
+
* `anthropic-beta` value required on jwt-bearer exchanges against the token
|
|
47
|
+
* endpoint. It routes the request to the federation service; it must NOT be
|
|
48
|
+
* sent on `refresh_token` grants, which are handled by a different backend.
|
|
49
|
+
*/
|
|
50
|
+
export declare const FEDERATION_BETA_HEADER = "oidc-federation-2026-04-01";
|
|
51
|
+
export declare const ADVISORY_REFRESH_THRESHOLD_IN_SECONDS = 120;
|
|
52
|
+
export declare const MANDATORY_REFRESH_THRESHOLD_IN_SECONDS = 30;
|
|
53
|
+
export declare const ADVISORY_REFRESH_BACKOFF_IN_SECONDS = 5;
|
|
54
|
+
/**
|
|
55
|
+
* Rejects base URLs that would cause a JWT assertion or refresh token to be
|
|
56
|
+
* sent over cleartext HTTP. Loopback hosts are allowed for local development.
|
|
57
|
+
*/
|
|
58
|
+
export declare function requireSecureTokenEndpoint(baseURL: string): void;
|
|
59
|
+
/**
|
|
60
|
+
* Reads the response body as text, parses it as a token-endpoint JSON
|
|
61
|
+
* response, validates `access_token` is present, and rejects a non-Bearer
|
|
62
|
+
* `token_type` when one is provided. Reads at most
|
|
63
|
+
* {@link MAX_TOKEN_RESPONSE_BYTES} from the body stream.
|
|
64
|
+
*/
|
|
65
|
+
export declare function parseTokenResponse(resp: Response, requestId: string | null): Promise<TokenEndpointResponse & {
|
|
66
|
+
access_token: string;
|
|
67
|
+
}>;
|
|
68
|
+
/**
|
|
69
|
+
* Returns a redacted copy of a token-endpoint error body for safe inclusion
|
|
70
|
+
* in an exception. Strings are truncated; objects keep only the RFC 6749
|
|
71
|
+
* §5.2 error fields.
|
|
72
|
+
*/
|
|
73
|
+
export declare function redactSensitive(body: unknown): unknown;
|
|
74
|
+
/**
|
|
75
|
+
* Best-effort safety check on a credentials file before reading it.
|
|
76
|
+
*
|
|
77
|
+
* On POSIX: resolves symlinks (so containerized deployments that mount the
|
|
78
|
+
* credential as a symlink to a tmpfs-backed file keep working), then rejects
|
|
79
|
+
* the resolved target if it is group- or world- readable or writable. A uid
|
|
80
|
+
* mismatch on the resolved target is surfaced via `onWarn` since
|
|
81
|
+
* root-written/app-read is common in init-container setups. No-op on Windows.
|
|
82
|
+
*/
|
|
83
|
+
export declare function checkCredentialsFileSafety(path: string, onWarn?: (msg: string) => void): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Atomically writes JSON to `targetPath` via a `.tmp` sibling + rename,
|
|
86
|
+
* with fsync on the file and (best-effort) on the parent directory.
|
|
87
|
+
* Creates the parent directory with mode 0700 and the file with mode 0600.
|
|
88
|
+
*/
|
|
89
|
+
export declare function writeCredentialsFileAtomic(targetPath: string, data: unknown): Promise<void>;
|
|
90
|
+
export declare class WorkloadIdentityError extends AnthropicError {
|
|
91
|
+
readonly statusCode: number | null;
|
|
92
|
+
readonly body: unknown;
|
|
93
|
+
readonly requestId: string | null;
|
|
94
|
+
constructor(message: string, statusCode?: number | null, body?: unknown, requestId?: string | null);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/credentials/types.ts"],"names":[],"mappings":"OAAO,EAAE,cAAc,EAAE;AAEzB,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,kEAAkE;IAClE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,mBAAmB,GAAG,CAAC,IAAI,CAAC,EAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAA;CAAE,KAAK,OAAO,CAAC,WAAW,CAAC,CAAC;AAE9F,MAAM,MAAM,qBAAqB,GAAG,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAEnE,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC9B,CAAC;AAEF,iDAAiD;AACjD,MAAM,MAAM,qBAAqB,GAAG;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,eAAO,MAAM,qBAAqB,gDAAgD,CAAC;AACnF,eAAO,MAAM,wBAAwB,kBAAkB,CAAC;AACxD,eAAO,MAAM,cAAc,oBAAoB,CAAC;AAEhD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,qBAAqB,CAAC;AAExD;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,+BAA+B,CAAC;AAEnE,eAAO,MAAM,qCAAqC,MAAM,CAAC;AACzD,eAAO,MAAM,sCAAsC,KAAK,CAAC;AACzD,eAAO,MAAM,mCAAmC,IAAI,CAAC;AAIrD;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAehE;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,QAAQ,EACd,SAAS,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,qBAAqB,GAAG;IAAE,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA8B3D;AAQD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAoBtD;AAED;;;;;;;;GAQG;AACH,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,MAAM,EACZ,MAAM,GAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAiD,GACzE,OAAO,CAAC,IAAI,CAAC,CAgCf;AAED;;;;GAIG;AACH,wBAAsB,0BAA0B,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAkCjG;AAmCD,qBAAa,qBAAsB,SAAQ,cAAc;IACvD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;gBAGhC,OAAO,EAAE,MAAM,EACf,UAAU,GAAE,MAAM,GAAG,IAAW,EAChC,IAAI,GAAE,OAAc,EACpB,SAAS,GAAE,MAAM,GAAG,IAAW;CAOlC"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.WorkloadIdentityError = exports.ADVISORY_REFRESH_BACKOFF_IN_SECONDS = exports.MANDATORY_REFRESH_THRESHOLD_IN_SECONDS = exports.ADVISORY_REFRESH_THRESHOLD_IN_SECONDS = exports.FEDERATION_BETA_HEADER = exports.OAUTH_API_BETA_HEADER = exports.TOKEN_ENDPOINT = exports.GRANT_TYPE_REFRESH_TOKEN = exports.GRANT_TYPE_JWT_BEARER = void 0;
|
|
37
|
+
exports.requireSecureTokenEndpoint = requireSecureTokenEndpoint;
|
|
38
|
+
exports.parseTokenResponse = parseTokenResponse;
|
|
39
|
+
exports.redactSensitive = redactSensitive;
|
|
40
|
+
exports.checkCredentialsFileSafety = checkCredentialsFileSafety;
|
|
41
|
+
exports.writeCredentialsFileAtomic = writeCredentialsFileAtomic;
|
|
42
|
+
const error_1 = require("../../core/error.js");
|
|
43
|
+
exports.GRANT_TYPE_JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
|
|
44
|
+
exports.GRANT_TYPE_REFRESH_TOKEN = 'refresh_token';
|
|
45
|
+
exports.TOKEN_ENDPOINT = '/v1/oauth/token';
|
|
46
|
+
/**
|
|
47
|
+
* `anthropic-beta` value required on authenticated API requests using an
|
|
48
|
+
* OAuth bearer token, and on `refresh_token` grants against the token endpoint.
|
|
49
|
+
*/
|
|
50
|
+
exports.OAUTH_API_BETA_HEADER = 'oauth-2025-04-20';
|
|
51
|
+
/**
|
|
52
|
+
* `anthropic-beta` value required on jwt-bearer exchanges against the token
|
|
53
|
+
* endpoint. It routes the request to the federation service; it must NOT be
|
|
54
|
+
* sent on `refresh_token` grants, which are handled by a different backend.
|
|
55
|
+
*/
|
|
56
|
+
exports.FEDERATION_BETA_HEADER = 'oidc-federation-2026-04-01';
|
|
57
|
+
exports.ADVISORY_REFRESH_THRESHOLD_IN_SECONDS = 120;
|
|
58
|
+
exports.MANDATORY_REFRESH_THRESHOLD_IN_SECONDS = 30;
|
|
59
|
+
exports.ADVISORY_REFRESH_BACKOFF_IN_SECONDS = 5;
|
|
60
|
+
const MAX_TOKEN_RESPONSE_BYTES = 1 << 20;
|
|
61
|
+
/**
|
|
62
|
+
* Rejects base URLs that would cause a JWT assertion or refresh token to be
|
|
63
|
+
* sent over cleartext HTTP. Loopback hosts are allowed for local development.
|
|
64
|
+
*/
|
|
65
|
+
function requireSecureTokenEndpoint(baseURL) {
|
|
66
|
+
if (!baseURL)
|
|
67
|
+
return;
|
|
68
|
+
let u;
|
|
69
|
+
try {
|
|
70
|
+
u = new URL(baseURL);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
throw new WorkloadIdentityError(`Invalid token endpoint base URL "${baseURL}": ${err}`);
|
|
74
|
+
}
|
|
75
|
+
if (u.protocol === 'https:')
|
|
76
|
+
return;
|
|
77
|
+
// WHATWG URL.hostname returns bracketed IPv6 ("[::1]"); Go's net/url strips them.
|
|
78
|
+
const host = u.hostname.toLowerCase().replace(/^\[|\]$/g, '');
|
|
79
|
+
if (u.protocol === 'http:' && (host === 'localhost' || host === '127.0.0.1' || host === '::1')) {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
throw new WorkloadIdentityError(`Refusing to send credential over non-https token endpoint "${baseURL}"`);
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Reads the response body as text, parses it as a token-endpoint JSON
|
|
86
|
+
* response, validates `access_token` is present, and rejects a non-Bearer
|
|
87
|
+
* `token_type` when one is provided. Reads at most
|
|
88
|
+
* {@link MAX_TOKEN_RESPONSE_BYTES} from the body stream.
|
|
89
|
+
*/
|
|
90
|
+
async function parseTokenResponse(resp, requestId) {
|
|
91
|
+
const text = await readLimitedText(resp);
|
|
92
|
+
let data;
|
|
93
|
+
try {
|
|
94
|
+
data = JSON.parse(text);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
throw new WorkloadIdentityError(`Token endpoint returned non-JSON response (status ${resp.status})`, resp.status, redactSensitive(text), requestId);
|
|
98
|
+
}
|
|
99
|
+
if (!data.access_token) {
|
|
100
|
+
throw new WorkloadIdentityError(`Token endpoint response missing access_token: ${JSON.stringify(redactSensitive(data))}`, resp.status, redactSensitive(data), requestId);
|
|
101
|
+
}
|
|
102
|
+
if (data.token_type && data.token_type.toLowerCase() !== 'bearer') {
|
|
103
|
+
throw new WorkloadIdentityError(`Token endpoint response: unsupported token_type "${data.token_type}" (want Bearer)`, resp.status, redactSensitive(data), requestId);
|
|
104
|
+
}
|
|
105
|
+
return data;
|
|
106
|
+
}
|
|
107
|
+
const MAX_ERROR_BODY_CHARS = 2000;
|
|
108
|
+
// RFC 6749 §5.2 standard error-response fields. Anything else in a token
|
|
109
|
+
// endpoint error body is potentially echoed input (assertion, refresh_token,
|
|
110
|
+
// access_token, …) and is dropped rather than allowlisted-with-exceptions.
|
|
111
|
+
const SAFE_ERROR_KEYS = new Set(['error', 'error_description', 'error_uri']);
|
|
112
|
+
/**
|
|
113
|
+
* Returns a redacted copy of a token-endpoint error body for safe inclusion
|
|
114
|
+
* in an exception. Strings are truncated; objects keep only the RFC 6749
|
|
115
|
+
* §5.2 error fields.
|
|
116
|
+
*/
|
|
117
|
+
function redactSensitive(body) {
|
|
118
|
+
if (body == null)
|
|
119
|
+
return body;
|
|
120
|
+
if (typeof body === 'string') {
|
|
121
|
+
let parsed;
|
|
122
|
+
try {
|
|
123
|
+
parsed = JSON.parse(body);
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
if (body.length <= MAX_ERROR_BODY_CHARS)
|
|
127
|
+
return body;
|
|
128
|
+
return body.slice(0, MAX_ERROR_BODY_CHARS) + `... <${body.length - MAX_ERROR_BODY_CHARS} more chars>`;
|
|
129
|
+
}
|
|
130
|
+
return JSON.stringify(redactSensitive(parsed));
|
|
131
|
+
}
|
|
132
|
+
if (typeof body === 'object' && !Array.isArray(body)) {
|
|
133
|
+
const out = {};
|
|
134
|
+
for (const [k, v] of Object.entries(body)) {
|
|
135
|
+
if (SAFE_ERROR_KEYS.has(k))
|
|
136
|
+
out[k] = v;
|
|
137
|
+
}
|
|
138
|
+
return out;
|
|
139
|
+
}
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Best-effort safety check on a credentials file before reading it.
|
|
144
|
+
*
|
|
145
|
+
* On POSIX: resolves symlinks (so containerized deployments that mount the
|
|
146
|
+
* credential as a symlink to a tmpfs-backed file keep working), then rejects
|
|
147
|
+
* the resolved target if it is group- or world- readable or writable. A uid
|
|
148
|
+
* mismatch on the resolved target is surfaced via `onWarn` since
|
|
149
|
+
* root-written/app-read is common in init-container setups. No-op on Windows.
|
|
150
|
+
*/
|
|
151
|
+
async function checkCredentialsFileSafety(path, onWarn = (m) => console.warn(`anthropic-sdk: ${m}`)) {
|
|
152
|
+
if (typeof process === 'undefined' || process.platform === 'win32')
|
|
153
|
+
return;
|
|
154
|
+
const fs = await Promise.resolve().then(() => __importStar(require('node:fs')));
|
|
155
|
+
let resolved = path;
|
|
156
|
+
let st;
|
|
157
|
+
try {
|
|
158
|
+
resolved = await fs.promises.realpath(path);
|
|
159
|
+
st = await fs.promises.stat(resolved);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
return; // ENOENT etc — let the subsequent read surface a precise error
|
|
163
|
+
}
|
|
164
|
+
const mode = st.mode & 0o777;
|
|
165
|
+
// 0o022 = group/world write; 0o044 = group/world read.
|
|
166
|
+
if (mode & 0o022) {
|
|
167
|
+
throw new WorkloadIdentityError(`Credentials file at ${resolved} is group/world-writable (mode 0o${mode.toString(8)}); ` +
|
|
168
|
+
`this allows other local users to plant tokens. Run \`chmod 600 ${resolved}\`.`);
|
|
169
|
+
}
|
|
170
|
+
if (mode & 0o044) {
|
|
171
|
+
throw new WorkloadIdentityError(`Credentials file at ${resolved} is group/world-readable (mode 0o${mode.toString(8)}); ` +
|
|
172
|
+
`run \`chmod 600 ${resolved}\` before retrying.`);
|
|
173
|
+
}
|
|
174
|
+
if (typeof process.getuid === 'function' && st.uid !== process.getuid()) {
|
|
175
|
+
onWarn(`credentials file at ${resolved} is owned by uid ${st.uid} (current process uid ${process.getuid()}); ` + `verify this is intentional.`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Atomically writes JSON to `targetPath` via a `.tmp` sibling + rename,
|
|
180
|
+
* with fsync on the file and (best-effort) on the parent directory.
|
|
181
|
+
* Creates the parent directory with mode 0700 and the file with mode 0600.
|
|
182
|
+
*/
|
|
183
|
+
async function writeCredentialsFileAtomic(targetPath, data) {
|
|
184
|
+
const fs = await Promise.resolve().then(() => __importStar(require('node:fs')));
|
|
185
|
+
const path = await Promise.resolve().then(() => __importStar(require('node:path')));
|
|
186
|
+
const dir = path.dirname(targetPath);
|
|
187
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
188
|
+
// Unique temp name avoids two concurrent writers (different processes or
|
|
189
|
+
// SDK instances) racing on the same '.tmp' sibling and corrupting each
|
|
190
|
+
// other's bytes mid-write before the rename.
|
|
191
|
+
const tmpPath = `${targetPath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
192
|
+
try {
|
|
193
|
+
const fh = await fs.promises.open(tmpPath, 'w', 0o600);
|
|
194
|
+
try {
|
|
195
|
+
await fh.writeFile(JSON.stringify(data, null, 2));
|
|
196
|
+
await fh.sync();
|
|
197
|
+
}
|
|
198
|
+
finally {
|
|
199
|
+
await fh.close();
|
|
200
|
+
}
|
|
201
|
+
await fs.promises.rename(tmpPath, targetPath);
|
|
202
|
+
}
|
|
203
|
+
catch (err) {
|
|
204
|
+
// Don't leak the temp file if anything between create and rename failed.
|
|
205
|
+
await fs.promises.unlink(tmpPath).catch(() => { });
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
// fsync the parent directory so the rename survives a crash.
|
|
209
|
+
try {
|
|
210
|
+
const dirFh = await fs.promises.open(dir, 'r');
|
|
211
|
+
try {
|
|
212
|
+
await dirFh.sync();
|
|
213
|
+
}
|
|
214
|
+
finally {
|
|
215
|
+
await dirFh.close();
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
catch {
|
|
219
|
+
// Directory fsync is best-effort (unsupported on some platforms, e.g. Windows).
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
async function readLimitedText(resp) {
|
|
223
|
+
if (!resp.body) {
|
|
224
|
+
return '';
|
|
225
|
+
}
|
|
226
|
+
const reader = resp.body.getReader();
|
|
227
|
+
const chunks = [];
|
|
228
|
+
let received = 0;
|
|
229
|
+
for (;;) {
|
|
230
|
+
const { done, value } = await reader.read();
|
|
231
|
+
if (done)
|
|
232
|
+
break;
|
|
233
|
+
if (received + value.length > MAX_TOKEN_RESPONSE_BYTES) {
|
|
234
|
+
const remaining = MAX_TOKEN_RESPONSE_BYTES - received;
|
|
235
|
+
if (remaining > 0)
|
|
236
|
+
chunks.push(value.subarray(0, remaining));
|
|
237
|
+
await reader.cancel();
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
chunks.push(value);
|
|
241
|
+
received += value.length;
|
|
242
|
+
}
|
|
243
|
+
let merged;
|
|
244
|
+
if (chunks.length === 1) {
|
|
245
|
+
merged = chunks[0];
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
merged = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));
|
|
249
|
+
let offset = 0;
|
|
250
|
+
for (const c of chunks) {
|
|
251
|
+
merged.set(c, offset);
|
|
252
|
+
offset += c.length;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
return new TextDecoder('utf-8').decode(merged);
|
|
256
|
+
}
|
|
257
|
+
class WorkloadIdentityError extends error_1.AnthropicError {
|
|
258
|
+
constructor(message, statusCode = null, body = null, requestId = null) {
|
|
259
|
+
super(message);
|
|
260
|
+
this.statusCode = statusCode;
|
|
261
|
+
this.body = body;
|
|
262
|
+
this.requestId = requestId;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.WorkloadIdentityError = WorkloadIdentityError;
|
|
266
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/credentials/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { AnthropicError } from "../../core/error.mjs";
|
|
2
|
+
export const GRANT_TYPE_JWT_BEARER = 'urn:ietf:params:oauth:grant-type:jwt-bearer';
|
|
3
|
+
export const GRANT_TYPE_REFRESH_TOKEN = 'refresh_token';
|
|
4
|
+
export const TOKEN_ENDPOINT = '/v1/oauth/token';
|
|
5
|
+
/**
|
|
6
|
+
* `anthropic-beta` value required on authenticated API requests using an
|
|
7
|
+
* OAuth bearer token, and on `refresh_token` grants against the token endpoint.
|
|
8
|
+
*/
|
|
9
|
+
export const OAUTH_API_BETA_HEADER = 'oauth-2025-04-20';
|
|
10
|
+
/**
|
|
11
|
+
* `anthropic-beta` value required on jwt-bearer exchanges against the token
|
|
12
|
+
* endpoint. It routes the request to the federation service; it must NOT be
|
|
13
|
+
* sent on `refresh_token` grants, which are handled by a different backend.
|
|
14
|
+
*/
|
|
15
|
+
export const FEDERATION_BETA_HEADER = 'oidc-federation-2026-04-01';
|
|
16
|
+
export const ADVISORY_REFRESH_THRESHOLD_IN_SECONDS = 120;
|
|
17
|
+
export const MANDATORY_REFRESH_THRESHOLD_IN_SECONDS = 30;
|
|
18
|
+
export const ADVISORY_REFRESH_BACKOFF_IN_SECONDS = 5;
|
|
19
|
+
const MAX_TOKEN_RESPONSE_BYTES = 1 << 20;
|
|
20
|
+
/**
|
|
21
|
+
* Rejects base URLs that would cause a JWT assertion or refresh token to be
|
|
22
|
+
* sent over cleartext HTTP. Loopback hosts are allowed for local development.
|
|
23
|
+
*/
|
|
24
|
+
export function requireSecureTokenEndpoint(baseURL) {
|
|
25
|
+
if (!baseURL)
|
|
26
|
+
return;
|
|
27
|
+
let u;
|
|
28
|
+
try {
|
|
29
|
+
u = new URL(baseURL);
|
|
30
|
+
}
|
|
31
|
+
catch (err) {
|
|
32
|
+
throw new WorkloadIdentityError(`Invalid token endpoint base URL "${baseURL}": ${err}`);
|
|
33
|
+
}
|
|
34
|
+
if (u.protocol === 'https:')
|
|
35
|
+
return;
|
|
36
|
+
// WHATWG URL.hostname returns bracketed IPv6 ("[::1]"); Go's net/url strips them.
|
|
37
|
+
const host = u.hostname.toLowerCase().replace(/^\[|\]$/g, '');
|
|
38
|
+
if (u.protocol === 'http:' && (host === 'localhost' || host === '127.0.0.1' || host === '::1')) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
throw new WorkloadIdentityError(`Refusing to send credential over non-https token endpoint "${baseURL}"`);
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Reads the response body as text, parses it as a token-endpoint JSON
|
|
45
|
+
* response, validates `access_token` is present, and rejects a non-Bearer
|
|
46
|
+
* `token_type` when one is provided. Reads at most
|
|
47
|
+
* {@link MAX_TOKEN_RESPONSE_BYTES} from the body stream.
|
|
48
|
+
*/
|
|
49
|
+
export async function parseTokenResponse(resp, requestId) {
|
|
50
|
+
const text = await readLimitedText(resp);
|
|
51
|
+
let data;
|
|
52
|
+
try {
|
|
53
|
+
data = JSON.parse(text);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
throw new WorkloadIdentityError(`Token endpoint returned non-JSON response (status ${resp.status})`, resp.status, redactSensitive(text), requestId);
|
|
57
|
+
}
|
|
58
|
+
if (!data.access_token) {
|
|
59
|
+
throw new WorkloadIdentityError(`Token endpoint response missing access_token: ${JSON.stringify(redactSensitive(data))}`, resp.status, redactSensitive(data), requestId);
|
|
60
|
+
}
|
|
61
|
+
if (data.token_type && data.token_type.toLowerCase() !== 'bearer') {
|
|
62
|
+
throw new WorkloadIdentityError(`Token endpoint response: unsupported token_type "${data.token_type}" (want Bearer)`, resp.status, redactSensitive(data), requestId);
|
|
63
|
+
}
|
|
64
|
+
return data;
|
|
65
|
+
}
|
|
66
|
+
const MAX_ERROR_BODY_CHARS = 2000;
|
|
67
|
+
// RFC 6749 §5.2 standard error-response fields. Anything else in a token
|
|
68
|
+
// endpoint error body is potentially echoed input (assertion, refresh_token,
|
|
69
|
+
// access_token, …) and is dropped rather than allowlisted-with-exceptions.
|
|
70
|
+
const SAFE_ERROR_KEYS = new Set(['error', 'error_description', 'error_uri']);
|
|
71
|
+
/**
|
|
72
|
+
* Returns a redacted copy of a token-endpoint error body for safe inclusion
|
|
73
|
+
* in an exception. Strings are truncated; objects keep only the RFC 6749
|
|
74
|
+
* §5.2 error fields.
|
|
75
|
+
*/
|
|
76
|
+
export function redactSensitive(body) {
|
|
77
|
+
if (body == null)
|
|
78
|
+
return body;
|
|
79
|
+
if (typeof body === 'string') {
|
|
80
|
+
let parsed;
|
|
81
|
+
try {
|
|
82
|
+
parsed = JSON.parse(body);
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
if (body.length <= MAX_ERROR_BODY_CHARS)
|
|
86
|
+
return body;
|
|
87
|
+
return body.slice(0, MAX_ERROR_BODY_CHARS) + `... <${body.length - MAX_ERROR_BODY_CHARS} more chars>`;
|
|
88
|
+
}
|
|
89
|
+
return JSON.stringify(redactSensitive(parsed));
|
|
90
|
+
}
|
|
91
|
+
if (typeof body === 'object' && !Array.isArray(body)) {
|
|
92
|
+
const out = {};
|
|
93
|
+
for (const [k, v] of Object.entries(body)) {
|
|
94
|
+
if (SAFE_ERROR_KEYS.has(k))
|
|
95
|
+
out[k] = v;
|
|
96
|
+
}
|
|
97
|
+
return out;
|
|
98
|
+
}
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Best-effort safety check on a credentials file before reading it.
|
|
103
|
+
*
|
|
104
|
+
* On POSIX: resolves symlinks (so containerized deployments that mount the
|
|
105
|
+
* credential as a symlink to a tmpfs-backed file keep working), then rejects
|
|
106
|
+
* the resolved target if it is group- or world- readable or writable. A uid
|
|
107
|
+
* mismatch on the resolved target is surfaced via `onWarn` since
|
|
108
|
+
* root-written/app-read is common in init-container setups. No-op on Windows.
|
|
109
|
+
*/
|
|
110
|
+
export async function checkCredentialsFileSafety(path, onWarn = (m) => console.warn(`anthropic-sdk: ${m}`)) {
|
|
111
|
+
if (typeof process === 'undefined' || process.platform === 'win32')
|
|
112
|
+
return;
|
|
113
|
+
const fs = await import('node:fs');
|
|
114
|
+
let resolved = path;
|
|
115
|
+
let st;
|
|
116
|
+
try {
|
|
117
|
+
resolved = await fs.promises.realpath(path);
|
|
118
|
+
st = await fs.promises.stat(resolved);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return; // ENOENT etc — let the subsequent read surface a precise error
|
|
122
|
+
}
|
|
123
|
+
const mode = st.mode & 0o777;
|
|
124
|
+
// 0o022 = group/world write; 0o044 = group/world read.
|
|
125
|
+
if (mode & 0o022) {
|
|
126
|
+
throw new WorkloadIdentityError(`Credentials file at ${resolved} is group/world-writable (mode 0o${mode.toString(8)}); ` +
|
|
127
|
+
`this allows other local users to plant tokens. Run \`chmod 600 ${resolved}\`.`);
|
|
128
|
+
}
|
|
129
|
+
if (mode & 0o044) {
|
|
130
|
+
throw new WorkloadIdentityError(`Credentials file at ${resolved} is group/world-readable (mode 0o${mode.toString(8)}); ` +
|
|
131
|
+
`run \`chmod 600 ${resolved}\` before retrying.`);
|
|
132
|
+
}
|
|
133
|
+
if (typeof process.getuid === 'function' && st.uid !== process.getuid()) {
|
|
134
|
+
onWarn(`credentials file at ${resolved} is owned by uid ${st.uid} (current process uid ${process.getuid()}); ` + `verify this is intentional.`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Atomically writes JSON to `targetPath` via a `.tmp` sibling + rename,
|
|
139
|
+
* with fsync on the file and (best-effort) on the parent directory.
|
|
140
|
+
* Creates the parent directory with mode 0700 and the file with mode 0600.
|
|
141
|
+
*/
|
|
142
|
+
export async function writeCredentialsFileAtomic(targetPath, data) {
|
|
143
|
+
const fs = await import('node:fs');
|
|
144
|
+
const path = await import('node:path');
|
|
145
|
+
const dir = path.dirname(targetPath);
|
|
146
|
+
await fs.promises.mkdir(dir, { recursive: true, mode: 0o700 });
|
|
147
|
+
// Unique temp name avoids two concurrent writers (different processes or
|
|
148
|
+
// SDK instances) racing on the same '.tmp' sibling and corrupting each
|
|
149
|
+
// other's bytes mid-write before the rename.
|
|
150
|
+
const tmpPath = `${targetPath}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
|
|
151
|
+
try {
|
|
152
|
+
const fh = await fs.promises.open(tmpPath, 'w', 0o600);
|
|
153
|
+
try {
|
|
154
|
+
await fh.writeFile(JSON.stringify(data, null, 2));
|
|
155
|
+
await fh.sync();
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await fh.close();
|
|
159
|
+
}
|
|
160
|
+
await fs.promises.rename(tmpPath, targetPath);
|
|
161
|
+
}
|
|
162
|
+
catch (err) {
|
|
163
|
+
// Don't leak the temp file if anything between create and rename failed.
|
|
164
|
+
await fs.promises.unlink(tmpPath).catch(() => { });
|
|
165
|
+
throw err;
|
|
166
|
+
}
|
|
167
|
+
// fsync the parent directory so the rename survives a crash.
|
|
168
|
+
try {
|
|
169
|
+
const dirFh = await fs.promises.open(dir, 'r');
|
|
170
|
+
try {
|
|
171
|
+
await dirFh.sync();
|
|
172
|
+
}
|
|
173
|
+
finally {
|
|
174
|
+
await dirFh.close();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// Directory fsync is best-effort (unsupported on some platforms, e.g. Windows).
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async function readLimitedText(resp) {
|
|
182
|
+
if (!resp.body) {
|
|
183
|
+
return '';
|
|
184
|
+
}
|
|
185
|
+
const reader = resp.body.getReader();
|
|
186
|
+
const chunks = [];
|
|
187
|
+
let received = 0;
|
|
188
|
+
for (;;) {
|
|
189
|
+
const { done, value } = await reader.read();
|
|
190
|
+
if (done)
|
|
191
|
+
break;
|
|
192
|
+
if (received + value.length > MAX_TOKEN_RESPONSE_BYTES) {
|
|
193
|
+
const remaining = MAX_TOKEN_RESPONSE_BYTES - received;
|
|
194
|
+
if (remaining > 0)
|
|
195
|
+
chunks.push(value.subarray(0, remaining));
|
|
196
|
+
await reader.cancel();
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
chunks.push(value);
|
|
200
|
+
received += value.length;
|
|
201
|
+
}
|
|
202
|
+
let merged;
|
|
203
|
+
if (chunks.length === 1) {
|
|
204
|
+
merged = chunks[0];
|
|
205
|
+
}
|
|
206
|
+
else {
|
|
207
|
+
merged = new Uint8Array(chunks.reduce((n, c) => n + c.length, 0));
|
|
208
|
+
let offset = 0;
|
|
209
|
+
for (const c of chunks) {
|
|
210
|
+
merged.set(c, offset);
|
|
211
|
+
offset += c.length;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return new TextDecoder('utf-8').decode(merged);
|
|
215
|
+
}
|
|
216
|
+
export class WorkloadIdentityError extends AnthropicError {
|
|
217
|
+
constructor(message, statusCode = null, body = null, requestId = null) {
|
|
218
|
+
super(message);
|
|
219
|
+
this.statusCode = statusCode;
|
|
220
|
+
this.body = body;
|
|
221
|
+
this.requestId = requestId;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=types.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.mjs","sourceRoot":"","sources":["../../src/lib/credentials/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Fetch } from "../../internal/builtin-types.mjs";
|
|
2
|
+
import type { AccessTokenProvider } from "./types.mjs";
|
|
3
|
+
export type UserOAuthConfig = {
|
|
4
|
+
credentialsPath: string;
|
|
5
|
+
clientId?: string | undefined;
|
|
6
|
+
baseURL: string;
|
|
7
|
+
fetch: Fetch;
|
|
8
|
+
userAgent?: string | undefined;
|
|
9
|
+
onSafetyWarning?: ((msg: string) => void) | undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Reads a user-oauth credential file. Returns the cached access token while
|
|
13
|
+
* fresh; on expiry performs a `refresh_token` grant and writes the new
|
|
14
|
+
* tokens back to the credentials file (atomic replace, fsync'd).
|
|
15
|
+
*
|
|
16
|
+
* If `clientId` is empty, the access token is treated as static — the
|
|
17
|
+
* credentials file is read on every call but no refresh is attempted, and
|
|
18
|
+
* an expired token without a `refresh_token` raises.
|
|
19
|
+
*/
|
|
20
|
+
export declare function userOAuthProvider(config: UserOAuthConfig): AccessTokenProvider;
|
|
21
|
+
//# sourceMappingURL=user-oauth.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"user-oauth.d.mts","sourceRoot":"","sources":["../../src/lib/credentials/user-oauth.ts"],"names":[],"mappings":"OAAO,KAAK,EAAE,KAAK,EAAE;OAEd,KAAK,EAAE,mBAAmB,EAAE;AAgBnC,MAAM,MAAM,eAAe,GAAG;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,KAAK,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,eAAe,GAAG,mBAAmB,CA2G9E"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Fetch } from "../../internal/builtin-types.js";
|
|
2
|
+
import type { AccessTokenProvider } from "./types.js";
|
|
3
|
+
export type UserOAuthConfig = {
|
|
4
|
+
credentialsPath: string;
|
|
5
|
+
clientId?: string | undefined;
|
|
6
|
+
baseURL: string;
|
|
7
|
+
fetch: Fetch;
|
|
8
|
+
userAgent?: string | undefined;
|
|
9
|
+
onSafetyWarning?: ((msg: string) => void) | undefined;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Reads a user-oauth credential file. Returns the cached access token while
|
|
13
|
+
* fresh; on expiry performs a `refresh_token` grant and writes the new
|
|
14
|
+
* tokens back to the credentials file (atomic replace, fsync'd).
|
|
15
|
+
*
|
|
16
|
+
* If `clientId` is empty, the access token is treated as static — the
|
|
17
|
+
* credentials file is read on every call but no refresh is attempted, and
|
|
18
|
+
* an expired token without a `refresh_token` raises.
|
|
19
|
+
*/
|
|
20
|
+
export declare function userOAuthProvider(config: UserOAuthConfig): AccessTokenProvider;
|
|
21
|
+
//# sourceMappingURL=user-oauth.d.ts.map
|