@keycardai/oauth 0.18.0 → 0.20.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.
Files changed (64) hide show
  1. package/README.md +5 -0
  2. package/dist/cjs/clientCredentials.d.ts +3 -2
  3. package/dist/cjs/clientCredentials.d.ts.map +1 -1
  4. package/dist/cjs/clientCredentials.js +4 -4
  5. package/dist/cjs/clientCredentials.js.map +1 -1
  6. package/dist/cjs/credentials.d.ts +5 -4
  7. package/dist/cjs/credentials.d.ts.map +1 -1
  8. package/dist/cjs/pkce.d.ts.map +1 -1
  9. package/dist/cjs/pkce.js +2 -2
  10. package/dist/cjs/pkce.js.map +1 -1
  11. package/dist/cjs/registration.js +4 -4
  12. package/dist/cjs/registration.js.map +1 -1
  13. package/dist/cjs/server/clientSecret.d.ts +1 -1
  14. package/dist/cjs/server/clientSecret.d.ts.map +1 -1
  15. package/dist/cjs/server/clientSecret.js +28 -19
  16. package/dist/cjs/server/clientSecret.js.map +1 -1
  17. package/dist/cjs/server/eksWorkloadIdentity.d.ts +7 -6
  18. package/dist/cjs/server/eksWorkloadIdentity.d.ts.map +1 -1
  19. package/dist/cjs/server/eksWorkloadIdentity.js +11 -95
  20. package/dist/cjs/server/eksWorkloadIdentity.js.map +1 -1
  21. package/dist/cjs/server/index.d.ts +2 -0
  22. package/dist/cjs/server/index.d.ts.map +1 -1
  23. package/dist/cjs/server/index.js +13 -1
  24. package/dist/cjs/server/index.js.map +1 -1
  25. package/dist/cjs/server/workloadIdentity.d.ts +166 -0
  26. package/dist/cjs/server/workloadIdentity.d.ts.map +1 -0
  27. package/dist/cjs/server/workloadIdentity.js +355 -0
  28. package/dist/cjs/server/workloadIdentity.js.map +1 -0
  29. package/dist/cjs/tokenExchange.d.ts +11 -3
  30. package/dist/cjs/tokenExchange.d.ts.map +1 -1
  31. package/dist/cjs/tokenExchange.js +8 -6
  32. package/dist/cjs/tokenExchange.js.map +1 -1
  33. package/dist/esm/clientCredentials.d.ts +3 -2
  34. package/dist/esm/clientCredentials.d.ts.map +1 -1
  35. package/dist/esm/clientCredentials.js +4 -4
  36. package/dist/esm/clientCredentials.js.map +1 -1
  37. package/dist/esm/credentials.d.ts +5 -4
  38. package/dist/esm/credentials.d.ts.map +1 -1
  39. package/dist/esm/pkce.d.ts.map +1 -1
  40. package/dist/esm/pkce.js +2 -2
  41. package/dist/esm/pkce.js.map +1 -1
  42. package/dist/esm/registration.js +4 -4
  43. package/dist/esm/registration.js.map +1 -1
  44. package/dist/esm/server/clientSecret.d.ts +1 -1
  45. package/dist/esm/server/clientSecret.d.ts.map +1 -1
  46. package/dist/esm/server/clientSecret.js +28 -19
  47. package/dist/esm/server/clientSecret.js.map +1 -1
  48. package/dist/esm/server/eksWorkloadIdentity.d.ts +7 -6
  49. package/dist/esm/server/eksWorkloadIdentity.d.ts.map +1 -1
  50. package/dist/esm/server/eksWorkloadIdentity.js +11 -62
  51. package/dist/esm/server/eksWorkloadIdentity.js.map +1 -1
  52. package/dist/esm/server/index.d.ts +2 -0
  53. package/dist/esm/server/index.d.ts.map +1 -1
  54. package/dist/esm/server/index.js +1 -0
  55. package/dist/esm/server/index.js.map +1 -1
  56. package/dist/esm/server/workloadIdentity.d.ts +166 -0
  57. package/dist/esm/server/workloadIdentity.d.ts.map +1 -0
  58. package/dist/esm/server/workloadIdentity.js +312 -0
  59. package/dist/esm/server/workloadIdentity.js.map +1 -0
  60. package/dist/esm/tokenExchange.d.ts +11 -3
  61. package/dist/esm/tokenExchange.d.ts.map +1 -1
  62. package/dist/esm/tokenExchange.js +8 -6
  63. package/dist/esm/tokenExchange.js.map +1 -1
  64. package/package.json +2 -2
@@ -0,0 +1,166 @@
1
+ import type { ApplicationCredential } from "../credentials.js";
2
+ import type { TokenExchangeRequest } from "../tokenExchange.js";
3
+ /**
4
+ * Source identifiers carried on WorkloadIdentityConfigurationError and
5
+ * WorkloadIdentityRuntimeError, for branching on which token source failed.
6
+ */
7
+ export declare const WORKLOAD_IDENTITY_SOURCE_FILE = "file";
8
+ export declare const WORKLOAD_IDENTITY_SOURCE_GCP_METADATA = "gcp-metadata";
9
+ export declare const WORKLOAD_IDENTITY_SOURCE_FLY = "fly";
10
+ export declare const WORKLOAD_IDENTITY_SOURCE_CUSTOM = "custom";
11
+ /**
12
+ * A workload identity credential or token source was misconfigured at
13
+ * construction: a missing or empty token file, no discovery environment
14
+ * variable set, a missing required audience, or an invalid source.
15
+ *
16
+ * `source` identifies the token source ("file", "gcp-metadata", "fly");
17
+ * undefined when the fault is in the credential itself. The underlying cause,
18
+ * when any, is on `cause`.
19
+ */
20
+ export declare class WorkloadIdentityConfigurationError extends Error {
21
+ readonly source?: string;
22
+ readonly cause?: unknown;
23
+ constructor(message: string, options?: {
24
+ source?: string;
25
+ cause?: unknown;
26
+ });
27
+ }
28
+ /**
29
+ * The subject token could not be obtained at request time: the token file was
30
+ * rotated away or emptied after construction, or the platform endpoint was
31
+ * unreachable. Distinct from WorkloadIdentityConfigurationError, which is a
32
+ * construction-time fault.
33
+ *
34
+ * `source` identifies the token source ("file", "gcp-metadata", "fly", or
35
+ * "custom" for a source whose error is not one of this module's typed
36
+ * errors). The underlying cause, when any, is on `cause`.
37
+ */
38
+ export declare class WorkloadIdentityRuntimeError extends Error {
39
+ readonly source?: string;
40
+ readonly cause?: unknown;
41
+ constructor(message: string, options?: {
42
+ source?: string;
43
+ cause?: unknown;
44
+ });
45
+ }
46
+ /**
47
+ * Supplies a platform-signed OIDC token for use as a client assertion during
48
+ * token exchange. The only per-platform piece of a workload identity
49
+ * credential: {@link FileTokenSource} covers platforms that project the token
50
+ * to a file (EKS, AKS, Kubernetes projected service-account tokens),
51
+ * {@link GCPMetadataTokenSource} covers platforms that serve it from the GCP
52
+ * metadata endpoint (GKE, GCE, Cloud Run), {@link FlyTokenSource} covers Fly
53
+ * Machines, and any bare function returning the token is accepted as a source.
54
+ *
55
+ * `identityToken` is called on every token exchange. Implementations must
56
+ * return the current token; platforms rotate these tokens, so returning a
57
+ * stale cached value risks an expired assertion.
58
+ */
59
+ export interface IdentityTokenSource {
60
+ identityToken(): Promise<string>;
61
+ }
62
+ /** A bare function accepted anywhere a IdentityTokenSource is. */
63
+ export type IdentityTokenFetcher = () => Promise<string> | string;
64
+ export declare const DEFAULT_FILE_TOKEN_ENV_VARS: string[];
65
+ export interface FileTokenSourceOptions {
66
+ /** Explicit token file path, skipping env-var discovery. */
67
+ tokenFilePath?: string;
68
+ /** An environment variable to consult first during discovery. */
69
+ envVarName?: string;
70
+ }
71
+ /** @internal Shared by FileTokenSource and the deprecated EKSWorkloadIdentity. */
72
+ export declare function resolveTokenFilePath(discoveryEnvVars: string[], options?: FileTokenSourceOptions): string;
73
+ /**
74
+ * Reads a platform-projected OIDC token from a mounted file, fresh on every
75
+ * call (platforms rotate projected tokens). Covers EKS pod identity, AKS
76
+ * workload identity, any Kubernetes projected service-account token, and CI
77
+ * providers that write the token to a file.
78
+ *
79
+ * When no explicit path is given, the path is discovered from the first set
80
+ * environment variable: the variable named by `envVarName` when given, then
81
+ * KEYCARD_EKS_WORKLOAD_IDENTITY_TOKEN_FILE, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE,
82
+ * AWS_WEB_IDENTITY_TOKEN_FILE, and AZURE_FEDERATED_TOKEN_FILE.
83
+ *
84
+ * **Requires Node.js.** Validates at construction that the resolved file
85
+ * exists and is non-empty.
86
+ */
87
+ export declare class FileTokenSource implements IdentityTokenSource {
88
+ #private;
89
+ constructor(options?: FileTokenSourceOptions);
90
+ /** Re-reads the token file and returns its trimmed contents. */
91
+ identityToken(): Promise<string>;
92
+ }
93
+ export interface GCPMetadataTokenSourceOptions {
94
+ /** The token audience, typically the Keycard zone URL. Required. */
95
+ audience: string;
96
+ /** Metadata server base URL override (for testing). */
97
+ metadataUrl?: string;
98
+ /** Per-call deadline in milliseconds. */
99
+ timeoutMs?: number;
100
+ }
101
+ /**
102
+ * Fetches an OIDC identity token for the default service account from the
103
+ * GCP metadata server. Covers GKE, GCE, and Cloud Run.
104
+ */
105
+ export declare class GCPMetadataTokenSource implements IdentityTokenSource {
106
+ #private;
107
+ constructor(options: GCPMetadataTokenSourceOptions);
108
+ /** Requests a GCP-signed OIDC JWT from the metadata server. */
109
+ identityToken(): Promise<string>;
110
+ }
111
+ export interface FlyTokenSourceOptions {
112
+ /** The token audience claim, typically the Keycard zone URL. */
113
+ audience?: string;
114
+ /** Machines API socket path override (default /.fly/api). */
115
+ socketPath?: string;
116
+ }
117
+ /**
118
+ * Fetches an OIDC token from the Fly.io Machines API over the local Unix
119
+ * socket. Covers workloads running on Fly Machines.
120
+ *
121
+ * **Requires Node.js** (Unix domain sockets). The socket is not probed at
122
+ * construction; an unreachable Machines API surfaces as a
123
+ * WorkloadIdentityRuntimeError at the first fetch.
124
+ */
125
+ export declare class FlyTokenSource implements IdentityTokenSource {
126
+ #private;
127
+ constructor(options?: FlyTokenSourceOptions);
128
+ /** Requests a Fly-signed OIDC JWT from the Machines API. */
129
+ identityToken(): Promise<string>;
130
+ }
131
+ export interface WorkloadIdentityOptions {
132
+ /**
133
+ * ID of the Keycard application credential this workload authenticates as,
134
+ * sent as the `client_id` form parameter alongside the client assertion.
135
+ * Token-federation application credentials are resolved by this ID, so
136
+ * they require it; legacy token credentials are resolved by the
137
+ * assertion's subject and do not use it.
138
+ */
139
+ clientId?: string;
140
+ }
141
+ /**
142
+ * Workload identity credential using a platform-signed OIDC token obtained
143
+ * from a {@link IdentityTokenSource}. On every token exchange it fetches the
144
+ * current token from the source and attaches it as a jwt-bearer client
145
+ * assertion. It holds no shared secret and never caches the token across
146
+ * requests.
147
+ *
148
+ * @example
149
+ * // EKS / AKS / Kubernetes projected token (path discovered from env)
150
+ * const credential = new WorkloadIdentity(new FileTokenSource());
151
+ *
152
+ * // GKE / GCE / Cloud Run
153
+ * const credential = new WorkloadIdentity(
154
+ * new GCPMetadataTokenSource({ audience: "https://zone.keycard.cloud" }),
155
+ * );
156
+ *
157
+ * // Custom fetch
158
+ * const credential = new WorkloadIdentity(() => fetchMyToken());
159
+ */
160
+ export declare class WorkloadIdentity implements ApplicationCredential {
161
+ #private;
162
+ constructor(source: IdentityTokenSource | IdentityTokenFetcher, options?: WorkloadIdentityOptions);
163
+ getAuth(): null;
164
+ prepareTokenExchangeRequest(subjectToken: string, resource: string): Promise<TokenExchangeRequest>;
165
+ }
166
+ //# sourceMappingURL=workloadIdentity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workloadIdentity.d.ts","sourceRoot":"","sources":["../../../src/server/workloadIdentity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,355 @@
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
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
36
+ if (kind === "m") throw new TypeError("Private method is not writable");
37
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
38
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
39
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
40
+ };
41
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
42
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
43
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
44
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
45
+ };
46
+ var _FileTokenSource_tokenFilePath, _GCPMetadataTokenSource_audience, _GCPMetadataTokenSource_metadataUrl, _GCPMetadataTokenSource_timeoutMs, _FlyTokenSource_audience, _FlyTokenSource_socketPath, _WorkloadIdentity_instances, _WorkloadIdentity_source, _WorkloadIdentity_clientId, _WorkloadIdentity_fetchIdentityToken;
47
+ Object.defineProperty(exports, "__esModule", { value: true });
48
+ exports.WorkloadIdentity = exports.FlyTokenSource = exports.GCPMetadataTokenSource = exports.FileTokenSource = exports.DEFAULT_FILE_TOKEN_ENV_VARS = exports.WorkloadIdentityRuntimeError = exports.WorkloadIdentityConfigurationError = exports.WORKLOAD_IDENTITY_SOURCE_CUSTOM = exports.WORKLOAD_IDENTITY_SOURCE_FLY = exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA = exports.WORKLOAD_IDENTITY_SOURCE_FILE = void 0;
49
+ exports.resolveTokenFilePath = resolveTokenFilePath;
50
+ const fs = __importStar(require("node:fs"));
51
+ /**
52
+ * Source identifiers carried on WorkloadIdentityConfigurationError and
53
+ * WorkloadIdentityRuntimeError, for branching on which token source failed.
54
+ */
55
+ exports.WORKLOAD_IDENTITY_SOURCE_FILE = "file";
56
+ exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA = "gcp-metadata";
57
+ exports.WORKLOAD_IDENTITY_SOURCE_FLY = "fly";
58
+ exports.WORKLOAD_IDENTITY_SOURCE_CUSTOM = "custom";
59
+ /**
60
+ * A workload identity credential or token source was misconfigured at
61
+ * construction: a missing or empty token file, no discovery environment
62
+ * variable set, a missing required audience, or an invalid source.
63
+ *
64
+ * `source` identifies the token source ("file", "gcp-metadata", "fly");
65
+ * undefined when the fault is in the credential itself. The underlying cause,
66
+ * when any, is on `cause`.
67
+ */
68
+ class WorkloadIdentityConfigurationError extends Error {
69
+ constructor(message, options) {
70
+ super(message);
71
+ this.name = "WorkloadIdentityConfigurationError";
72
+ this.source = options?.source;
73
+ this.cause = options?.cause;
74
+ }
75
+ }
76
+ exports.WorkloadIdentityConfigurationError = WorkloadIdentityConfigurationError;
77
+ /**
78
+ * The subject token could not be obtained at request time: the token file was
79
+ * rotated away or emptied after construction, or the platform endpoint was
80
+ * unreachable. Distinct from WorkloadIdentityConfigurationError, which is a
81
+ * construction-time fault.
82
+ *
83
+ * `source` identifies the token source ("file", "gcp-metadata", "fly", or
84
+ * "custom" for a source whose error is not one of this module's typed
85
+ * errors). The underlying cause, when any, is on `cause`.
86
+ */
87
+ class WorkloadIdentityRuntimeError extends Error {
88
+ constructor(message, options) {
89
+ super(message);
90
+ this.name = "WorkloadIdentityRuntimeError";
91
+ this.source = options?.source;
92
+ this.cause = options?.cause;
93
+ }
94
+ }
95
+ exports.WorkloadIdentityRuntimeError = WorkloadIdentityRuntimeError;
96
+ exports.DEFAULT_FILE_TOKEN_ENV_VARS = [
97
+ "KEYCARD_EKS_WORKLOAD_IDENTITY_TOKEN_FILE",
98
+ "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE",
99
+ "AWS_WEB_IDENTITY_TOKEN_FILE",
100
+ "AZURE_FEDERATED_TOKEN_FILE",
101
+ ];
102
+ /** @internal Shared by FileTokenSource and the deprecated EKSWorkloadIdentity. */
103
+ function resolveTokenFilePath(discoveryEnvVars, options) {
104
+ if (options?.tokenFilePath) {
105
+ return options.tokenFilePath;
106
+ }
107
+ const envNames = options?.envVarName
108
+ ? [options.envVarName, ...discoveryEnvVars]
109
+ : discoveryEnvVars;
110
+ const found = envNames.find((name) => process.env[name]);
111
+ if (!found || !process.env[found]) {
112
+ throw new WorkloadIdentityConfigurationError(`Could not find token file path in environment variables; checked: ${envNames.join(", ")}`, { source: exports.WORKLOAD_IDENTITY_SOURCE_FILE });
113
+ }
114
+ return process.env[found];
115
+ }
116
+ function readTokenFile(tokenFilePath, errorClass) {
117
+ let contents;
118
+ try {
119
+ contents = fs.readFileSync(tokenFilePath, "utf-8");
120
+ }
121
+ catch (error) {
122
+ throw new errorClass(`Error reading token file: ${tokenFilePath}`, {
123
+ source: exports.WORKLOAD_IDENTITY_SOURCE_FILE,
124
+ cause: error,
125
+ });
126
+ }
127
+ const token = contents.trim();
128
+ if (!token) {
129
+ throw new errorClass(`Token file is empty: ${tokenFilePath}`, {
130
+ source: exports.WORKLOAD_IDENTITY_SOURCE_FILE,
131
+ });
132
+ }
133
+ return token;
134
+ }
135
+ /**
136
+ * Reads a platform-projected OIDC token from a mounted file, fresh on every
137
+ * call (platforms rotate projected tokens). Covers EKS pod identity, AKS
138
+ * workload identity, any Kubernetes projected service-account token, and CI
139
+ * providers that write the token to a file.
140
+ *
141
+ * When no explicit path is given, the path is discovered from the first set
142
+ * environment variable: the variable named by `envVarName` when given, then
143
+ * KEYCARD_EKS_WORKLOAD_IDENTITY_TOKEN_FILE, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE,
144
+ * AWS_WEB_IDENTITY_TOKEN_FILE, and AZURE_FEDERATED_TOKEN_FILE.
145
+ *
146
+ * **Requires Node.js.** Validates at construction that the resolved file
147
+ * exists and is non-empty.
148
+ */
149
+ class FileTokenSource {
150
+ constructor(options) {
151
+ _FileTokenSource_tokenFilePath.set(this, void 0);
152
+ __classPrivateFieldSet(this, _FileTokenSource_tokenFilePath, resolveTokenFilePath(exports.DEFAULT_FILE_TOKEN_ENV_VARS, options), "f");
153
+ readTokenFile(__classPrivateFieldGet(this, _FileTokenSource_tokenFilePath, "f"), WorkloadIdentityConfigurationError);
154
+ }
155
+ /** Re-reads the token file and returns its trimmed contents. */
156
+ async identityToken() {
157
+ return readTokenFile(__classPrivateFieldGet(this, _FileTokenSource_tokenFilePath, "f"), WorkloadIdentityRuntimeError);
158
+ }
159
+ }
160
+ exports.FileTokenSource = FileTokenSource;
161
+ _FileTokenSource_tokenFilePath = new WeakMap();
162
+ const DEFAULT_GCP_METADATA_URL = "http://metadata.google.internal";
163
+ const DEFAULT_GCP_TIMEOUT_MS = 5000;
164
+ const GCP_IDENTITY_PATH = "/computeMetadata/v1/instance/service-accounts/default/identity";
165
+ /**
166
+ * Fetches an OIDC identity token for the default service account from the
167
+ * GCP metadata server. Covers GKE, GCE, and Cloud Run.
168
+ */
169
+ class GCPMetadataTokenSource {
170
+ constructor(options) {
171
+ _GCPMetadataTokenSource_audience.set(this, void 0);
172
+ _GCPMetadataTokenSource_metadataUrl.set(this, void 0);
173
+ _GCPMetadataTokenSource_timeoutMs.set(this, void 0);
174
+ if (!options.audience || !options.audience.trim()) {
175
+ throw new WorkloadIdentityConfigurationError("audience must not be empty", {
176
+ source: exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA,
177
+ });
178
+ }
179
+ __classPrivateFieldSet(this, _GCPMetadataTokenSource_audience, options.audience, "f");
180
+ __classPrivateFieldSet(this, _GCPMetadataTokenSource_metadataUrl, (options.metadataUrl ?? DEFAULT_GCP_METADATA_URL).replace(/\/$/, ""), "f");
181
+ __classPrivateFieldSet(this, _GCPMetadataTokenSource_timeoutMs, options.timeoutMs ?? DEFAULT_GCP_TIMEOUT_MS, "f");
182
+ }
183
+ /** Requests a GCP-signed OIDC JWT from the metadata server. */
184
+ async identityToken() {
185
+ const url = `${__classPrivateFieldGet(this, _GCPMetadataTokenSource_metadataUrl, "f")}${GCP_IDENTITY_PATH}` +
186
+ `?audience=${encodeURIComponent(__classPrivateFieldGet(this, _GCPMetadataTokenSource_audience, "f"))}&format=full`;
187
+ let response;
188
+ let body;
189
+ try {
190
+ response = await fetch(url, {
191
+ headers: { "Metadata-Flavor": "Google" },
192
+ signal: AbortSignal.timeout(__classPrivateFieldGet(this, _GCPMetadataTokenSource_timeoutMs, "f")),
193
+ });
194
+ body = await response.text();
195
+ }
196
+ catch (error) {
197
+ throw new WorkloadIdentityRuntimeError(`Error calling metadata server at ${__classPrivateFieldGet(this, _GCPMetadataTokenSource_metadataUrl, "f")} (is this running on GCP?)`, { source: exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA, cause: error });
198
+ }
199
+ if (!response.ok) {
200
+ throw new WorkloadIdentityRuntimeError(`Metadata server returned status ${response.status}`, { source: exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA });
201
+ }
202
+ const token = body.trim();
203
+ if (!token) {
204
+ throw new WorkloadIdentityRuntimeError("Metadata server returned an empty token", {
205
+ source: exports.WORKLOAD_IDENTITY_SOURCE_GCP_METADATA,
206
+ });
207
+ }
208
+ return token;
209
+ }
210
+ }
211
+ exports.GCPMetadataTokenSource = GCPMetadataTokenSource;
212
+ _GCPMetadataTokenSource_audience = new WeakMap(), _GCPMetadataTokenSource_metadataUrl = new WeakMap(), _GCPMetadataTokenSource_timeoutMs = new WeakMap();
213
+ const DEFAULT_FLY_SOCKET_PATH = "/.fly/api";
214
+ const FLY_TOKEN_PATH = "/v1/tokens/oidc";
215
+ const FLY_TIMEOUT_MS = 5000;
216
+ /**
217
+ * Fetches an OIDC token from the Fly.io Machines API over the local Unix
218
+ * socket. Covers workloads running on Fly Machines.
219
+ *
220
+ * **Requires Node.js** (Unix domain sockets). The socket is not probed at
221
+ * construction; an unreachable Machines API surfaces as a
222
+ * WorkloadIdentityRuntimeError at the first fetch.
223
+ */
224
+ class FlyTokenSource {
225
+ constructor(options) {
226
+ _FlyTokenSource_audience.set(this, void 0);
227
+ _FlyTokenSource_socketPath.set(this, void 0);
228
+ __classPrivateFieldSet(this, _FlyTokenSource_audience, options?.audience, "f");
229
+ __classPrivateFieldSet(this, _FlyTokenSource_socketPath, options?.socketPath ?? DEFAULT_FLY_SOCKET_PATH, "f");
230
+ }
231
+ /** Requests a Fly-signed OIDC JWT from the Machines API. */
232
+ async identityToken() {
233
+ const http = await Promise.resolve().then(() => __importStar(require("node:http")));
234
+ const payload = JSON.stringify(__classPrivateFieldGet(this, _FlyTokenSource_audience, "f") ? { aud: __classPrivateFieldGet(this, _FlyTokenSource_audience, "f") } : {});
235
+ return new Promise((resolve, reject) => {
236
+ const request = http.request({
237
+ socketPath: __classPrivateFieldGet(this, _FlyTokenSource_socketPath, "f"),
238
+ path: FLY_TOKEN_PATH,
239
+ method: "POST",
240
+ headers: {
241
+ "Content-Type": "application/json",
242
+ "Content-Length": Buffer.byteLength(payload),
243
+ },
244
+ timeout: FLY_TIMEOUT_MS,
245
+ }, (response) => {
246
+ const chunks = [];
247
+ response.on("data", (chunk) => chunks.push(chunk));
248
+ response.on("end", () => {
249
+ if (response.statusCode !== 200) {
250
+ reject(new WorkloadIdentityRuntimeError(`Machines API returned status ${response.statusCode}`, { source: exports.WORKLOAD_IDENTITY_SOURCE_FLY }));
251
+ return;
252
+ }
253
+ const token = Buffer.concat(chunks).toString("utf-8").trim();
254
+ if (!token) {
255
+ reject(new WorkloadIdentityRuntimeError("Machines API returned an empty token", {
256
+ source: exports.WORKLOAD_IDENTITY_SOURCE_FLY,
257
+ }));
258
+ return;
259
+ }
260
+ resolve(token);
261
+ });
262
+ });
263
+ request.on("error", (error) => {
264
+ if (error instanceof WorkloadIdentityRuntimeError) {
265
+ reject(error);
266
+ return;
267
+ }
268
+ reject(new WorkloadIdentityRuntimeError(`Error calling Machines API socket ${__classPrivateFieldGet(this, _FlyTokenSource_socketPath, "f")} (is this running on a Fly Machine?)`, { source: exports.WORKLOAD_IDENTITY_SOURCE_FLY, cause: error }));
269
+ });
270
+ request.on("timeout", () => {
271
+ request.destroy(new WorkloadIdentityRuntimeError(`Machines API request timed out after ${FLY_TIMEOUT_MS}ms`, { source: exports.WORKLOAD_IDENTITY_SOURCE_FLY }));
272
+ });
273
+ request.write(payload);
274
+ request.end();
275
+ });
276
+ }
277
+ }
278
+ exports.FlyTokenSource = FlyTokenSource;
279
+ _FlyTokenSource_audience = new WeakMap(), _FlyTokenSource_socketPath = new WeakMap();
280
+ /**
281
+ * Workload identity credential using a platform-signed OIDC token obtained
282
+ * from a {@link IdentityTokenSource}. On every token exchange it fetches the
283
+ * current token from the source and attaches it as a jwt-bearer client
284
+ * assertion. It holds no shared secret and never caches the token across
285
+ * requests.
286
+ *
287
+ * @example
288
+ * // EKS / AKS / Kubernetes projected token (path discovered from env)
289
+ * const credential = new WorkloadIdentity(new FileTokenSource());
290
+ *
291
+ * // GKE / GCE / Cloud Run
292
+ * const credential = new WorkloadIdentity(
293
+ * new GCPMetadataTokenSource({ audience: "https://zone.keycard.cloud" }),
294
+ * );
295
+ *
296
+ * // Custom fetch
297
+ * const credential = new WorkloadIdentity(() => fetchMyToken());
298
+ */
299
+ class WorkloadIdentity {
300
+ constructor(source, options) {
301
+ _WorkloadIdentity_instances.add(this);
302
+ _WorkloadIdentity_source.set(this, void 0);
303
+ _WorkloadIdentity_clientId.set(this, void 0);
304
+ if (source == null) {
305
+ throw new WorkloadIdentityConfigurationError("identity token source must not be null");
306
+ }
307
+ if (typeof source !== "function" &&
308
+ typeof source.identityToken !== "function") {
309
+ throw new WorkloadIdentityConfigurationError("identity token source must provide identityToken() or be a function");
310
+ }
311
+ __classPrivateFieldSet(this, _WorkloadIdentity_source, source, "f");
312
+ __classPrivateFieldSet(this, _WorkloadIdentity_clientId, options?.clientId, "f");
313
+ }
314
+ getAuth() {
315
+ return null;
316
+ }
317
+ async prepareTokenExchangeRequest(subjectToken, resource) {
318
+ const assertion = await __classPrivateFieldGet(this, _WorkloadIdentity_instances, "m", _WorkloadIdentity_fetchIdentityToken).call(this);
319
+ return {
320
+ subjectToken,
321
+ resource,
322
+ subjectTokenType: "urn:ietf:params:oauth:token-type:access_token",
323
+ clientAssertionType: "urn:ietf:params:oauth:client-assertion-type:jwt-bearer",
324
+ clientAssertion: assertion,
325
+ clientId: __classPrivateFieldGet(this, _WorkloadIdentity_clientId, "f"),
326
+ };
327
+ }
328
+ }
329
+ exports.WorkloadIdentity = WorkloadIdentity;
330
+ _WorkloadIdentity_source = new WeakMap(), _WorkloadIdentity_clientId = new WeakMap(), _WorkloadIdentity_instances = new WeakSet(), _WorkloadIdentity_fetchIdentityToken = async function _WorkloadIdentity_fetchIdentityToken() {
331
+ let token;
332
+ try {
333
+ token =
334
+ typeof __classPrivateFieldGet(this, _WorkloadIdentity_source, "f") === "function"
335
+ ? await __classPrivateFieldGet(this, _WorkloadIdentity_source, "f").call(this)
336
+ : await __classPrivateFieldGet(this, _WorkloadIdentity_source, "f").identityToken();
337
+ }
338
+ catch (error) {
339
+ if (error instanceof WorkloadIdentityConfigurationError ||
340
+ error instanceof WorkloadIdentityRuntimeError) {
341
+ throw error;
342
+ }
343
+ throw new WorkloadIdentityRuntimeError("Error fetching identity token", {
344
+ source: exports.WORKLOAD_IDENTITY_SOURCE_CUSTOM,
345
+ cause: error,
346
+ });
347
+ }
348
+ if (typeof token !== "string" || !token.trim()) {
349
+ throw new WorkloadIdentityRuntimeError("Identity token source returned an empty token", {
350
+ source: exports.WORKLOAD_IDENTITY_SOURCE_CUSTOM,
351
+ });
352
+ }
353
+ return token;
354
+ };
355
+ //# sourceMappingURL=workloadIdentity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workloadIdentity.js","sourceRoot":"","sources":["../../../src/server/workloadIdentity.ts"],"names":[],"mappings":"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"}
@@ -20,6 +20,12 @@ export interface TokenExchangeRequest {
20
20
  actorTokenType?: string;
21
21
  clientAssertion?: string;
22
22
  clientAssertionType?: string;
23
+ /**
24
+ * Names the application credential the client authenticates as, sent as
25
+ * the client_id form parameter. Used with assertion-based credentials that
26
+ * are resolved by ID rather than by the assertion's subject.
27
+ */
28
+ clientId?: string;
23
29
  }
24
30
  export interface TokenResponse {
25
31
  accessToken: string;
@@ -37,18 +43,20 @@ export interface TokenExchangeClientOptions {
37
43
  /**
38
44
  * Application credential provider. When set, takes precedence over
39
45
  * static `clientId`/`clientSecret` and resolves the per-request
40
- * Authorization header from the credential's `getAuth(zoneId)`.
46
+ * Authorization header from the credential's `getAuth(issuer)`.
41
47
  */
42
48
  credential?: ApplicationCredential;
43
49
  }
44
50
  export interface ExchangeOptions {
45
- zoneId?: string;
51
+ /** Zone issuer URL used to select per-zone credentials. */
52
+ issuer?: string;
46
53
  }
47
54
  export interface ImpersonateRequest {
48
55
  userIdentifier: string;
49
56
  resource: string;
50
57
  scope?: string;
51
- zoneId?: string;
58
+ /** Zone issuer URL used to select per-zone credentials. */
59
+ issuer?: string;
52
60
  }
53
61
  export declare function deserializeTokenResponse(json: Record<string, unknown>): TokenResponse;
54
62
  export declare class TokenExchangeClient {
@@ -1 +1 @@
1
- {"version":3,"file":"tokenExchange.d.ts","sourceRoot":"","sources":["../../src/tokenExchange.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAO9D,eAAO,MAAM,SAAS;;IAEpB;;;OAGG;;CAEK,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAyBD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAqBrF;AAMD,qBAAa,mBAAmB;;gBAQlB,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAO1D,aAAa,CACjB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,aAAa,CAAC;IA8CnB,WAAW,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IA+BlE;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAuB1C"}
1
+ {"version":3,"file":"tokenExchange.d.ts","sourceRoot":"","sources":["../../src/tokenExchange.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAO9D,eAAO,MAAM,SAAS;;IAEpB;;;OAGG;;CAEK,CAAC;AACX,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,SAAS,CAAC,CAAC,MAAM,OAAO,SAAS,CAAC,CAAC;AAEnE,MAAM,WAAW,oBAAoB;IACnC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,qBAAqB,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,cAAc,EAAE,MAAM,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA0BD,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,aAAa,CAqBrF;AAMD,qBAAa,mBAAmB;;gBAQlB,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,0BAA0B;IAO1D,aAAa,CACjB,OAAO,EAAE,oBAAoB,EAC7B,OAAO,CAAC,EAAE,eAAe,GACxB,OAAO,CAAC,aAAa,CAAC;IA+CnB,WAAW,CAAC,GAAG,EAAE,kBAAkB,GAAG,OAAO,CAAC,aAAa,CAAC;IA+BlE;;;;OAIG;IACG,gBAAgB,IAAI,OAAO,CAAC,MAAM,CAAC;CAuB1C"}
@@ -52,12 +52,14 @@ function serializeRequest(request) {
52
52
  params.set("client_assertion", request.clientAssertion);
53
53
  if (request.clientAssertionType)
54
54
  params.set("client_assertion_type", request.clientAssertionType);
55
+ if (request.clientId)
56
+ params.set("client_id", request.clientId);
55
57
  return params;
56
58
  }
57
59
  function deserializeTokenResponse(json) {
58
60
  const accessToken = json.access_token;
59
61
  if (typeof accessToken !== "string" || !accessToken) {
60
- throw new Error("Token exchange response missing access_token");
62
+ throw new errors_js_1.OAuthError("invalid_response", "Token response missing access_token");
61
63
  }
62
64
  const response = {
63
65
  accessToken,
@@ -100,7 +102,7 @@ class TokenExchangeClient {
100
102
  const headers = {
101
103
  "Content-Type": "application/x-www-form-urlencoded",
102
104
  };
103
- const basicAuth = __classPrivateFieldGet(this, _TokenExchangeClient_instances, "m", _TokenExchangeClient_resolveBasicAuth).call(this, options?.zoneId);
105
+ const basicAuth = __classPrivateFieldGet(this, _TokenExchangeClient_instances, "m", _TokenExchangeClient_resolveBasicAuth).call(this, options?.issuer);
104
106
  if (basicAuth) {
105
107
  const credentials = btoa(`${basicAuth.clientId}:${basicAuth.clientSecret}`);
106
108
  headers["Authorization"] = `Basic ${credentials}`;
@@ -129,7 +131,7 @@ class TokenExchangeClient {
129
131
  throw e;
130
132
  // non-JSON or no "error" key — fall through
131
133
  }
132
- throw new Error(`Token exchange failed (HTTP ${response.status})`);
134
+ throw new errors_js_1.OAuthError("invalid_response", `Token exchange failed (HTTP ${response.status})`);
133
135
  }
134
136
  const json = await response.json();
135
137
  return deserializeTokenResponse(json);
@@ -147,7 +149,7 @@ class TokenExchangeClient {
147
149
  subjectTokenType: exports.TokenType.SUBSTITUTE_USER,
148
150
  resource: req.resource,
149
151
  scope: req.scope,
150
- }, { zoneId: req.zoneId });
152
+ }, { issuer: req.issuer });
151
153
  }
152
154
  /**
153
155
  * Resolve the authorization server's token endpoint (discovered from metadata
@@ -159,9 +161,9 @@ class TokenExchangeClient {
159
161
  }
160
162
  }
161
163
  exports.TokenExchangeClient = TokenExchangeClient;
162
- _TokenExchangeClient_issuer = new WeakMap(), _TokenExchangeClient_clientId = new WeakMap(), _TokenExchangeClient_clientSecret = new WeakMap(), _TokenExchangeClient_credential = new WeakMap(), _TokenExchangeClient_tokenEndpoint = new WeakMap(), _TokenExchangeClient_discoveryPromise = new WeakMap(), _TokenExchangeClient_instances = new WeakSet(), _TokenExchangeClient_resolveBasicAuth = function _TokenExchangeClient_resolveBasicAuth(zoneId) {
164
+ _TokenExchangeClient_issuer = new WeakMap(), _TokenExchangeClient_clientId = new WeakMap(), _TokenExchangeClient_clientSecret = new WeakMap(), _TokenExchangeClient_credential = new WeakMap(), _TokenExchangeClient_tokenEndpoint = new WeakMap(), _TokenExchangeClient_discoveryPromise = new WeakMap(), _TokenExchangeClient_instances = new WeakSet(), _TokenExchangeClient_resolveBasicAuth = function _TokenExchangeClient_resolveBasicAuth(issuer) {
163
165
  if (__classPrivateFieldGet(this, _TokenExchangeClient_credential, "f")) {
164
- return __classPrivateFieldGet(this, _TokenExchangeClient_credential, "f").getAuth(zoneId);
166
+ return __classPrivateFieldGet(this, _TokenExchangeClient_credential, "f").getAuth(issuer);
165
167
  }
166
168
  if (__classPrivateFieldGet(this, _TokenExchangeClient_clientId, "f") && __classPrivateFieldGet(this, _TokenExchangeClient_clientSecret, "f")) {
167
169
  return { clientId: __classPrivateFieldGet(this, _TokenExchangeClient_clientId, "f"), clientSecret: __classPrivateFieldGet(this, _TokenExchangeClient_clientSecret, "f") };