@stripe/workload-identity 0.0.0-stage → 0.1.0-alpha.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (C) 2011 Ask Bjørn Hansen
2
+ Copyright (C) 2013 Stripe, Inc. (https://stripe.com)
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is
9
+ furnished to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in
12
+ all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,117 @@
1
- # Temporary Holding Version
1
+ # @stripe/workload-identity
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ > **Private preview.** This package and the Stripe workload identity API it
4
+ > depends on are in private preview and may change.
5
+
6
+ Workload identity adapter for [stripe-node](https://github.com/stripe/stripe-node).
7
+
8
+ Currently, it lets an application running on AWS authenticate to Stripe without holding a
9
+ long-lived Stripe secret key. The application proves where it is running instead
10
+ of storing a credential.
11
+
12
+ ## Installation
13
+
14
+ ```sh
15
+ npm install stripe @stripe/workload-identity
16
+ ```
17
+
18
+ ### Node.js version
19
+
20
+ This package requires **Node.js 20 or newer**.
21
+
22
+ ```json
23
+ {"dependencies": {"@aws-sdk/client-sts": "3.952.x"}}
24
+ ```
25
+
26
+
27
+ ## Usage
28
+
29
+ ```js
30
+ import Stripe from 'stripe';
31
+ import {awsWorkloadIdentity} from '@stripe/workload-identity';
32
+
33
+ const client = Stripe.forWorkloadIdentity(
34
+ 'oacli_live_...',
35
+ awsWorkloadIdentity()
36
+ );
37
+
38
+ const customers = await client.customers.list();
39
+ ```
40
+
41
+ Once constructed, the client behaves like any other Stripe client: resources,
42
+ request options, retries, idempotency, and error handling all work the same way.
43
+
44
+ ## What it does
45
+
46
+ `awsWorkloadIdentity()` returns a provider object that Stripe's SDK calls when it
47
+ needs a credential. On each call it asks AWS STS for a freshly signed JSON Web
48
+ Token via `sts:GetWebIdentityToken`, using:
49
+
50
+ | | |
51
+ | --- | --- |
52
+ | Audience | `https://access.stripe.com/wif` |
53
+ | Signing algorithm | `ES384` |
54
+
55
+ Stripe exchanges that token for a short-lived restricted key. This package never
56
+ sees the Stripe credential — it only produces the AWS assertion.
57
+
58
+ Both values can be overridden, e.g. if Stripe asks you to use a different one
59
+ before you've upgraded to a version of this package with a new default:
60
+
61
+ ```js
62
+ awsWorkloadIdentity({audience: '...', signingAlgorithm: '...'});
63
+ ```
64
+
65
+ AWS region and credentials come from the AWS SDK's normal resolution. Any other
66
+ STS client configuration can be passed through the same object:
67
+
68
+ ```js
69
+ awsWorkloadIdentity({region: 'us-west-2'});
70
+ ```
71
+
72
+ Note that `GetWebIdentityToken` is not available on the STS global endpoint, so a
73
+ region must be resolvable.
74
+
75
+ ## Local development, tests, and CI
76
+
77
+ `GetWebIdentityToken` only works on AWS infrastructure with an identity allowed to
78
+ call it. Anywhere else — a laptop, a unit test, a CI runner that is not on AWS —
79
+ use a normal Stripe test API key or a fully mocked Stripe client instead:
80
+
81
+ ```js
82
+ const client = new Stripe(process.env.STRIPE_TEST_API_KEY);
83
+ ```
84
+
85
+ ## Troubleshooting
86
+
87
+ | Error | What to check |
88
+ | --- | --- |
89
+ | `sts:GetWebIdentityToken failed (CredentialsProviderError: ...)` | The process is not running on AWS, or no credentials are resolvable. |
90
+ | `sts:GetWebIdentityToken failed (AccessDeniedException: ...)` | The AWS identity is not allowed to call `sts:GetWebIdentityToken`. |
91
+ | `returned no WebIdentityToken` | AWS answered without a token. Retry; if it persists, contact Stripe support. |
92
+ | `Stripe rejected the workload identity token exchange` | The Stripe client ID is wrong or not enabled for workload identity, or the Dashboard configuration does not trust this workload. |
93
+
94
+ See the [workload identity documentation](../../docs/workload-identity.md) for the
95
+ full guide.
96
+
97
+ ## Releasing
98
+
99
+ This package is versioned and released independently of the core `stripe` package,
100
+ so core releases never republish it and a fix here does not require a core release.
101
+
102
+ 1. Bump `version` in this directory's `package.json` and merge that PR.
103
+ 2. Push a matching tag: `wif-v<version>`, e.g.
104
+
105
+ ```sh
106
+ git tag wif-v0.1.0-alpha.1
107
+ git push origin wif-v0.1.0-alpha.1
108
+ ```
109
+
110
+ CI then builds, typechecks, tests, and publishes. The job refuses to publish if the
111
+ tag and `package.json` versions disagree, and is a no-op if that version is already
112
+ on npm, so re-running it is safe. An `alpha` version publishes under the
113
+ `private-preview` dist-tag, `beta` under `public-preview`, anything else `latest`.
114
+
115
+ ## License
116
+
117
+ MIT
package/cjs/index.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { STSClientConfig } from '@aws-sdk/client-sts';
2
+ export declare const STRIPE_WORKLOAD_IDENTITY_AUDIENCE = "https://access.stripe.com/wif";
3
+ export declare const STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM = "ES384";
4
+ /**
5
+ * The structural contract the Stripe SDK consumes. It is duplicated here rather
6
+ * than imported so that this package does not depend on `stripe`, and `stripe`
7
+ * does not depend on the AWS SDK.
8
+ */
9
+ export interface WorkloadIdentityProvider {
10
+ readonly provider: 'aws';
11
+ getIdentityAssertion(): Promise<string>;
12
+ }
13
+ /** Raised when AWS would not produce a usable workload identity assertion. */
14
+ export declare class AwsWorkloadIdentityError extends Error {
15
+ constructor(message: string, cause?: unknown);
16
+ }
17
+ export interface AwsWorkloadIdentityConfig extends STSClientConfig {
18
+ /**
19
+ * Overrides the JWT audience requested from AWS STS. Defaults to
20
+ * `STRIPE_WORKLOAD_IDENTITY_AUDIENCE`. Only set this if Stripe has told you
21
+ * to use a different value -- an audience Stripe does not expect will cause
22
+ * every token exchange to be rejected.
23
+ */
24
+ audience?: string;
25
+ /**
26
+ * Overrides the JWT signing algorithm requested from AWS STS. Defaults to
27
+ * `STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM`. Only set this if Stripe has
28
+ * told you to use a different value.
29
+ */
30
+ signingAlgorithm?: string;
31
+ }
32
+ /**
33
+ * Builds the AWS workload identity provider for `Stripe.forWorkloadIdentity`.
34
+ *
35
+ * Each call to `getIdentityAssertion()` asks AWS STS for a freshly signed JWT
36
+ * that proves the calling AWS identity. Stripe exchanges that assertion for a
37
+ * short-lived restricted key; this package never sees the Stripe credential.
38
+ *
39
+ */
40
+ export declare function awsWorkloadIdentity(config?: AwsWorkloadIdentityConfig): WorkloadIdentityProvider;
package/cjs/index.js ADDED
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AwsWorkloadIdentityError = exports.STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM = exports.STRIPE_WORKLOAD_IDENTITY_AUDIENCE = void 0;
4
+ exports.awsWorkloadIdentity = awsWorkloadIdentity;
5
+ const client_sts_1 = require("@aws-sdk/client-sts");
6
+ exports.STRIPE_WORKLOAD_IDENTITY_AUDIENCE = 'https://access.stripe.com/wif';
7
+ exports.STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM = 'ES384';
8
+ /** Raised when AWS would not produce a usable workload identity assertion. */
9
+ class AwsWorkloadIdentityError extends Error {
10
+ constructor(message, cause) {
11
+ super(message);
12
+ this.name = 'AwsWorkloadIdentityError';
13
+ this.cause = cause;
14
+ }
15
+ }
16
+ exports.AwsWorkloadIdentityError = AwsWorkloadIdentityError;
17
+ const SETUP_GUIDANCE = 'Check that the process is running on AWS infrastructure with an identity that is allowed to call ' +
18
+ 'sts:GetWebIdentityToken, and that a region is configured (the operation is not available on the STS global endpoint). ' +
19
+ 'For local development, unit tests, and CI that are not running on AWS, use a normal Stripe test API key with ' +
20
+ '`new Stripe(apiKey)` or a fully mocked Stripe client instead.';
21
+ /**
22
+ * Builds the AWS workload identity provider for `Stripe.forWorkloadIdentity`.
23
+ *
24
+ * Each call to `getIdentityAssertion()` asks AWS STS for a freshly signed JWT
25
+ * that proves the calling AWS identity. Stripe exchanges that assertion for a
26
+ * short-lived restricted key; this package never sees the Stripe credential.
27
+ *
28
+ */
29
+ function awsWorkloadIdentity(config = {}) {
30
+ const { audience = exports.STRIPE_WORKLOAD_IDENTITY_AUDIENCE, signingAlgorithm = exports.STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM, ...stsClientConfig } = config;
31
+ const client = new client_sts_1.STSClient(stsClientConfig);
32
+ return {
33
+ provider: 'aws',
34
+ async getIdentityAssertion() {
35
+ let response;
36
+ try {
37
+ response = await client.send(new client_sts_1.GetWebIdentityTokenCommand({
38
+ Audience: [audience],
39
+ SigningAlgorithm: signingAlgorithm,
40
+ }));
41
+ }
42
+ catch (err) {
43
+ throw new AwsWorkloadIdentityError(`Unable to obtain an AWS workload identity assertion: sts:GetWebIdentityToken failed. ${SETUP_GUIDANCE}`, err);
44
+ }
45
+ const token = response?.WebIdentityToken;
46
+ if (typeof token !== 'string' || !token) {
47
+ throw new AwsWorkloadIdentityError('Unable to obtain an AWS workload identity assertion: sts:GetWebIdentityToken returned no WebIdentityToken. ' +
48
+ SETUP_GUIDANCE);
49
+ }
50
+ return token;
51
+ },
52
+ };
53
+ }
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}
package/esm/index.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import { STSClientConfig } from '@aws-sdk/client-sts';
2
+ export declare const STRIPE_WORKLOAD_IDENTITY_AUDIENCE = "https://access.stripe.com/wif";
3
+ export declare const STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM = "ES384";
4
+ /**
5
+ * The structural contract the Stripe SDK consumes. It is duplicated here rather
6
+ * than imported so that this package does not depend on `stripe`, and `stripe`
7
+ * does not depend on the AWS SDK.
8
+ */
9
+ export interface WorkloadIdentityProvider {
10
+ readonly provider: 'aws';
11
+ getIdentityAssertion(): Promise<string>;
12
+ }
13
+ /** Raised when AWS would not produce a usable workload identity assertion. */
14
+ export declare class AwsWorkloadIdentityError extends Error {
15
+ constructor(message: string, cause?: unknown);
16
+ }
17
+ export interface AwsWorkloadIdentityConfig extends STSClientConfig {
18
+ /**
19
+ * Overrides the JWT audience requested from AWS STS. Defaults to
20
+ * `STRIPE_WORKLOAD_IDENTITY_AUDIENCE`. Only set this if Stripe has told you
21
+ * to use a different value -- an audience Stripe does not expect will cause
22
+ * every token exchange to be rejected.
23
+ */
24
+ audience?: string;
25
+ /**
26
+ * Overrides the JWT signing algorithm requested from AWS STS. Defaults to
27
+ * `STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM`. Only set this if Stripe has
28
+ * told you to use a different value.
29
+ */
30
+ signingAlgorithm?: string;
31
+ }
32
+ /**
33
+ * Builds the AWS workload identity provider for `Stripe.forWorkloadIdentity`.
34
+ *
35
+ * Each call to `getIdentityAssertion()` asks AWS STS for a freshly signed JWT
36
+ * that proves the calling AWS identity. Stripe exchanges that assertion for a
37
+ * short-lived restricted key; this package never sees the Stripe credential.
38
+ *
39
+ */
40
+ export declare function awsWorkloadIdentity(config?: AwsWorkloadIdentityConfig): WorkloadIdentityProvider;
package/esm/index.js ADDED
@@ -0,0 +1,48 @@
1
+ import { GetWebIdentityTokenCommand, STSClient, } from '@aws-sdk/client-sts';
2
+ export const STRIPE_WORKLOAD_IDENTITY_AUDIENCE = 'https://access.stripe.com/wif';
3
+ export const STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM = 'ES384';
4
+ /** Raised when AWS would not produce a usable workload identity assertion. */
5
+ export class AwsWorkloadIdentityError extends Error {
6
+ constructor(message, cause) {
7
+ super(message);
8
+ this.name = 'AwsWorkloadIdentityError';
9
+ this.cause = cause;
10
+ }
11
+ }
12
+ const SETUP_GUIDANCE = 'Check that the process is running on AWS infrastructure with an identity that is allowed to call ' +
13
+ 'sts:GetWebIdentityToken, and that a region is configured (the operation is not available on the STS global endpoint). ' +
14
+ 'For local development, unit tests, and CI that are not running on AWS, use a normal Stripe test API key with ' +
15
+ '`new Stripe(apiKey)` or a fully mocked Stripe client instead.';
16
+ /**
17
+ * Builds the AWS workload identity provider for `Stripe.forWorkloadIdentity`.
18
+ *
19
+ * Each call to `getIdentityAssertion()` asks AWS STS for a freshly signed JWT
20
+ * that proves the calling AWS identity. Stripe exchanges that assertion for a
21
+ * short-lived restricted key; this package never sees the Stripe credential.
22
+ *
23
+ */
24
+ export function awsWorkloadIdentity(config = {}) {
25
+ const { audience = STRIPE_WORKLOAD_IDENTITY_AUDIENCE, signingAlgorithm = STRIPE_WORKLOAD_IDENTITY_SIGNING_ALGORITHM, ...stsClientConfig } = config;
26
+ const client = new STSClient(stsClientConfig);
27
+ return {
28
+ provider: 'aws',
29
+ async getIdentityAssertion() {
30
+ let response;
31
+ try {
32
+ response = await client.send(new GetWebIdentityTokenCommand({
33
+ Audience: [audience],
34
+ SigningAlgorithm: signingAlgorithm,
35
+ }));
36
+ }
37
+ catch (err) {
38
+ throw new AwsWorkloadIdentityError(`Unable to obtain an AWS workload identity assertion: sts:GetWebIdentityToken failed. ${SETUP_GUIDANCE}`, err);
39
+ }
40
+ const token = response?.WebIdentityToken;
41
+ if (typeof token !== 'string' || !token) {
42
+ throw new AwsWorkloadIdentityError('Unable to obtain an AWS workload identity assertion: sts:GetWebIdentityToken returned no WebIdentityToken. ' +
43
+ SETUP_GUIDANCE);
44
+ }
45
+ return token;
46
+ },
47
+ };
48
+ }
@@ -0,0 +1 @@
1
+ {"type":"module"}
package/package.json CHANGED
@@ -1,6 +1,66 @@
1
1
  {
2
2
  "name": "@stripe/workload-identity",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.1.0-alpha.1",
4
+ "description": "AWS workload identity adapter for the Stripe Node.js SDK",
5
+ "keywords": [
6
+ "stripe",
7
+ "workload identity",
8
+ "aws",
9
+ "authentication"
10
+ ],
11
+ "homepage": "https://github.com/stripe/stripe-node/tree/master/packages/workload-identity",
12
+ "author": "Stripe <support@stripe.com> (https://stripe.com/)",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/stripe/stripe-node",
16
+ "directory": "packages/workload-identity"
17
+ },
18
+ "bugs": "https://github.com/stripe/stripe-node/issues",
19
+ "license": "MIT",
20
+ "engines": {
21
+ "node": ">=20"
22
+ },
23
+ "main": "cjs/index.js",
24
+ "module": "esm/index.js",
25
+ "types": "cjs/index.d.ts",
26
+ "exports": {
27
+ ".": {
28
+ "import": {
29
+ "types": "./esm/index.d.ts",
30
+ "default": "./esm/index.js"
31
+ },
32
+ "require": {
33
+ "types": "./cjs/index.d.ts",
34
+ "default": "./cjs/index.js"
35
+ }
36
+ }
37
+ },
38
+ "files": [
39
+ "cjs/**/*",
40
+ "esm/**/*",
41
+ "LICENSE",
42
+ "README.md"
43
+ ],
44
+ "dependencies": {
45
+ "@aws-sdk/client-sts": "^3.952.0"
46
+ },
47
+ "devDependencies": {
48
+ "@types/chai": "^4.3.4",
49
+ "@types/mocha": "^10.0.1",
50
+ "@types/node": "~22",
51
+ "chai": "^4.3.6",
52
+ "chai-as-promised": "~7.1.1",
53
+ "mocha": "^8.4.0",
54
+ "ts-node": "^10.9.1",
55
+ "typescript": "^5.9.3"
56
+ },
57
+ "scripts": {
58
+ "clean": "node -e \"for (const d of ['cjs','esm']) require('fs').rmSync(d, {recursive: true, force: true})\"",
59
+ "build": "npm run clean && npm run build:cjs && npm run build:esm",
60
+ "build:cjs": "tsc -p tsconfig.cjs.json && node -e \"require('fs').writeFileSync('cjs/package.json', JSON.stringify({type:'commonjs'}))\"",
61
+ "build:esm": "tsc -p tsconfig.esm.json && node -e \"require('fs').writeFileSync('esm/package.json', JSON.stringify({type:'module'}))\"",
62
+ "typecheck": "tsc -p tsconfig.cjs.json --noEmit",
63
+ "test": "mocha",
64
+ "prepack": "npm run build"
65
+ }
6
66
  }