From c69e03ce3dd66a35f88c19c488f5a4bd5d9978e1 Mon Sep 17 00:00:00 2001 From: Roland Fuszenecker Date: Mon, 30 Mar 2026 20:34:14 +0200 Subject: [PATCH 1/3] feat(backend-defaults): add AWS RDS IAM authentication support for PostgreSQL Signed-off-by: Roland Fuszenecker --- .../backend-defaults-aws-rds-iam-auth.md | 5 + packages/backend-defaults/config.d.ts | 29 ++ packages/backend-defaults/package.json | 1 + .../database/connectors/postgres.test.ts | 196 ++++++++++ .../database/connectors/postgres.ts | 52 +++ yarn.lock | 334 ++++++++++++++++++ 6 files changed, 617 insertions(+) create mode 100644 .changeset/backend-defaults-aws-rds-iam-auth.md diff --git a/.changeset/backend-defaults-aws-rds-iam-auth.md b/.changeset/backend-defaults-aws-rds-iam-auth.md new file mode 100644 index 0000000000..7f364ab001 --- /dev/null +++ b/.changeset/backend-defaults-aws-rds-iam-auth.md @@ -0,0 +1,5 @@ +--- +'@backstage/backend-defaults': minor +--- + +Added support for AWS RDS IAM authentication for PostgreSQL connections. Set `connection.type: rds` along with `host`, `user`, and `region` to use short-lived IAM tokens instead of a static password. Requires the `@aws-sdk/rds-signer` package and an IAM role with `rds-db:connect` permission. diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 3d09146b0d..1ff45e6679 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -632,6 +632,35 @@ export interface Config { */ ipAddressType?: 'PUBLIC' | 'PRIVATE' | 'PSC'; } + | { + /** + * The specific config for AWS RDS connections with IAM authentication. + * Requires the `@aws-sdk/rds-signer` package to be installed. + * The IAM role or user must have the `rds-db:connect` permission for the database user. + */ + type: 'rds'; + /** + * The hostname of the RDS instance. + */ + host: string; + /** + * The port number the database is listening on. Defaults to 5432. + */ + port?: number; + /** + * The database user to authenticate as. This user must have the `rds_iam` role granted. + */ + user: string; + /** + * The AWS region where the RDS instance is located. + * Falls back to the AWS_REGION or AWS_DEFAULT_REGION environment variables if not set. + */ + region?: string; + /** + * Other connection settings + */ + [key: string]: unknown; + } | { /** * The rest config for default, regular connections diff --git a/packages/backend-defaults/package.json b/packages/backend-defaults/package.json index 33a262aadd..158ae1d05e 100644 --- a/packages/backend-defaults/package.json +++ b/packages/backend-defaults/package.json @@ -130,6 +130,7 @@ "@aws-sdk/client-codecommit": "^3.350.0", "@aws-sdk/client-s3": "^3.350.0", "@aws-sdk/credential-providers": "^3.350.0", + "@aws-sdk/rds-signer": "^3.0.0", "@aws-sdk/types": "^3.347.0", "@azure/identity": "^4.0.0", "@azure/storage-blob": "^12.5.0", diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts index 7205fbd2f5..e095a17e11 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts @@ -26,6 +26,7 @@ import { type Knex } from 'knex'; jest.mock('@google-cloud/cloud-sql-connector'); jest.mock('@azure/identity'); +jest.mock('@aws-sdk/rds-signer'); describe('postgres', () => { const createMockConnection = () => ({ @@ -587,6 +588,201 @@ describe('postgres', () => { }); }); + it('uses the correct config when using rds IAM auth', async () => { + const { Signer } = jest.requireMock('@aws-sdk/rds-signer') as jest.Mocked< + typeof import('@aws-sdk/rds-signer') + >; + + Signer.prototype.getAuthToken.mockResolvedValue('mock-iam-token'); + + const configResult = await buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, + user: 'postgres', + region: 'eu-west-1', + }, + }), + ); + + expect(Signer).toHaveBeenCalledWith({ + hostname: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, + username: 'postgres', + region: 'eu-west-1', + }); + expect(configResult).toMatchObject({ + client: 'pg', + connection: expect.any(Function), + useNullAsDefault: true, + }); + + const connectionResult = await ( + configResult.connection as () => Promise + )(); + + expect(connectionResult).toMatchObject({ + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, + user: 'postgres', + password: 'mock-iam-token', + }); + expect(connectionResult).not.toHaveProperty('type'); + expect(connectionResult).not.toHaveProperty('region'); + }); + + it('generates a fresh IAM token on each connection factory call', async () => { + const { Signer } = jest.requireMock('@aws-sdk/rds-signer') as jest.Mocked< + typeof import('@aws-sdk/rds-signer') + >; + + Signer.prototype.getAuthToken + .mockResolvedValueOnce('token-1') + .mockResolvedValueOnce('token-2'); + + const configResult = await buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + user: 'postgres', + region: 'eu-west-1', + }, + }), + ); + + const conn1 = await (configResult.connection as () => Promise)(); + const conn2 = await (configResult.connection as () => Promise)(); + + expect(conn1.password).toBe('token-1'); + expect(conn2.password).toBe('token-2'); + }); + + it('defaults port to 5432 for rds connections', async () => { + const { Signer } = jest.requireMock('@aws-sdk/rds-signer') as jest.Mocked< + typeof import('@aws-sdk/rds-signer') + >; + + Signer.prototype.getAuthToken.mockResolvedValue('mock-iam-token'); + + await buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + user: 'postgres', + region: 'eu-west-1', + }, + }), + ); + + expect(Signer).toHaveBeenCalledWith( + expect.objectContaining({ port: 5432 }), + ); + }); + + it('falls back to AWS_REGION env var when region is not set in config', async () => { + const { Signer } = jest.requireMock('@aws-sdk/rds-signer') as jest.Mocked< + typeof import('@aws-sdk/rds-signer') + >; + + Signer.prototype.getAuthToken.mockResolvedValue('mock-iam-token'); + + const originalRegion = process.env.AWS_REGION; + process.env.AWS_REGION = 'us-east-1'; + + try { + await buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.us-east-1.rds.amazonaws.com', + user: 'postgres', + }, + }), + ); + + expect(Signer).toHaveBeenCalledWith( + expect.objectContaining({ region: 'us-east-1' }), + ); + } finally { + if (originalRegion === undefined) { + delete process.env.AWS_REGION; + } else { + process.env.AWS_REGION = originalRegion; + } + } + }); + + it('throws when host is missing for rds connection', async () => { + await expect( + buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + user: 'postgres', + region: 'eu-west-1', + }, + }), + ), + ).rejects.toThrow( + /Missing host in connection config for AWS RDS IAM auth/, + ); + }); + + it('throws when user is missing for rds connection', async () => { + await expect( + buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + region: 'eu-west-1', + }, + }), + ), + ).rejects.toThrow( + /Missing user in connection config for AWS RDS IAM auth/, + ); + }); + + it('throws when region is missing and no env var is set for rds connection', async () => { + const originalRegion = process.env.AWS_REGION; + const originalDefaultRegion = process.env.AWS_DEFAULT_REGION; + delete process.env.AWS_REGION; + delete process.env.AWS_DEFAULT_REGION; + + try { + await expect( + buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + user: 'postgres', + }, + }), + ), + ).rejects.toThrow(/Missing region for AWS RDS IAM auth/); + } finally { + if (originalRegion !== undefined) { + process.env.AWS_REGION = originalRegion; + } + if (originalDefaultRegion !== undefined) { + process.env.AWS_DEFAULT_REGION = originalDefaultRegion; + } + } + }); + it('throws an error when the connection type is not supported', async () => { await expect( buildPgDatabaseConfig( diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts index afc2125c00..53e00e863c 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts @@ -108,6 +108,8 @@ export async function buildPgDatabaseConfig( return buildAzurePgConfig(mergedConfigReader); case 'cloudsql': return buildCloudSqlConfig(mergedConfigReader); + case 'rds': + return buildRdsPgConfig(mergedConfigReader); default: throw new Error(`Unknown connection type: ${config.connection.type}`); } @@ -271,6 +273,56 @@ export async function buildCloudSqlConfig( }; } +export async function buildRdsPgConfig(config: Config): Promise { + const { Signer } = + require('@aws-sdk/rds-signer') as typeof import('@aws-sdk/rds-signer'); + + const rawConfig = config.get() as Record; + const normalized = normalizeConnection(rawConfig.connection as any); + const sanitizedConnection = omit(normalized, [ + 'type', + 'region', + ]) as Partial; + + const hostname = (normalized as any).host as string; + if (!hostname) { + throw new Error('Missing host in connection config for AWS RDS IAM auth'); + } + const port = ((normalized as any).port as number | undefined) ?? 5432; + const username = (normalized as any).user as string; + if (!username) { + throw new Error('Missing user in connection config for AWS RDS IAM auth'); + } + const region = + ((normalized as any).region as string | undefined) ?? + process.env.AWS_REGION ?? + process.env.AWS_DEFAULT_REGION; + if (!region) { + throw new Error( + 'Missing region for AWS RDS IAM auth: set connection.region or the AWS_REGION environment variable', + ); + } + + const signer = new Signer({ hostname, port, username, region }); + + async function getConnectionConfig() { + try { + const password = await signer.getAuthToken(); + return { ...sanitizedConnection, password }; + } catch (err) { + console.error( + `AWS RDS IAM auth token acquisition failed for ${username}@${hostname}:${port}: ${err}`, + ); + throw err; + } + } + + return { + ...(rawConfig as Record), + connection: getConnectionConfig, + }; +} + /** * Gets the postgres connection config * diff --git a/yarn.lock b/yarn.lock index 13b51ed309..73a2ea7da1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -585,6 +585,53 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/client-cognito-identity@npm:3.1022.0": + version: 3.1022.0 + resolution: "@aws-sdk/client-cognito-identity@npm:3.1022.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/credential-provider-node": "npm:^3.972.29" + "@aws-sdk/middleware-host-header": "npm:^3.972.8" + "@aws-sdk/middleware-logger": "npm:^3.972.8" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" + "@aws-sdk/middleware-user-agent": "npm:^3.972.28" + "@aws-sdk/region-config-resolver": "npm:^3.972.10" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" + "@aws-sdk/util-user-agent-node": "npm:^3.973.14" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/core": "npm:^3.23.13" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/hash-node": "npm:^4.2.12" + "@smithy/invalid-dependency": "npm:^4.2.12" + "@smithy/middleware-content-length": "npm:^4.2.12" + "@smithy/middleware-endpoint": "npm:^4.4.28" + "@smithy/middleware-retry": "npm:^4.4.46" + "@smithy/middleware-serde": "npm:^4.2.16" + "@smithy/middleware-stack": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/node-http-handler": "npm:^4.5.1" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.8" + "@smithy/types": "npm:^4.13.1" + "@smithy/url-parser": "npm:^4.2.12" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-body-length-browser": "npm:^4.2.2" + "@smithy/util-body-length-node": "npm:^4.2.3" + "@smithy/util-defaults-mode-browser": "npm:^4.3.44" + "@smithy/util-defaults-mode-node": "npm:^4.2.48" + "@smithy/util-endpoints": "npm:^3.3.3" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-retry": "npm:^4.2.13" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/569321ecde471b530ce4af6b2b2145a8500293de109ed9625ce1d09532723573b224c0e74bdcce5664d6fdbee9c0f8cd2ae2704c169b544054fed3c4dab35f02 + languageName: node + linkType: hard + "@aws-sdk/client-eks@npm:^3.350.0": version: 3.1020.0 resolution: "@aws-sdk/client-eks@npm:3.1020.0" @@ -931,6 +978,19 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-cognito-identity@npm:^3.972.21": + version: 3.972.21 + resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.972.21" + dependencies: + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/8ce7358427e39502ad664e549233ee19ff766340894391bfe31fd500af3a6bd63d1d871a6d154c69edac8fb241465161eb9739ce57fb8a7de5689767e0e01878 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-env@npm:^3.972.24": version: 3.972.24 resolution: "@aws-sdk/credential-provider-env@npm:3.972.24" @@ -984,6 +1044,28 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-ini@npm:^3.972.28": + version: 3.972.28 + resolution: "@aws-sdk/credential-provider-ini@npm:3.972.28" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/credential-provider-env": "npm:^3.972.24" + "@aws-sdk/credential-provider-http": "npm:^3.972.26" + "@aws-sdk/credential-provider-login": "npm:^3.972.28" + "@aws-sdk/credential-provider-process": "npm:^3.972.24" + "@aws-sdk/credential-provider-sso": "npm:^3.972.28" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.28" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/credential-provider-imds": "npm:^4.2.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/4a961738da0487acc4b72de413321e35941550ca85d6b3afa2103a896c093ee530eacbf905a2286c40a3fab387ba62ef0fa05173d49f3aeef2a1fcd403a8b29b + languageName: node + linkType: hard + "@aws-sdk/credential-provider-login@npm:^3.972.27": version: 3.972.27 resolution: "@aws-sdk/credential-provider-login@npm:3.972.27" @@ -1000,6 +1082,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-login@npm:^3.972.28": + version: 3.972.28 + resolution: "@aws-sdk/credential-provider-login@npm:3.972.28" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/075c680e352140fd678434cb29d05dfb5016f1a8e1eda8cfe6b39f0b72c52e374d53f63ccd9e35088d3bd26de9201c20020ea7dfbe2e3afc17cec52c139297b5 + languageName: node + linkType: hard + "@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/credential-provider-node@npm:3.972.28" @@ -1020,6 +1118,26 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-node@npm:^3.972.29": + version: 3.972.29 + resolution: "@aws-sdk/credential-provider-node@npm:3.972.29" + dependencies: + "@aws-sdk/credential-provider-env": "npm:^3.972.24" + "@aws-sdk/credential-provider-http": "npm:^3.972.26" + "@aws-sdk/credential-provider-ini": "npm:^3.972.28" + "@aws-sdk/credential-provider-process": "npm:^3.972.24" + "@aws-sdk/credential-provider-sso": "npm:^3.972.28" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.28" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/credential-provider-imds": "npm:^4.2.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/99e64f9719146104ef4f1484654ceefd7ca821b328f488c305159e4d9b81e9205e5ccafb5f7eb50a2872fcb58bc28131945d8dc71fc4d988009bc5c8c757251b + languageName: node + linkType: hard + "@aws-sdk/credential-provider-process@npm:^3.972.24": version: 3.972.24 resolution: "@aws-sdk/credential-provider-process@npm:3.972.24" @@ -1050,6 +1168,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-sso@npm:^3.972.28": + version: 3.972.28 + resolution: "@aws-sdk/credential-provider-sso@npm:3.972.28" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/token-providers": "npm:3.1021.0" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/440c07e329f5112a9ff637f2b595fbae21001fb0255183e3713630ac38e3de35cfa84beac49d78da4ef9684a9f78a3cbeac13e7f48c7da1df6e1390dbf3bc28b + languageName: node + linkType: hard + "@aws-sdk/credential-provider-web-identity@npm:^3.972.27": version: 3.972.27 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.27" @@ -1065,6 +1199,49 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/credential-provider-web-identity@npm:^3.972.28": + version: 3.972.28 + resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.28" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/9578e46e5b2a08a0f49b02807f4dfe20e22da01ff9b2c70fa54680efda4106817497c461e2dd2caa7a5226658519ec6c98c808adb33993e61aac5061e3470f28 + languageName: node + linkType: hard + +"@aws-sdk/credential-providers@npm:3.1022.0": + version: 3.1022.0 + resolution: "@aws-sdk/credential-providers@npm:3.1022.0" + dependencies: + "@aws-sdk/client-cognito-identity": "npm:3.1022.0" + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/credential-provider-cognito-identity": "npm:^3.972.21" + "@aws-sdk/credential-provider-env": "npm:^3.972.24" + "@aws-sdk/credential-provider-http": "npm:^3.972.26" + "@aws-sdk/credential-provider-ini": "npm:^3.972.28" + "@aws-sdk/credential-provider-login": "npm:^3.972.28" + "@aws-sdk/credential-provider-node": "npm:^3.972.29" + "@aws-sdk/credential-provider-process": "npm:^3.972.24" + "@aws-sdk/credential-provider-sso": "npm:^3.972.28" + "@aws-sdk/credential-provider-web-identity": "npm:^3.972.28" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/core": "npm:^3.23.13" + "@smithy/credential-provider-imds": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/387292596f496320e8e74264acadf242eb3c6261caf4c8b5f94c9a15c6b8c0b9040e252e2fe7a1fa24b7cd2a68c8b8e9242fad00ed61e333b33d8003bf89c293 + languageName: node + linkType: hard + "@aws-sdk/credential-providers@npm:^3.350.0": version: 3.1020.0 resolution: "@aws-sdk/credential-providers@npm:3.1020.0" @@ -1302,6 +1479,22 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/middleware-user-agent@npm:^3.972.28": + version: 3.972.28 + resolution: "@aws-sdk/middleware-user-agent@npm:3.972.28" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@smithy/core": "npm:^3.23.13" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-retry": "npm:^4.2.13" + tslib: "npm:^2.6.2" + checksum: 10/1f5668ea362c98cbfe2ec17d71a47792b8f78c1d5ba77b2a9ef10614528b8f704fb11df74fdf6d9199799341171eed6b7710b56ac927df43343c06df15dd2e74 + languageName: node + linkType: hard + "@aws-sdk/nested-clients@npm:^3.996.17": version: 3.996.17 resolution: "@aws-sdk/nested-clients@npm:3.996.17" @@ -1348,6 +1541,52 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/nested-clients@npm:^3.996.18": + version: 3.996.18 + resolution: "@aws-sdk/nested-clients@npm:3.996.18" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/middleware-host-header": "npm:^3.972.8" + "@aws-sdk/middleware-logger": "npm:^3.972.8" + "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" + "@aws-sdk/middleware-user-agent": "npm:^3.972.28" + "@aws-sdk/region-config-resolver": "npm:^3.972.10" + "@aws-sdk/types": "npm:^3.973.6" + "@aws-sdk/util-endpoints": "npm:^3.996.5" + "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" + "@aws-sdk/util-user-agent-node": "npm:^3.973.14" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/core": "npm:^3.23.13" + "@smithy/fetch-http-handler": "npm:^5.3.15" + "@smithy/hash-node": "npm:^4.2.12" + "@smithy/invalid-dependency": "npm:^4.2.12" + "@smithy/middleware-content-length": "npm:^4.2.12" + "@smithy/middleware-endpoint": "npm:^4.4.28" + "@smithy/middleware-retry": "npm:^4.4.46" + "@smithy/middleware-serde": "npm:^4.2.16" + "@smithy/middleware-stack": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/node-http-handler": "npm:^4.5.1" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/smithy-client": "npm:^4.12.8" + "@smithy/types": "npm:^4.13.1" + "@smithy/url-parser": "npm:^4.2.12" + "@smithy/util-base64": "npm:^4.3.2" + "@smithy/util-body-length-browser": "npm:^4.2.2" + "@smithy/util-body-length-node": "npm:^4.2.3" + "@smithy/util-defaults-mode-browser": "npm:^4.3.44" + "@smithy/util-defaults-mode-node": "npm:^4.2.48" + "@smithy/util-endpoints": "npm:^3.3.3" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-retry": "npm:^4.2.13" + "@smithy/util-utf8": "npm:^4.2.2" + tslib: "npm:^2.6.2" + checksum: 10/042d258e098e8e097374a5a5ef29fdebcd39ab6bdb76a06d21dc6291a03ccb1bcd6b17c6bf9cb011d2efa0483ccaf5c2e81f7b5f0febaae8fea6cbad8479dbec + languageName: node + linkType: hard + "@aws-sdk/node-http-handler@npm:3.370.0": version: 3.370.0 resolution: "@aws-sdk/node-http-handler@npm:3.370.0" @@ -1392,6 +1631,26 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/rds-signer@npm:^3.0.0": + version: 3.1022.0 + resolution: "@aws-sdk/rds-signer@npm:3.1022.0" + dependencies: + "@aws-crypto/sha256-browser": "npm:5.2.0" + "@aws-crypto/sha256-js": "npm:5.2.0" + "@aws-sdk/credential-providers": "npm:3.1022.0" + "@aws-sdk/util-format-url": "npm:^3.972.8" + "@smithy/config-resolver": "npm:^4.4.13" + "@smithy/hash-node": "npm:^4.2.12" + "@smithy/invalid-dependency": "npm:^4.2.12" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/signature-v4": "npm:^5.3.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/50a14b25f9cb7a496a8ba04e69ccbdd5d94e999a8a38b668252154d6c3fd7af09088201bd75fcf99bab76a9175703c0bebdab99cd014a1aee8e6829b07b5c79e + languageName: node + linkType: hard + "@aws-sdk/region-config-resolver@npm:^3.972.10": version: 3.972.10 resolution: "@aws-sdk/region-config-resolver@npm:3.972.10" @@ -1434,6 +1693,21 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/token-providers@npm:3.1021.0": + version: 3.1021.0 + resolution: "@aws-sdk/token-providers@npm:3.1021.0" + dependencies: + "@aws-sdk/core": "npm:^3.973.26" + "@aws-sdk/nested-clients": "npm:^3.996.18" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/property-provider": "npm:^4.2.12" + "@smithy/shared-ini-file-loader": "npm:^4.4.7" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/8b64169f56e3b352656bdcea347269d979aa7422c09396e01ef97912db96584274b6aac1fa6d0e267536ef0f6b8acfa150c0eed722243af2235019d62f824870 + languageName: node + linkType: hard + "@aws-sdk/types@npm:3.370.0": version: 3.370.0 resolution: "@aws-sdk/types@npm:3.370.0" @@ -1497,6 +1771,18 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-format-url@npm:^3.972.8": + version: 3.972.8 + resolution: "@aws-sdk/util-format-url@npm:3.972.8" + dependencies: + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/querystring-builder": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/37aa7d0e47b32fbfbb9b6d2c7ec03512191cac3eab7ce45c996dd19b77d5317cf2e1636d90de87313a5604c3c7fb2f8a426c8fbb6f39f672f3774ca8a5e72d19 + languageName: node + linkType: hard + "@aws-sdk/util-locate-window@npm:^3.0.0": version: 3.965.5 resolution: "@aws-sdk/util-locate-window@npm:3.965.5" @@ -1567,6 +1853,25 @@ __metadata: languageName: node linkType: hard +"@aws-sdk/util-user-agent-node@npm:^3.973.14": + version: 3.973.14 + resolution: "@aws-sdk/util-user-agent-node@npm:3.973.14" + dependencies: + "@aws-sdk/middleware-user-agent": "npm:^3.972.28" + "@aws-sdk/types": "npm:^3.973.6" + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-config-provider": "npm:^4.2.2" + tslib: "npm:^2.6.2" + peerDependencies: + aws-crt: ">=1.0.0" + peerDependenciesMeta: + aws-crt: + optional: true + checksum: 10/61077c95e26478ee73b125cac0fb1b5d08d833c67be8209662c851c768641f9043e24ed8449f72ce6968faee976001a784b1ebc1f29170f4c07942260b2500ff + languageName: node + linkType: hard + "@aws-sdk/xml-builder@npm:^3.972.16": version: 3.972.16 resolution: "@aws-sdk/xml-builder@npm:3.972.16" @@ -2509,6 +2814,7 @@ __metadata: "@aws-sdk/client-codecommit": "npm:^3.350.0" "@aws-sdk/client-s3": "npm:^3.350.0" "@aws-sdk/credential-providers": "npm:^3.350.0" + "@aws-sdk/rds-signer": "npm:^3.0.0" "@aws-sdk/types": "npm:^3.347.0" "@aws-sdk/util-stream-node": "npm:^3.350.0" "@azure/identity": "npm:^4.0.0" @@ -18425,6 +18731,23 @@ __metadata: languageName: node linkType: hard +"@smithy/middleware-retry@npm:^4.4.46": + version: 4.4.46 + resolution: "@smithy/middleware-retry@npm:4.4.46" + dependencies: + "@smithy/node-config-provider": "npm:^4.3.12" + "@smithy/protocol-http": "npm:^5.3.12" + "@smithy/service-error-classification": "npm:^4.2.12" + "@smithy/smithy-client": "npm:^4.12.8" + "@smithy/types": "npm:^4.13.1" + "@smithy/util-middleware": "npm:^4.2.12" + "@smithy/util-retry": "npm:^4.2.13" + "@smithy/uuid": "npm:^1.1.2" + tslib: "npm:^2.6.2" + checksum: 10/6444f96e8355522b907d1a5a3d9743cc0ba41531a46392c1f085a9c44396befe0cb414d18716ec29c0bbdf5602b5844d17b6eebec92ad27f64ecd5261ebea5a8 + languageName: node + linkType: hard + "@smithy/middleware-serde@npm:^4.2.16": version: 4.2.16 resolution: "@smithy/middleware-serde@npm:4.2.16" @@ -18805,6 +19128,17 @@ __metadata: languageName: node linkType: hard +"@smithy/util-retry@npm:^4.2.13": + version: 4.2.13 + resolution: "@smithy/util-retry@npm:4.2.13" + dependencies: + "@smithy/service-error-classification": "npm:^4.2.12" + "@smithy/types": "npm:^4.13.1" + tslib: "npm:^2.6.2" + checksum: 10/8b3a467c77b09e662321dab459a9173a88969b90f8de60378bb6b20993767ff8c7069da9696eca16714a2a1a61639834c5968ff1992771c75dbcf5bdffa2c6de + languageName: node + linkType: hard + "@smithy/util-stream@npm:^4.5.21": version: 4.5.21 resolution: "@smithy/util-stream@npm:4.5.21" From 21e7ec5d740e2cf45db0f3b304906c7586b4d1a0 Mon Sep 17 00:00:00 2001 From: Roland Fuszenecker Date: Thu, 2 Apr 2026 15:29:38 +0200 Subject: [PATCH 2/3] feat(backend-defaults): improve AWS RDS IAM auth error handling and token expiry Signed-off-by: Roland Fuszenecker --- packages/backend-defaults/config.d.ts | 4 +- .../database/connectors/postgres.test.ts | 42 +++++++++++---- .../database/connectors/postgres.ts | 53 ++++++++++++------- 3 files changed, 66 insertions(+), 33 deletions(-) diff --git a/packages/backend-defaults/config.d.ts b/packages/backend-defaults/config.d.ts index 1ff45e6679..12da0a7061 100644 --- a/packages/backend-defaults/config.d.ts +++ b/packages/backend-defaults/config.d.ts @@ -644,9 +644,9 @@ export interface Config { */ host: string; /** - * The port number the database is listening on. Defaults to 5432. + * The port number the database is listening on. */ - port?: number; + port: number; /** * The database user to authenticate as. This user must have the `rds_iam` role granted. */ diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts index e095a17e11..012b5d9f13 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.test.ts @@ -649,6 +649,7 @@ describe('postgres', () => { connection: { type: 'rds', host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, user: 'postgres', region: 'eu-west-1', }, @@ -662,28 +663,47 @@ describe('postgres', () => { expect(conn2.password).toBe('token-2'); }); - it('defaults port to 5432 for rds connections', async () => { + it('returns an expirationChecker that reflects the token TTL', async () => { const { Signer } = jest.requireMock('@aws-sdk/rds-signer') as jest.Mocked< typeof import('@aws-sdk/rds-signer') >; Signer.prototype.getAuthToken.mockResolvedValue('mock-iam-token'); - await buildPgDatabaseConfig( + const configResult = await buildPgDatabaseConfig( new ConfigReader({ client: 'pg', connection: { type: 'rds', host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, user: 'postgres', region: 'eu-west-1', }, }), ); - expect(Signer).toHaveBeenCalledWith( - expect.objectContaining({ port: 5432 }), - ); + const conn = await (configResult.connection as () => Promise)(); + + expect(conn.expirationChecker).toBeInstanceOf(Function); + // Token was just issued, so it should not yet be considered expired. + expect(conn.expirationChecker()).toBe(false); + }); + + it('throws when port is missing for rds connection', async () => { + await expect( + buildPgDatabaseConfig( + new ConfigReader({ + client: 'pg', + connection: { + type: 'rds', + host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + user: 'postgres', + region: 'eu-west-1', + }, + }), + ), + ).rejects.toThrow(/connection\.port/); }); it('falls back to AWS_REGION env var when region is not set in config', async () => { @@ -703,6 +723,7 @@ describe('postgres', () => { connection: { type: 'rds', host: 'mydb.cluster.us-east-1.rds.amazonaws.com', + port: 5432, user: 'postgres', }, }), @@ -727,14 +748,13 @@ describe('postgres', () => { client: 'pg', connection: { type: 'rds', + port: 5432, user: 'postgres', region: 'eu-west-1', }, }), ), - ).rejects.toThrow( - /Missing host in connection config for AWS RDS IAM auth/, - ); + ).rejects.toThrow(/connection\.host/); }); it('throws when user is missing for rds connection', async () => { @@ -745,13 +765,12 @@ describe('postgres', () => { connection: { type: 'rds', host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, region: 'eu-west-1', }, }), ), - ).rejects.toThrow( - /Missing user in connection config for AWS RDS IAM auth/, - ); + ).rejects.toThrow(/connection\.user/); }); it('throws when region is missing and no env var is set for rds connection', async () => { @@ -768,6 +787,7 @@ describe('postgres', () => { connection: { type: 'rds', host: 'mydb.cluster.eu-west-1.rds.amazonaws.com', + port: 5432, user: 'postgres', }, }), diff --git a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts index 53e00e863c..74e95601bd 100644 --- a/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts +++ b/packages/backend-defaults/src/entrypoints/database/connectors/postgres.ts @@ -277,24 +277,21 @@ export async function buildRdsPgConfig(config: Config): Promise { const { Signer } = require('@aws-sdk/rds-signer') as typeof import('@aws-sdk/rds-signer'); - const rawConfig = config.get() as Record; - const normalized = normalizeConnection(rawConfig.connection as any); - const sanitizedConnection = omit(normalized, [ - 'type', - 'region', - ]) as Partial; - - const hostname = (normalized as any).host as string; - if (!hostname) { - throw new Error('Missing host in connection config for AWS RDS IAM auth'); - } - const port = ((normalized as any).port as number | undefined) ?? 5432; - const username = (normalized as any).user as string; - if (!username) { - throw new Error('Missing user in connection config for AWS RDS IAM auth'); + let hostname: string; + let port: number; + let username: string; + try { + hostname = config.getString('connection.host'); + port = config.getNumber('connection.port'); + username = config.getString('connection.user'); + } catch (err) { + throw new ForwardedError( + 'AWS RDS IAM auth: missing required database connection config — make sure connection.host, connection.port, and connection.user are set and any environment variables they reference are set', + err, + ); } const region = - ((normalized as any).region as string | undefined) ?? + config.getOptionalString('connection.region') ?? process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION; if (!region) { @@ -303,17 +300,33 @@ export async function buildRdsPgConfig(config: Config): Promise { ); } + const rawConfig = config.get() as Record; + const sanitizedConnection = omit( + config.get('connection') as Record, + ['type', 'region'], + ) as Partial; + const signer = new Signer({ hostname, port, username, region }); + // RDS IAM auth tokens are valid for 15 minutes. Renew 1 minute early so + // that pooled connections are refreshed before the token actually expires. + const tokenTtlMs = 15 * 60 * 1000; + const renewalOffsetMs = 60 * 1000; + async function getConnectionConfig() { try { const password = await signer.getAuthToken(); - return { ...sanitizedConnection, password }; + const tokenExpiration = Date.now() + tokenTtlMs - renewalOffsetMs; + return { + ...sanitizedConnection, + password, + expirationChecker: () => tokenExpiration <= Date.now(), + }; } catch (err) { - console.error( - `AWS RDS IAM auth token acquisition failed for ${username}@${hostname}:${port}: ${err}`, + throw new ForwardedError( + `AWS RDS IAM auth token acquisition failed for ${username}@${hostname}:${port}`, + err, ); - throw err; } } From 9a60dcd9fc2b1b94ee82e99159f2d8383eab4be6 Mon Sep 17 00:00:00 2001 From: Roland Fuszenecker Date: Thu, 9 Apr 2026 12:07:32 +0200 Subject: [PATCH 3/3] chore: deduplicate yarn.lock Signed-off-by: Roland Fuszenecker --- yarn.lock | 313 ++---------------------------------------------------- 1 file changed, 6 insertions(+), 307 deletions(-) diff --git a/yarn.lock b/yarn.lock index 73a2ea7da1..79f4e9123a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -538,53 +538,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/client-cognito-identity@npm:3.1020.0": - version: 3.1020.0 - resolution: "@aws-sdk/client-cognito-identity@npm:3.1020.0" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/credential-provider-node": "npm:^3.972.28" - "@aws-sdk/middleware-host-header": "npm:^3.972.8" - "@aws-sdk/middleware-logger": "npm:^3.972.8" - "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" - "@aws-sdk/middleware-user-agent": "npm:^3.972.27" - "@aws-sdk/region-config-resolver": "npm:^3.972.10" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" - "@aws-sdk/util-user-agent-node": "npm:^3.973.13" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/core": "npm:^3.23.13" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/hash-node": "npm:^4.2.12" - "@smithy/invalid-dependency": "npm:^4.2.12" - "@smithy/middleware-content-length": "npm:^4.2.12" - "@smithy/middleware-endpoint": "npm:^4.4.28" - "@smithy/middleware-retry": "npm:^4.4.45" - "@smithy/middleware-serde": "npm:^4.2.16" - "@smithy/middleware-stack": "npm:^4.2.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/node-http-handler": "npm:^4.5.1" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.8" - "@smithy/types": "npm:^4.13.1" - "@smithy/url-parser": "npm:^4.2.12" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-body-length-browser": "npm:^4.2.2" - "@smithy/util-body-length-node": "npm:^4.2.3" - "@smithy/util-defaults-mode-browser": "npm:^4.3.44" - "@smithy/util-defaults-mode-node": "npm:^4.2.48" - "@smithy/util-endpoints": "npm:^3.3.3" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-retry": "npm:^4.2.12" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/62e5feb1be4154524906e00f059520903c0f29daf8f6db036c30bff7756b563ea74e0f01e4393c6ebea9fad255da6c1b220c9c4ee9bd51fee2b8a3f48a42db56 - languageName: node - linkType: hard - "@aws-sdk/client-cognito-identity@npm:3.1022.0": version: 3.1022.0 resolution: "@aws-sdk/client-cognito-identity@npm:3.1022.0" @@ -965,19 +918,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-cognito-identity@npm:^3.972.20": - version: 3.972.20 - resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.972.20" - dependencies: - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/0ce90d2cb907e5b79ba326fa5743577af6ca377a865f2177469579e7afb7407111f7248e76183de77f5c72950c8e53474a6a1c598cdc4dfb3b5f6c9bdcfbc12a - languageName: node - linkType: hard - "@aws-sdk/credential-provider-cognito-identity@npm:^3.972.21": version: 3.972.21 resolution: "@aws-sdk/credential-provider-cognito-identity@npm:3.972.21" @@ -1022,28 +962,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-ini@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/credential-provider-ini@npm:3.972.27" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/credential-provider-env": "npm:^3.972.24" - "@aws-sdk/credential-provider-http": "npm:^3.972.26" - "@aws-sdk/credential-provider-login": "npm:^3.972.27" - "@aws-sdk/credential-provider-process": "npm:^3.972.24" - "@aws-sdk/credential-provider-sso": "npm:^3.972.27" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.27" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/credential-provider-imds": "npm:^4.2.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/65b10fa0428d49e44ea9ff8df4e4bdc43131e938ef1c94723ebfe4e9ff73cd8a39dd4301521662593b4c6c6d2d4b9cd090102df79b1d2efe8d2bc191ed90f401 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-ini@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/credential-provider-ini@npm:3.972.28" @@ -1066,22 +984,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-login@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/credential-provider-login@npm:3.972.27" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/765879fe6db638b2f64098dc5494e859d33cfa2888310332e1189a42e4abc2a981222d53de410bf436efe00b720755c85ea33d002e2277641937e787809ea205 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-login@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/credential-provider-login@npm:3.972.28" @@ -1098,27 +1000,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.28": - version: 3.972.28 - resolution: "@aws-sdk/credential-provider-node@npm:3.972.28" - dependencies: - "@aws-sdk/credential-provider-env": "npm:^3.972.24" - "@aws-sdk/credential-provider-http": "npm:^3.972.26" - "@aws-sdk/credential-provider-ini": "npm:^3.972.27" - "@aws-sdk/credential-provider-process": "npm:^3.972.24" - "@aws-sdk/credential-provider-sso": "npm:^3.972.27" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.27" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/credential-provider-imds": "npm:^4.2.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/e914b22d77bf47511cb2d32109bfc864b53778dd8951f8ea555927092662a512fe888e9fd53afbeccf23943f8a4494f60be7ea5a94d625c6e72ebe4ae9c2da36 - languageName: node - linkType: hard - -"@aws-sdk/credential-provider-node@npm:^3.972.29": +"@aws-sdk/credential-provider-node@npm:^3.350.0, @aws-sdk/credential-provider-node@npm:^3.972.28, @aws-sdk/credential-provider-node@npm:^3.972.29": version: 3.972.29 resolution: "@aws-sdk/credential-provider-node@npm:3.972.29" dependencies: @@ -1152,22 +1034,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-sso@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/credential-provider-sso@npm:3.972.27" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/token-providers": "npm:3.1020.0" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/5007301d4830088ed31d69e06cb881a4608287174d08543e98df51416aa6dcd8e5d5d9716ba371f83b4d6a9fc753b3394cdb1c6d0826aa98b2901db2df7f0c44 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-sso@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/credential-provider-sso@npm:3.972.28" @@ -1184,21 +1050,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-provider-web-identity@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.27" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/06661b21c47c7002d6a025245a34c20500f9976617dbb3956bb8436530065bdfba0c9ccd35fee1abb11b6df67162c0ab23866cacf2e8d2b2f57da91abfec1c51 - languageName: node - linkType: hard - "@aws-sdk/credential-provider-web-identity@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/credential-provider-web-identity@npm:3.972.28" @@ -1214,7 +1065,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-providers@npm:3.1022.0": +"@aws-sdk/credential-providers@npm:3.1022.0, @aws-sdk/credential-providers@npm:^3.350.0": version: 3.1022.0 resolution: "@aws-sdk/credential-providers@npm:3.1022.0" dependencies: @@ -1242,34 +1093,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/credential-providers@npm:^3.350.0": - version: 3.1020.0 - resolution: "@aws-sdk/credential-providers@npm:3.1020.0" - dependencies: - "@aws-sdk/client-cognito-identity": "npm:3.1020.0" - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/credential-provider-cognito-identity": "npm:^3.972.20" - "@aws-sdk/credential-provider-env": "npm:^3.972.24" - "@aws-sdk/credential-provider-http": "npm:^3.972.26" - "@aws-sdk/credential-provider-ini": "npm:^3.972.27" - "@aws-sdk/credential-provider-login": "npm:^3.972.27" - "@aws-sdk/credential-provider-node": "npm:^3.972.28" - "@aws-sdk/credential-provider-process": "npm:^3.972.24" - "@aws-sdk/credential-provider-sso": "npm:^3.972.27" - "@aws-sdk/credential-provider-web-identity": "npm:^3.972.27" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/core": "npm:^3.23.13" - "@smithy/credential-provider-imds": "npm:^4.2.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/405f4d6470df421709241489c30e86034a329443dd5d7ecd0a85439c2f9838da8e38b68fba58f9d2568c679d47d4ecd5d52ac3d864ab64a6ac4572e38dd22888 - languageName: node - linkType: hard - "@aws-sdk/is-array-buffer@npm:3.310.0": version: 3.310.0 resolution: "@aws-sdk/is-array-buffer@npm:3.310.0" @@ -1463,23 +1286,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/middleware-user-agent@npm:^3.972.27": - version: 3.972.27 - resolution: "@aws-sdk/middleware-user-agent@npm:3.972.27" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@smithy/core": "npm:^3.23.13" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-retry": "npm:^4.2.12" - tslib: "npm:^2.6.2" - checksum: 10/14c1f9579e0e72a8de27fc587208f4993dcb53c6980b181a26d1181c7a51212f51603014691448678b05495ecc01045971a95ad82f27f1f7e8dc32fb59b3dac7 - languageName: node - linkType: hard - -"@aws-sdk/middleware-user-agent@npm:^3.972.28": +"@aws-sdk/middleware-user-agent@npm:^3.972.27, @aws-sdk/middleware-user-agent@npm:^3.972.28": version: 3.972.28 resolution: "@aws-sdk/middleware-user-agent@npm:3.972.28" dependencies: @@ -1495,52 +1302,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/nested-clients@npm:^3.996.17": - version: 3.996.17 - resolution: "@aws-sdk/nested-clients@npm:3.996.17" - dependencies: - "@aws-crypto/sha256-browser": "npm:5.2.0" - "@aws-crypto/sha256-js": "npm:5.2.0" - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/middleware-host-header": "npm:^3.972.8" - "@aws-sdk/middleware-logger": "npm:^3.972.8" - "@aws-sdk/middleware-recursion-detection": "npm:^3.972.9" - "@aws-sdk/middleware-user-agent": "npm:^3.972.27" - "@aws-sdk/region-config-resolver": "npm:^3.972.10" - "@aws-sdk/types": "npm:^3.973.6" - "@aws-sdk/util-endpoints": "npm:^3.996.5" - "@aws-sdk/util-user-agent-browser": "npm:^3.972.8" - "@aws-sdk/util-user-agent-node": "npm:^3.973.13" - "@smithy/config-resolver": "npm:^4.4.13" - "@smithy/core": "npm:^3.23.13" - "@smithy/fetch-http-handler": "npm:^5.3.15" - "@smithy/hash-node": "npm:^4.2.12" - "@smithy/invalid-dependency": "npm:^4.2.12" - "@smithy/middleware-content-length": "npm:^4.2.12" - "@smithy/middleware-endpoint": "npm:^4.4.28" - "@smithy/middleware-retry": "npm:^4.4.45" - "@smithy/middleware-serde": "npm:^4.2.16" - "@smithy/middleware-stack": "npm:^4.2.12" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/node-http-handler": "npm:^4.5.1" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/smithy-client": "npm:^4.12.8" - "@smithy/types": "npm:^4.13.1" - "@smithy/url-parser": "npm:^4.2.12" - "@smithy/util-base64": "npm:^4.3.2" - "@smithy/util-body-length-browser": "npm:^4.2.2" - "@smithy/util-body-length-node": "npm:^4.2.3" - "@smithy/util-defaults-mode-browser": "npm:^4.3.44" - "@smithy/util-defaults-mode-node": "npm:^4.2.48" - "@smithy/util-endpoints": "npm:^3.3.3" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-retry": "npm:^4.2.12" - "@smithy/util-utf8": "npm:^4.2.2" - tslib: "npm:^2.6.2" - checksum: 10/571e2c6606e489f2cfae4f114de6e72fea601f5ab9becedecf9a88a68e18025d90fc25a10d284a3970c405d3bdd5dfdfbdea384e4b7a881b96e950e8fcb84c9b - languageName: node - linkType: hard - "@aws-sdk/nested-clients@npm:^3.996.18": version: 3.996.18 resolution: "@aws-sdk/nested-clients@npm:3.996.18" @@ -1678,21 +1439,6 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/token-providers@npm:3.1020.0": - version: 3.1020.0 - resolution: "@aws-sdk/token-providers@npm:3.1020.0" - dependencies: - "@aws-sdk/core": "npm:^3.973.26" - "@aws-sdk/nested-clients": "npm:^3.996.17" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/property-provider": "npm:^4.2.12" - "@smithy/shared-ini-file-loader": "npm:^4.4.7" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/e8758e5fda0013c1723eeaeb510de80952ab050ca975e6a5e4e231785a62b3373825315236cbf56af10d85cb2fda3a58f284145e60401c56c4eeee8303927d4b - languageName: node - linkType: hard - "@aws-sdk/token-providers@npm:3.1021.0": version: 3.1021.0 resolution: "@aws-sdk/token-providers@npm:3.1021.0" @@ -1834,26 +1580,7 @@ __metadata: languageName: node linkType: hard -"@aws-sdk/util-user-agent-node@npm:^3.973.13": - version: 3.973.13 - resolution: "@aws-sdk/util-user-agent-node@npm:3.973.13" - dependencies: - "@aws-sdk/middleware-user-agent": "npm:^3.972.27" - "@aws-sdk/types": "npm:^3.973.6" - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-config-provider": "npm:^4.2.2" - tslib: "npm:^2.6.2" - peerDependencies: - aws-crt: ">=1.0.0" - peerDependenciesMeta: - aws-crt: - optional: true - checksum: 10/d9265cc820993a09518abeb38e0dff03dacb3a5102683c10b1dceb22d387afae2e12ea14fc4f7008d891f7c288717d5bd1af9a4a5451eedac1b4b764b9ef3d56 - languageName: node - linkType: hard - -"@aws-sdk/util-user-agent-node@npm:^3.973.14": +"@aws-sdk/util-user-agent-node@npm:^3.973.13, @aws-sdk/util-user-agent-node@npm:^3.973.14": version: 3.973.14 resolution: "@aws-sdk/util-user-agent-node@npm:3.973.14" dependencies: @@ -18714,24 +18441,7 @@ __metadata: languageName: node linkType: hard -"@smithy/middleware-retry@npm:^4.4.45": - version: 4.4.45 - resolution: "@smithy/middleware-retry@npm:4.4.45" - dependencies: - "@smithy/node-config-provider": "npm:^4.3.12" - "@smithy/protocol-http": "npm:^5.3.12" - "@smithy/service-error-classification": "npm:^4.2.12" - "@smithy/smithy-client": "npm:^4.12.8" - "@smithy/types": "npm:^4.13.1" - "@smithy/util-middleware": "npm:^4.2.12" - "@smithy/util-retry": "npm:^4.2.12" - "@smithy/uuid": "npm:^1.1.2" - tslib: "npm:^2.6.2" - checksum: 10/c5fb3806177efbf14066d5a173a3f5ec1b4d878ce669c81a4a34afe94aa69016151cd168175b8cbb5142455766a699991e44712621d39dfef621cd7a6f44c32e - languageName: node - linkType: hard - -"@smithy/middleware-retry@npm:^4.4.46": +"@smithy/middleware-retry@npm:^4.4.45, @smithy/middleware-retry@npm:^4.4.46": version: 4.4.46 resolution: "@smithy/middleware-retry@npm:4.4.46" dependencies: @@ -19117,18 +18827,7 @@ __metadata: languageName: node linkType: hard -"@smithy/util-retry@npm:^4.2.12": - version: 4.2.12 - resolution: "@smithy/util-retry@npm:4.2.12" - dependencies: - "@smithy/service-error-classification": "npm:^4.2.12" - "@smithy/types": "npm:^4.13.1" - tslib: "npm:^2.6.2" - checksum: 10/bb44627ca79317e280c4427ddf83df289c4f4206ad613bc10e236298960ecdfafd7c81ffb02411e475d482e7bf96e70bb3515952ed0d3a01ed53d8f1e4f271a9 - languageName: node - linkType: hard - -"@smithy/util-retry@npm:^4.2.13": +"@smithy/util-retry@npm:^4.2.12, @smithy/util-retry@npm:^4.2.13": version: 4.2.13 resolution: "@smithy/util-retry@npm:4.2.13" dependencies: