diff --git a/.changeset/neat-weeks-wait.md b/.changeset/neat-weeks-wait.md new file mode 100644 index 0000000000..c16b91fd2f --- /dev/null +++ b/.changeset/neat-weeks-wait.md @@ -0,0 +1,5 @@ +--- +'@backstage/plugin-auth-backend-module-aws-alb-provider': patch +--- + +Added support for AWS GovCloud (US) regions diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts index cb103debb0..0bbcf9b5c1 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.test.ts @@ -26,7 +26,13 @@ import { makeProfileInfo, provisionKeyCache } from './helpers'; jest.mock('crypto'); const cryptoMock = crypto as jest.Mocked; -describe('helpers', () => { +describe.each([ + ['eu-west-1', 'https://public-keys.auth.elb.eu-west-1.amazonaws.com/kid'], + [ + 'us-gov-west-1', + 'https://s3-us-gov-west-1.amazonaws.com/aws-elb-public-keys-prod-us-gov-west-1/kid', + ], +])('helpers', (region, url) => { const server = setupServer(); setupRequestMockHandlers(server); @@ -37,7 +43,7 @@ describe('helpers', () => { jest.clearAllMocks(); server.use( http.get( - 'https://public-keys.auth.elb.eu-west-1.amazonaws.com/kid', + url, () => new HttpResponse( `-----BEGIN PUBLIC KEY----- @@ -51,12 +57,12 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should create a key', () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); expect(getKey).toBeDefined(); }); it('should return a key from cache', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); cryptoMock.createPublicKey.mockReturnValueOnce('key'); nodeCache.get = jest.fn().mockReturnValue('key'); @@ -67,7 +73,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should update cache if key is not found', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); jest.spyOn(nodeCache, 'set'); @@ -80,7 +86,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should throw error if key is not found', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); cryptoMock.createPublicKey.mockReturnValue(undefined); @@ -91,7 +97,7 @@ yOlxJ2VW88mLAQGJ7HPAvOdylxZsItMnzCuqNzZvie8m/NJsOjhDncVkrw== }); it('should throw if key is not present in request header', async () => { - const getKey = provisionKeyCache('eu-west-1', nodeCache); + const getKey = provisionKeyCache(region, nodeCache); nodeCache.get = jest.fn().mockReturnValue(undefined); diff --git a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts index e846b2484e..24026e2c9c 100644 --- a/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts +++ b/plugins/auth-backend-module-aws-alb-provider/src/helpers.ts @@ -70,6 +70,18 @@ export const makeProfileInfo = ( }; }; +const getPublicKeyEndpoint = (region: string) => { + if (region.startsWith('us-gov')) { + return `https://s3-${encodeURIComponent( + region, + )}.amazonaws.com/aws-elb-public-keys-prod-${encodeURIComponent(region)}`; + } + + return `https://public-keys.auth.elb.${encodeURIComponent( + region, + )}.amazonaws.com`; +}; + export const provisionKeyCache = (region: string, keyCache: NodeCache) => { return async (header: JWTHeaderParameters): Promise => { if (!header.kid) { @@ -79,10 +91,9 @@ export const provisionKeyCache = (region: string, keyCache: NodeCache) => { if (optionalCacheKey) { return crypto.createPublicKey(optionalCacheKey); } + const keyText: string = await fetch( - `https://public-keys.auth.elb.${encodeURIComponent( - region, - )}.amazonaws.com/${encodeURIComponent(header.kid)}`, + `${getPublicKeyEndpoint(region)}/${encodeURIComponent(header.kid)}`, ).then(response => response.text()); const keyValue = crypto.createPublicKey(keyText);