'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var clientSts = require('@aws-sdk/client-sts'); var credentialProviders = require('@aws-sdk/credential-providers'); var utilArnParser = require('@aws-sdk/util-arn-parser'); function readAwsIntegrationAccountConfig(config) { const accountConfig = { accountId: config.getString("accountId"), accessKeyId: config.getOptionalString("accessKeyId"), secretAccessKey: config.getOptionalString("secretAccessKey"), profile: config.getOptionalString("profile"), roleName: config.getOptionalString("roleName"), region: config.getOptionalString("region"), partition: config.getOptionalString("partition"), externalId: config.getOptionalString("externalId") }; if (accountConfig.accessKeyId && !accountConfig.secretAccessKey) { throw new Error( `AWS integration account ${accountConfig.accountId} has an access key ID configured, but no secret access key.` ); } if (!accountConfig.accessKeyId && accountConfig.secretAccessKey) { throw new Error( `AWS integration account ${accountConfig.accountId} has a secret access key configured, but no access key ID` ); } if (accountConfig.profile && accountConfig.accessKeyId) { throw new Error( `AWS integration account ${accountConfig.accountId} has both an access key ID and a profile configured, but only one must be specified` ); } if (accountConfig.profile && accountConfig.roleName) { throw new Error( `AWS integration account ${accountConfig.accountId} has both an access key ID and a role name configured, but only one must be specified` ); } if (!accountConfig.roleName && accountConfig.externalId) { throw new Error( `AWS integration account ${accountConfig.accountId} has an external ID configured, but no role name.` ); } if (!accountConfig.roleName && accountConfig.region) { throw new Error( `AWS integration account ${accountConfig.accountId} has an STS region configured, but no role name.` ); } if (!accountConfig.roleName && accountConfig.partition) { throw new Error( `AWS integration account ${accountConfig.accountId} has an IAM partition configured, but no role name.` ); } return accountConfig; } function readMainAwsIntegrationAccountConfig(config) { const mainAccountConfig = { accessKeyId: config.getOptionalString("accessKeyId"), secretAccessKey: config.getOptionalString("secretAccessKey"), profile: config.getOptionalString("profile"), region: config.getOptionalString("region") }; if (mainAccountConfig.accessKeyId && !mainAccountConfig.secretAccessKey) { throw new Error( `The main AWS integration account has an access key ID configured, but no secret access key.` ); } if (!mainAccountConfig.accessKeyId && mainAccountConfig.secretAccessKey) { throw new Error( `The main AWS integration account has a secret access key configured, but no access key ID` ); } if (mainAccountConfig.profile && mainAccountConfig.accessKeyId) { throw new Error( `The main AWS integration account has both an access key ID and a profile configured, but only one must be specified` ); } return mainAccountConfig; } function readAwsIntegrationAccountDefaultsConfig(config) { const defaultAccountConfig = { roleName: config.getOptionalString("roleName"), partition: config.getOptionalString("partition"), region: config.getOptionalString("region"), externalId: config.getOptionalString("externalId") }; if (!defaultAccountConfig.roleName && defaultAccountConfig.externalId) { throw new Error( `AWS integration account default configuration has an external ID configured, but no role name.` ); } if (!defaultAccountConfig.roleName && defaultAccountConfig.region) { throw new Error( `AWS integration account default configuration has an STS region configured, but no role name.` ); } if (!defaultAccountConfig.roleName && defaultAccountConfig.partition) { throw new Error( `AWS integration account default configuration has an IAM partition configured, but no role name.` ); } return defaultAccountConfig; } function readAwsIntegrationConfig(config) { var _a; const accounts = (_a = config.getOptionalConfigArray("accounts")) == null ? void 0 : _a.map(readAwsIntegrationAccountConfig); const mainAccount = config.has("mainAccount") ? readMainAwsIntegrationAccountConfig(config.getConfig("mainAccount")) : {}; const accountDefaults = config.has("accountDefaults") ? readAwsIntegrationAccountDefaultsConfig( config.getConfig("accountDefaults") ) : {}; return { accounts: accounts != null ? accounts : [], mainAccount, accountDefaults }; } async function fillInAccountId(credProvider) { if (credProvider.accountId) { return; } const client = new clientSts.STSClient({ region: credProvider.stsRegion, customUserAgent: "backstage-aws-credentials-manager", credentialDefaultProvider: () => credProvider.sdkCredentialProvider }); const resp = await client.send(new clientSts.GetCallerIdentityCommand({})); credProvider.accountId = resp.Account; } function getStaticCredentials(accessKeyId, secretAccessKey) { return async () => { return Promise.resolve({ accessKeyId, secretAccessKey }); }; } function getProfileCredentials(profile, region) { return credentialProviders.fromIni({ profile, clientConfig: { region, customUserAgent: "backstage-aws-credentials-manager" } }); } function getDefaultCredentialsChain() { return credentialProviders.fromNodeProviderChain(); } function getSdkCredentialProvider(config, mainAccountCredProvider) { var _a, _b; if (config.roleName) { const region = (_a = config.region) != null ? _a : "us-east-1"; const partition = (_b = config.partition) != null ? _b : "aws"; return credentialProviders.fromTemporaryCredentials({ masterCredentials: config.accessKeyId ? getStaticCredentials(config.accessKeyId, config.secretAccessKey) : mainAccountCredProvider, params: { RoleArn: `arn:${partition}:iam::${config.accountId}:role/${config.roleName}`, RoleSessionName: "backstage", ExternalId: config.externalId }, clientConfig: { region, customUserAgent: "backstage-aws-credentials-manager" } }); } if (config.accessKeyId) { return getStaticCredentials(config.accessKeyId, config.secretAccessKey); } if (config.profile) { return getProfileCredentials(config.profile, config.region); } return getDefaultCredentialsChain(); } function getMainAccountSdkCredentialProvider(config) { if (config.accessKeyId) { return getStaticCredentials(config.accessKeyId, config.secretAccessKey); } if (config.profile) { return getProfileCredentials(config.profile, config.region); } return getDefaultCredentialsChain(); } class DefaultAwsCredentialsManager { constructor(accountCredentialProviders, accountDefaults, mainAccountCredentialProvider) { this.accountCredentialProviders = accountCredentialProviders; this.accountDefaults = accountDefaults; this.mainAccountCredentialProvider = mainAccountCredentialProvider; } static fromConfig(config) { const awsConfig = config.has("aws") ? readAwsIntegrationConfig(config.getConfig("aws")) : { accounts: [], mainAccount: {}, accountDefaults: {} }; const mainAccountSdkCredProvider = getMainAccountSdkCredentialProvider( awsConfig.mainAccount ); const mainAccountCredProvider = { sdkCredentialProvider: mainAccountSdkCredProvider }; const accountCredProviders = /* @__PURE__ */ new Map(); for (const accountConfig of awsConfig.accounts) { const sdkCredentialProvider = getSdkCredentialProvider( accountConfig, mainAccountSdkCredProvider ); accountCredProviders.set(accountConfig.accountId, { accountId: accountConfig.accountId, stsRegion: accountConfig.region, sdkCredentialProvider }); } return new DefaultAwsCredentialsManager( accountCredProviders, awsConfig.accountDefaults, mainAccountCredProvider ); } /** * Returns an {@link AwsCredentialProvider} for a given AWS account. * * @example * ```ts * const { provider } = await getCredentialProvider({ * accountId: '0123456789012', * }) * * const { provider } = await getCredentialProvider({ * arn: 'arn:aws:ecs:us-west-2:123456789012:service/my-http-service' * }) * ``` * * @param opts - the AWS account ID or AWS resource ARN * @returns A promise of {@link AwsCredentialProvider}. */ async getCredentialProvider(opts) { if (!opts) { return this.mainAccountCredentialProvider; } let accountId = opts.accountId; if (opts.arn && !accountId) { const arnComponents = utilArnParser.parse(opts.arn); accountId = arnComponents.accountId; } if (!accountId) { return this.mainAccountCredentialProvider; } if (this.accountCredentialProviders.has(accountId)) { return this.accountCredentialProviders.get(accountId); } if (this.accountDefaults.roleName) { const config = { accountId, roleName: this.accountDefaults.roleName, partition: this.accountDefaults.partition, region: this.accountDefaults.region, externalId: this.accountDefaults.externalId }; const sdkCredentialProvider = getSdkCredentialProvider( config, this.mainAccountCredentialProvider.sdkCredentialProvider ); const credProvider = { accountId, sdkCredentialProvider }; this.accountCredentialProviders.set(accountId, credProvider); return credProvider; } await fillInAccountId(this.mainAccountCredentialProvider); if (accountId === this.mainAccountCredentialProvider.accountId) { return this.mainAccountCredentialProvider; } throw new Error( `There is no AWS integration that matches ${accountId}. Please add a configuration for this AWS account.` ); } } exports.DefaultAwsCredentialsManager = DefaultAwsCredentialsManager; //# sourceMappingURL=index.cjs.js.map