@backstage/integration-aws-node 0.1.15 → 0.1.16

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 CHANGED
@@ -1,5 +1,23 @@
1
1
  # @backstage/integration-aws-node
2
2
 
3
+ ## 0.1.16
4
+
5
+ ### Patch Changes
6
+
7
+ - db4630e: Fixed bug in DefaultAwsCredentialsManager where aws.mainAccount.region has no effect on the STS region used for account ID lookup during credential provider lookup when falling back to the main account, and it does not default to us-east-1
8
+ - Updated dependencies
9
+ - @backstage/config@1.3.2
10
+ - @backstage/errors@1.2.7
11
+
12
+ ## 0.1.16-next.0
13
+
14
+ ### Patch Changes
15
+
16
+ - db4630e: Fixed bug in DefaultAwsCredentialsManager where aws.mainAccount.region has no effect on the STS region used for account ID lookup during credential provider lookup when falling back to the main account, and it does not default to us-east-1
17
+ - Updated dependencies
18
+ - @backstage/config@1.3.2
19
+ - @backstage/errors@1.2.7
20
+
3
21
  ## 0.1.15
4
22
 
5
23
  ### Patch Changes
@@ -10,7 +10,7 @@ async function fillInAccountId(credProvider) {
10
10
  return;
11
11
  }
12
12
  const client = new clientSts.STSClient({
13
- region: credProvider.stsRegion,
13
+ region: credProvider.stsRegion ?? "us-east-1",
14
14
  customUserAgent: "backstage-aws-credentials-manager",
15
15
  credentialDefaultProvider: () => credProvider.sdkCredentialProvider
16
16
  });
@@ -87,6 +87,7 @@ class DefaultAwsCredentialsManager {
87
87
  awsConfig.mainAccount
88
88
  );
89
89
  const mainAccountCredProvider = {
90
+ stsRegion: awsConfig.mainAccount.region,
90
91
  sdkCredentialProvider: mainAccountSdkCredProvider
91
92
  };
92
93
  const accountCredProviders = /* @__PURE__ */ new Map();
@@ -1 +1 @@
1
- {"version":3,"file":"DefaultAwsCredentialsManager.cjs.js","sources":["../src/DefaultAwsCredentialsManager.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n readAwsIntegrationConfig,\n AwsIntegrationAccountConfig,\n AwsIntegrationDefaultAccountConfig,\n AwsIntegrationMainAccountConfig,\n} from './config';\nimport {\n AwsCredentialsManager,\n AwsCredentialProvider,\n AwsCredentialProviderOptions,\n} from './types';\nimport { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';\nimport {\n fromIni,\n fromNodeProviderChain,\n fromTemporaryCredentials,\n} from '@aws-sdk/credential-providers';\nimport { AwsCredentialIdentityProvider } from '@aws-sdk/types';\nimport { parse } from '@aws-sdk/util-arn-parser';\nimport { Config } from '@backstage/config';\n\n/**\n * Retrieves the account ID for the given credential provider from STS.\n */\nasync function fillInAccountId(credProvider: AwsCredentialProvider) {\n if (credProvider.accountId) {\n return;\n }\n\n const client = new STSClient({\n region: credProvider.stsRegion,\n customUserAgent: 'backstage-aws-credentials-manager',\n credentialDefaultProvider: () => credProvider.sdkCredentialProvider,\n });\n const resp = await client.send(new GetCallerIdentityCommand({}));\n credProvider.accountId = resp.Account!;\n}\n\nfunction getStaticCredentials(\n accessKeyId: string,\n secretAccessKey: string,\n): AwsCredentialIdentityProvider {\n return async () => {\n return Promise.resolve({\n accessKeyId: accessKeyId,\n secretAccessKey: secretAccessKey,\n });\n };\n}\n\nfunction getProfileCredentials(\n profile: string,\n region?: string,\n): AwsCredentialIdentityProvider {\n return fromIni({\n profile,\n clientConfig: {\n region,\n customUserAgent: 'backstage-aws-credentials-manager',\n },\n });\n}\n\n/**\n * Include the region if present, otherwise use the default region.\n *\n * @see https://www.npmjs.com/package/@aws-sdk/credential-provider-node\n */\nfunction getDefaultCredentialsChain(\n region = 'us-east-1',\n): AwsCredentialIdentityProvider {\n return fromNodeProviderChain({ clientConfig: { region } });\n}\n\n/**\n * Constructs the credential provider needed by the AWS SDK from the given account config\n *\n * Order of precedence:\n * 1. Assume role with static creds\n * 2. Assume role with main account creds\n * 3. Static creds\n * 4. Profile creds\n * 5. Default AWS SDK creds chain\n */\nfunction getSdkCredentialProvider(\n config: AwsIntegrationAccountConfig,\n mainAccountCredProvider: AwsCredentialIdentityProvider,\n): AwsCredentialIdentityProvider {\n if (config.roleName) {\n const region = config.region ?? 'us-east-1';\n const partition = config.partition ?? 'aws';\n\n return fromTemporaryCredentials({\n masterCredentials: config.accessKeyId\n ? getStaticCredentials(config.accessKeyId!, config.secretAccessKey!)\n : mainAccountCredProvider,\n params: {\n RoleArn: `arn:${partition}:iam::${config.accountId}:role/${config.roleName}`,\n RoleSessionName: 'backstage',\n ExternalId: config.externalId,\n },\n clientConfig: {\n region,\n customUserAgent: 'backstage-aws-credentials-manager',\n },\n });\n }\n\n if (config.accessKeyId) {\n return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);\n }\n\n if (config.profile) {\n return getProfileCredentials(config.profile!, config.region);\n }\n\n return getDefaultCredentialsChain(config.region);\n}\n\n/**\n * Constructs the credential provider needed by the AWS SDK for the main account\n *\n * Order of precedence:\n * 1. Static creds\n * 2. Profile creds\n * 3. Default AWS SDK creds chain\n */\nfunction getMainAccountSdkCredentialProvider(\n config: AwsIntegrationMainAccountConfig,\n): AwsCredentialIdentityProvider {\n if (config.accessKeyId) {\n return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);\n }\n\n if (config.profile) {\n return getProfileCredentials(config.profile!, config.region);\n }\n\n return getDefaultCredentialsChain(config.region);\n}\n\n/**\n * Handles the creation and caching of credential providers for AWS accounts.\n *\n * @public\n */\nexport class DefaultAwsCredentialsManager implements AwsCredentialsManager {\n static fromConfig(config: Config): DefaultAwsCredentialsManager {\n const awsConfig = config.has('aws')\n ? readAwsIntegrationConfig(config.getConfig('aws'))\n : {\n accounts: [],\n mainAccount: {},\n accountDefaults: {},\n };\n\n const mainAccountSdkCredProvider = getMainAccountSdkCredentialProvider(\n awsConfig.mainAccount,\n );\n const mainAccountCredProvider: AwsCredentialProvider = {\n sdkCredentialProvider: mainAccountSdkCredProvider,\n };\n\n const accountCredProviders = new Map<string, AwsCredentialProvider>();\n for (const accountConfig of awsConfig.accounts) {\n const sdkCredentialProvider = getSdkCredentialProvider(\n accountConfig,\n mainAccountSdkCredProvider,\n );\n accountCredProviders.set(accountConfig.accountId, {\n accountId: accountConfig.accountId,\n stsRegion: accountConfig.region,\n sdkCredentialProvider,\n });\n }\n\n return new DefaultAwsCredentialsManager(\n accountCredProviders,\n awsConfig.accountDefaults,\n mainAccountCredProvider,\n );\n }\n\n private constructor(\n private readonly accountCredentialProviders: Map<\n string,\n AwsCredentialProvider\n >,\n private readonly accountDefaults: AwsIntegrationDefaultAccountConfig,\n private readonly mainAccountCredentialProvider: AwsCredentialProvider,\n ) {}\n\n /**\n * Returns an {@link AwsCredentialProvider} for a given AWS account.\n *\n * @example\n * ```ts\n * const { provider } = await getCredentialProvider({\n * accountId: '0123456789012',\n * })\n *\n * const { provider } = await getCredentialProvider({\n * arn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service'\n * })\n * ```\n *\n * @param opts - the AWS account ID or AWS resource ARN\n * @returns A promise of {@link AwsCredentialProvider}.\n */\n async getCredentialProvider(\n opts?: AwsCredentialProviderOptions,\n ): Promise<AwsCredentialProvider> {\n // If no options provided, fall back to the main account\n if (!opts) {\n return this.mainAccountCredentialProvider;\n }\n\n // Determine the account ID: either explicitly provided or extracted from the provided ARN\n let accountId = opts.accountId;\n if (opts.arn && !accountId) {\n const arnComponents = parse(opts.arn);\n accountId = arnComponents.accountId;\n }\n\n // If the account ID was not provided (explicitly or in the ARN),\n // fall back to the main account\n if (!accountId) {\n return this.mainAccountCredentialProvider;\n }\n\n // Return a cached provider if available\n if (this.accountCredentialProviders.has(accountId)) {\n return this.accountCredentialProviders.get(accountId)!;\n }\n\n // First, fall back to using the account defaults\n if (this.accountDefaults.roleName) {\n const config: AwsIntegrationAccountConfig = {\n accountId,\n roleName: this.accountDefaults.roleName,\n partition: this.accountDefaults.partition,\n region: this.accountDefaults.region,\n externalId: this.accountDefaults.externalId,\n };\n const sdkCredentialProvider = getSdkCredentialProvider(\n config,\n this.mainAccountCredentialProvider.sdkCredentialProvider,\n );\n const credProvider: AwsCredentialProvider = {\n accountId,\n sdkCredentialProvider,\n };\n this.accountCredentialProviders.set(accountId, credProvider);\n return credProvider;\n }\n\n // Then, fall back to using the main account, but only\n // if the account requested matches the main account ID\n await fillInAccountId(this.mainAccountCredentialProvider);\n if (accountId === this.mainAccountCredentialProvider.accountId) {\n return this.mainAccountCredentialProvider;\n }\n\n // Otherwise, the account needs to be explicitly configured in Backstage\n throw new Error(\n `There is no AWS integration that matches ${accountId}. Please add a configuration for this AWS account.`,\n );\n }\n}\n"],"names":["STSClient","GetCallerIdentityCommand","fromIni","fromNodeProviderChain","fromTemporaryCredentials","config","readAwsIntegrationConfig","parse"],"mappings":"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"}
1
+ {"version":3,"file":"DefaultAwsCredentialsManager.cjs.js","sources":["../src/DefaultAwsCredentialsManager.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n readAwsIntegrationConfig,\n AwsIntegrationAccountConfig,\n AwsIntegrationDefaultAccountConfig,\n AwsIntegrationMainAccountConfig,\n} from './config';\nimport {\n AwsCredentialsManager,\n AwsCredentialProvider,\n AwsCredentialProviderOptions,\n} from './types';\nimport { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';\nimport {\n fromIni,\n fromNodeProviderChain,\n fromTemporaryCredentials,\n} from '@aws-sdk/credential-providers';\nimport { AwsCredentialIdentityProvider } from '@aws-sdk/types';\nimport { parse } from '@aws-sdk/util-arn-parser';\nimport { Config } from '@backstage/config';\n\n/**\n * Retrieves the account ID for the given credential provider from STS.\n * Include the region if present, otherwise use the default region.\n */\nasync function fillInAccountId(credProvider: AwsCredentialProvider) {\n if (credProvider.accountId) {\n return;\n }\n\n const client = new STSClient({\n region: credProvider.stsRegion ?? 'us-east-1',\n customUserAgent: 'backstage-aws-credentials-manager',\n credentialDefaultProvider: () => credProvider.sdkCredentialProvider,\n });\n const resp = await client.send(new GetCallerIdentityCommand({}));\n credProvider.accountId = resp.Account!;\n}\n\nfunction getStaticCredentials(\n accessKeyId: string,\n secretAccessKey: string,\n): AwsCredentialIdentityProvider {\n return async () => {\n return Promise.resolve({\n accessKeyId: accessKeyId,\n secretAccessKey: secretAccessKey,\n });\n };\n}\n\nfunction getProfileCredentials(\n profile: string,\n region?: string,\n): AwsCredentialIdentityProvider {\n return fromIni({\n profile,\n clientConfig: {\n region,\n customUserAgent: 'backstage-aws-credentials-manager',\n },\n });\n}\n\n/**\n * Include the region if present, otherwise use the default region.\n *\n * @see https://www.npmjs.com/package/@aws-sdk/credential-provider-node\n */\nfunction getDefaultCredentialsChain(\n region = 'us-east-1',\n): AwsCredentialIdentityProvider {\n return fromNodeProviderChain({ clientConfig: { region } });\n}\n\n/**\n * Constructs the credential provider needed by the AWS SDK from the given account config\n *\n * Order of precedence:\n * 1. Assume role with static creds\n * 2. Assume role with main account creds\n * 3. Static creds\n * 4. Profile creds\n * 5. Default AWS SDK creds chain\n */\nfunction getSdkCredentialProvider(\n config: AwsIntegrationAccountConfig,\n mainAccountCredProvider: AwsCredentialIdentityProvider,\n): AwsCredentialIdentityProvider {\n if (config.roleName) {\n const region = config.region ?? 'us-east-1';\n const partition = config.partition ?? 'aws';\n\n return fromTemporaryCredentials({\n masterCredentials: config.accessKeyId\n ? getStaticCredentials(config.accessKeyId!, config.secretAccessKey!)\n : mainAccountCredProvider,\n params: {\n RoleArn: `arn:${partition}:iam::${config.accountId}:role/${config.roleName}`,\n RoleSessionName: 'backstage',\n ExternalId: config.externalId,\n },\n clientConfig: {\n region,\n customUserAgent: 'backstage-aws-credentials-manager',\n },\n });\n }\n\n if (config.accessKeyId) {\n return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);\n }\n\n if (config.profile) {\n return getProfileCredentials(config.profile!, config.region);\n }\n\n return getDefaultCredentialsChain(config.region);\n}\n\n/**\n * Constructs the credential provider needed by the AWS SDK for the main account\n *\n * Order of precedence:\n * 1. Static creds\n * 2. Profile creds\n * 3. Default AWS SDK creds chain\n */\nfunction getMainAccountSdkCredentialProvider(\n config: AwsIntegrationMainAccountConfig,\n): AwsCredentialIdentityProvider {\n if (config.accessKeyId) {\n return getStaticCredentials(config.accessKeyId!, config.secretAccessKey!);\n }\n\n if (config.profile) {\n return getProfileCredentials(config.profile!, config.region);\n }\n\n return getDefaultCredentialsChain(config.region);\n}\n\n/**\n * Handles the creation and caching of credential providers for AWS accounts.\n *\n * @public\n */\nexport class DefaultAwsCredentialsManager implements AwsCredentialsManager {\n static fromConfig(config: Config): DefaultAwsCredentialsManager {\n const awsConfig = config.has('aws')\n ? readAwsIntegrationConfig(config.getConfig('aws'))\n : {\n accounts: [],\n mainAccount: {},\n accountDefaults: {},\n };\n\n const mainAccountSdkCredProvider = getMainAccountSdkCredentialProvider(\n awsConfig.mainAccount,\n );\n const mainAccountCredProvider: AwsCredentialProvider = {\n stsRegion: awsConfig.mainAccount.region,\n sdkCredentialProvider: mainAccountSdkCredProvider,\n };\n\n const accountCredProviders = new Map<string, AwsCredentialProvider>();\n for (const accountConfig of awsConfig.accounts) {\n const sdkCredentialProvider = getSdkCredentialProvider(\n accountConfig,\n mainAccountSdkCredProvider,\n );\n accountCredProviders.set(accountConfig.accountId, {\n accountId: accountConfig.accountId,\n stsRegion: accountConfig.region,\n sdkCredentialProvider,\n });\n }\n\n return new DefaultAwsCredentialsManager(\n accountCredProviders,\n awsConfig.accountDefaults,\n mainAccountCredProvider,\n );\n }\n\n private constructor(\n private readonly accountCredentialProviders: Map<\n string,\n AwsCredentialProvider\n >,\n private readonly accountDefaults: AwsIntegrationDefaultAccountConfig,\n private readonly mainAccountCredentialProvider: AwsCredentialProvider,\n ) {}\n\n /**\n * Returns an {@link AwsCredentialProvider} for a given AWS account.\n *\n * @example\n * ```ts\n * const { provider } = await getCredentialProvider({\n * accountId: '0123456789012',\n * })\n *\n * const { provider } = await getCredentialProvider({\n * arn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service'\n * })\n * ```\n *\n * @param opts - the AWS account ID or AWS resource ARN\n * @returns A promise of {@link AwsCredentialProvider}.\n */\n async getCredentialProvider(\n opts?: AwsCredentialProviderOptions,\n ): Promise<AwsCredentialProvider> {\n // If no options provided, fall back to the main account\n if (!opts) {\n return this.mainAccountCredentialProvider;\n }\n\n // Determine the account ID: either explicitly provided or extracted from the provided ARN\n let accountId = opts.accountId;\n if (opts.arn && !accountId) {\n const arnComponents = parse(opts.arn);\n accountId = arnComponents.accountId;\n }\n\n // If the account ID was not provided (explicitly or in the ARN),\n // fall back to the main account\n if (!accountId) {\n return this.mainAccountCredentialProvider;\n }\n\n // Return a cached provider if available\n if (this.accountCredentialProviders.has(accountId)) {\n return this.accountCredentialProviders.get(accountId)!;\n }\n\n // First, fall back to using the account defaults\n if (this.accountDefaults.roleName) {\n const config: AwsIntegrationAccountConfig = {\n accountId,\n roleName: this.accountDefaults.roleName,\n partition: this.accountDefaults.partition,\n region: this.accountDefaults.region,\n externalId: this.accountDefaults.externalId,\n };\n const sdkCredentialProvider = getSdkCredentialProvider(\n config,\n this.mainAccountCredentialProvider.sdkCredentialProvider,\n );\n const credProvider: AwsCredentialProvider = {\n accountId,\n sdkCredentialProvider,\n };\n this.accountCredentialProviders.set(accountId, credProvider);\n return credProvider;\n }\n\n // Then, fall back to using the main account, but only\n // if the account requested matches the main account ID\n await fillInAccountId(this.mainAccountCredentialProvider);\n if (accountId === this.mainAccountCredentialProvider.accountId) {\n return this.mainAccountCredentialProvider;\n }\n\n // Otherwise, the account needs to be explicitly configured in Backstage\n throw new Error(\n `There is no AWS integration that matches ${accountId}. Please add a configuration for this AWS account.`,\n );\n }\n}\n"],"names":["STSClient","GetCallerIdentityCommand","fromIni","fromNodeProviderChain","fromTemporaryCredentials","config","readAwsIntegrationConfig","parse"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/integration-aws-node",
3
- "version": "0.1.15",
3
+ "version": "0.1.16",
4
4
  "description": "Helpers for fetching AWS account credentials",
5
5
  "backstage": {
6
6
  "role": "node-library"
@@ -45,17 +45,17 @@
45
45
  "@backstage/errors": "^1.2.7"
46
46
  },
47
47
  "devDependencies": {
48
- "@backstage/cli": "^0.29.5",
49
- "@backstage/config-loader": "^1.9.5",
50
- "@backstage/test-utils": "^1.7.4",
48
+ "@backstage/cli": "^0.32.1",
49
+ "@backstage/config-loader": "^1.10.1",
50
+ "@backstage/test-utils": "^1.7.8",
51
51
  "aws-sdk-client-mock": "^4.0.0",
52
52
  "aws-sdk-client-mock-jest": "^4.0.0"
53
53
  },
54
54
  "configSchema": "config.d.ts",
55
55
  "typesVersions": {
56
56
  "*": {
57
- "index": [
58
- "dist/index.d.ts"
57
+ "package.json": [
58
+ "package.json"
59
59
  ]
60
60
  }
61
61
  },