From 493c123be7cb75db993aa8985d9106583486cd3a Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Tue, 2 Mar 2021 11:33:54 +0100 Subject: [PATCH 01/14] Ignore intellij files --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index f4b70ee..4d4af2b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,6 @@ jspm_packages # Optional REPL history .node_repl_history *.zip + +# IntelliJ files +.idea/ From 68beff43efe50f95a182db979e07549dfea5f06e Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Tue, 2 Mar 2021 11:49:51 +0100 Subject: [PATCH 02/14] setup API, provide doc --- README.md | 21 +++++++++++++++++++++ lib/config.js | 3 ++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index ae0a897..6b10af8 100644 --- a/README.md +++ b/README.md @@ -83,6 +83,27 @@ openssl enc -aes-256-cbc -d \ -iv $(< postgres-27-12-2019@13-19-13.backup.iv) ``` +#### IAM-based Postgres authentication + +Your context may require that you use IAM-based authentication to log into the Postgres service. +Support for this can be enabled my making your Cloudwatch Event look like this. + +```json + +{ + "PGDATABASE": "dbname", + "PGUSER": "postgres", + "USE_IAM_AUTH": "true", + "PGHOST": "host", + "S3_BUCKET" : "db-backups", + "ROOT": "hourly-backups" + } +``` + +If you supply `USE_IAM_AUTH` with a value of `true`, the `PGPASSWORD` var may be omitted in the CloudWatch event. +If you still provide it, it will be ignored. + +Don't forget to make sure that the lambda-execution-role thas the right IAM-rds policy attached to it. ## Developer diff --git a/lib/config.js b/lib/config.js index 42a9ed6..d631d7b 100644 --- a/lib/config.js +++ b/lib/config.js @@ -5,5 +5,6 @@ module.exports = { S3_REGION: 'eu-west-1', PGDUMP_PATH: path.join(__dirname, '../bin/postgres-11.6'), // maximum time allowed to connect to postgres before a timeout occurs - PGCONNECT_TIMEOUT: 15 + PGCONNECT_TIMEOUT: 15, + USE_IAM_AUTH: false } From 58c443fa283117f5fa9cb3fb47e216b60be65693 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 08:56:08 +0100 Subject: [PATCH 03/14] Correct type --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b10af8..5233d8f 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ Support for this can be enabled my making your Cloudwatch Event look like this. { "PGDATABASE": "dbname", "PGUSER": "postgres", - "USE_IAM_AUTH": "true", + "USE_IAM_AUTH": true, "PGHOST": "host", "S3_BUCKET" : "db-backups", "ROOT": "hourly-backups" From 0a900489d50d0790bf2a7c605b2441678d01b474 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 11:31:35 +0100 Subject: [PATCH 04/14] formatting --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 5233d8f..f999a59 100644 --- a/README.md +++ b/README.md @@ -91,13 +91,13 @@ Support for this can be enabled my making your Cloudwatch Event look like this. ```json { - "PGDATABASE": "dbname", - "PGUSER": "postgres", - "USE_IAM_AUTH": true, - "PGHOST": "host", - "S3_BUCKET" : "db-backups", - "ROOT": "hourly-backups" - } + "PGDATABASE": "dbname", + "PGUSER": "postgres", + "USE_IAM_AUTH": true, + "PGHOST": "host", + "S3_BUCKET" : "db-backups", + "ROOT": "hourly-backups" +} ``` If you supply `USE_IAM_AUTH` with a value of `true`, the `PGPASSWORD` var may be omitted in the CloudWatch event. From 2aeb8478f6eef6b783bc2b09d08a9a3278008d66 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 11:58:24 +0100 Subject: [PATCH 05/14] Add ability to connect using iam --- lib/handler.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/handler.js b/lib/handler.js index 0d82ae3..012bcf9 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -2,6 +2,7 @@ const utils = require('./utils') const uploadS3 = require('./upload-s3') const pgdump = require('./pgdump') const encryption = require('./encryption') +const AWS = require('aws-sdk') const DEFAULT_CONFIG = require('./config') @@ -32,8 +33,20 @@ async function backup(config) { return uploadS3(stream, config, key) } +function decorateWithIamToken(baseConfig) { + const rdsSigner = new AWS.RDS.Signer() + const token = rdsSigner.getAuthToken({ + hostname: baseConfig.PGHOST, + port: baseConfig.PGPORT != null ? baseConfig.PGPORT : 5432, + region: baseConfig.S3_REGION, + username: baseConfig.PGUSER + }) + return Object.assign(baseConfig, { PGPASSWORD: token }) +} + async function handler(event) { - const config = { ...DEFAULT_CONFIG, ...event } + const baseConfig = { ...DEFAULT_CONFIG, ...event } + const config = event.USE_IAM_AUTH === true ? decorateWithIamToken(baseConfig) : baseConfig try { return await backup(config) } From a417031e008f20b176623dc705f70f7f6949a16f Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 12:00:19 +0100 Subject: [PATCH 06/14] Typo, remove noise. --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index f999a59..ba6b941 100644 --- a/README.md +++ b/README.md @@ -103,8 +103,6 @@ Support for this can be enabled my making your Cloudwatch Event look like this. If you supply `USE_IAM_AUTH` with a value of `true`, the `PGPASSWORD` var may be omitted in the CloudWatch event. If you still provide it, it will be ignored. -Don't forget to make sure that the lambda-execution-role thas the right IAM-rds policy attached to it. - ## Developer #### Bundling a new `pg_dump` binary From be96c34906a6613877cd9da7a2c8fff75692bcba Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 15:20:48 +0100 Subject: [PATCH 07/14] Do not modify baseConfig --- lib/handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/handler.js b/lib/handler.js index 012bcf9..3c8bdc1 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -41,7 +41,7 @@ function decorateWithIamToken(baseConfig) { region: baseConfig.S3_REGION, username: baseConfig.PGUSER }) - return Object.assign(baseConfig, { PGPASSWORD: token }) + return { ...baseConfig, PGPASSWORD: token } } async function handler(event) { From d23c6ef012639f259769d09f4e2b331a685ca4b5 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 18:16:15 +0100 Subject: [PATCH 08/14] eslint --- lib/handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/handler.js b/lib/handler.js index 3c8bdc1..9ccd2c1 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -1,8 +1,8 @@ +const AWS = require('aws-sdk') const utils = require('./utils') const uploadS3 = require('./upload-s3') const pgdump = require('./pgdump') const encryption = require('./encryption') -const AWS = require('aws-sdk') const DEFAULT_CONFIG = require('./config') From ad0c9597954b1dcd2963820aaed6d140d1d5b535 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 18:16:28 +0100 Subject: [PATCH 09/14] Add test --- package-lock.json | 124 ++++++++++++++++++++++++++++++++++++++++++++++ package.json | 1 + test/handler.js | 19 +++++++ 3 files changed, 144 insertions(+) diff --git a/package-lock.json b/package-lock.json index f6bb1cd..ade4eea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -243,6 +243,15 @@ "type-detect": "4.0.8" } }, + "@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, "@sinonjs/formatio": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-4.0.1.tgz", @@ -445,6 +454,115 @@ "xml2js": "0.4.19" } }, + "aws-sdk-mock": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/aws-sdk-mock/-/aws-sdk-mock-5.1.0.tgz", + "integrity": "sha512-Wa5eCSo8HX0Snqb7FdBylaXMmfrAWoWZ+d7MFhiYsgHPvNvMEGjV945FF2qqE1U0Tolr1ALzik1fcwgaOhqUWQ==", + "dev": true, + "requires": { + "aws-sdk": "^2.637.0", + "sinon": "^9.0.1", + "traverse": "^0.6.6" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.2.tgz", + "integrity": "sha512-sruwd86RJHdsVf/AtBoijDmUqJp3B6hF/DGC23C+JaegnDHaZyewCjoVGTdg3J0uz3Zs7NnIT05OBOmML72lQw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "aws-sdk": { + "version": "2.855.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.855.0.tgz", + "integrity": "sha512-u1lO75V82E4REeu0Pt3RE1Kg2CdtUoMgMnyR02cUxdWnoTBpdSlwvz2X2U0VEGW2oYzeJJYp0N0H1sgSRnv8vg==", + "dev": true, + "requires": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.15.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "uuid": "3.3.2", + "xml2js": "0.4.19" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", @@ -3475,6 +3593,12 @@ } } }, + "traverse": { + "version": "0.6.6", + "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.6.6.tgz", + "integrity": "sha1-y99WD9e5r2MlAv7UD5GMFX6pcTc=", + "dev": true + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", diff --git a/package.json b/package.json index ec83fd6..3e69b15 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ }, "devDependencies": { "aws-sdk": "2.595.0", + "aws-sdk-mock": "^5.1.0", "chai": "4.2.0", "chai-as-promised": "7.1.1", "coveralls": "3.0.9", diff --git a/test/handler.js b/test/handler.js index 1ee5528..7b100cf 100644 --- a/test/handler.js +++ b/test/handler.js @@ -6,7 +6,10 @@ const mockDate = require('mockdate') const mockSpawn = require('mock-spawn') const chai = require('chai') const chaiAsPromised = require('chai-as-promised') +const AWSMOCK = require('aws-sdk-mock') +const AWS = require('aws-sdk') +AWSMOCK.setSDKInstance(AWS) chai.should() chai.use(chaiAsPromised) @@ -69,6 +72,22 @@ describe('Handler', () => { ) }) + it('should be able to authenticate via IAM ', async () => { + const { s3Spy, pgSpy } = makeMockHandler() + + const iamMockEvent = { ...mockEvent, USE_IAM_AUTH: true } + const token = 'foo' + AWSMOCK.mock('RDS.Signer', 'getAuthToken', token) + await handler(iamMockEvent) + // handler should have called pgSpy with correct arguments + expect(pgSpy.calledOnce).to.be.true + expect(s3Spy.calledOnce).to.be.true + expect(s3Spy.firstCall.args).to.have.length(3) + const config = s3Spy.firstCall.args[1] + expect(await config.PGPASSWORD.promise()).to.equal(token) // production code is synchronous, so this is annoying + AWSMOCK.restore('RDS') + }) + it('should upload the backup file and an iv file', async () => { const { s3Spy } = makeMockHandler() From dc9de01c524d3693a2f2a0383237056b91a79b73 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 18:53:42 +0100 Subject: [PATCH 10/14] polish --- lib/handler.js | 16 +++------------- lib/iam.js | 14 ++++++++++++++ test/handler.js | 3 ++- test/iam.js | 29 +++++++++++++++++++++++++++++ 4 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 lib/iam.js create mode 100644 test/iam.js diff --git a/lib/handler.js b/lib/handler.js index 9ccd2c1..6276765 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -1,7 +1,8 @@ -const AWS = require('aws-sdk') const utils = require('./utils') const uploadS3 = require('./upload-s3') const pgdump = require('./pgdump') +const decorateWithIamToken = require('./iam') + const encryption = require('./encryption') const DEFAULT_CONFIG = require('./config') @@ -33,17 +34,6 @@ async function backup(config) { return uploadS3(stream, config, key) } -function decorateWithIamToken(baseConfig) { - const rdsSigner = new AWS.RDS.Signer() - const token = rdsSigner.getAuthToken({ - hostname: baseConfig.PGHOST, - port: baseConfig.PGPORT != null ? baseConfig.PGPORT : 5432, - region: baseConfig.S3_REGION, - username: baseConfig.PGUSER - }) - return { ...baseConfig, PGPASSWORD: token } -} - async function handler(event) { const baseConfig = { ...DEFAULT_CONFIG, ...event } const config = event.USE_IAM_AUTH === true ? decorateWithIamToken(baseConfig) : baseConfig @@ -59,4 +49,4 @@ async function handler(event) { } } -module.exports = handler +module.exports = handler, decorateWithIamToken diff --git a/lib/iam.js b/lib/iam.js new file mode 100644 index 0000000..a7be49a --- /dev/null +++ b/lib/iam.js @@ -0,0 +1,14 @@ +const AWS = require('aws-sdk') + +function decorateWithIamToken(baseConfig) { + const rdsSigner = new AWS.RDS.Signer() + const token = rdsSigner.getAuthToken({ + hostname: baseConfig.PGHOST, + port: baseConfig.PGPORT != null ? baseConfig.PGPORT : 5432, + region: baseConfig.S3_REGION, + username: baseConfig.PGUSER + }) + return { ...baseConfig, PGPASSWORD: token } +} + +module.exports = decorateWithIamToken diff --git a/test/handler.js b/test/handler.js index 7b100cf..f01f683 100644 --- a/test/handler.js +++ b/test/handler.js @@ -84,7 +84,8 @@ describe('Handler', () => { expect(s3Spy.calledOnce).to.be.true expect(s3Spy.firstCall.args).to.have.length(3) const config = s3Spy.firstCall.args[1] - expect(await config.PGPASSWORD.promise()).to.equal(token) // production code is synchronous, so this is annoying + // production code is synchronous, so this is annoying + expect(await config.PGPASSWORD.promise()).to.equal(token) AWSMOCK.restore('RDS') }) diff --git a/test/iam.js b/test/iam.js new file mode 100644 index 0000000..c303d56 --- /dev/null +++ b/test/iam.js @@ -0,0 +1,29 @@ +/* eslint no-underscore-dangle: 0 */ +const { expect } = require('chai') +const rewire = require('rewire') +const chai = require('chai') +const chaiAsPromised = require('chai-as-promised') +const AWSMOCK = require('aws-sdk-mock') +const AWS = require('aws-sdk') + +chai.should() +chai.use(chaiAsPromised) + +AWSMOCK.setSDKInstance(AWS) + + +const decorateWithIamToken = rewire('../lib/iam') + +describe('iam-based auth', () => { + it('should set the postgres default if no PGPORT is set', async () => { + const mockEvent = { USE_IAM_AUTH: true } + const token = 'foo' + AWSMOCK.mock('RDS.Signer', 'getAuthToken', (options) => { + expect(options.port).to.equal(5432) + return token + }) + decorateWithIamToken(mockEvent) + + AWSMOCK.restore('RDS') + }) +}) From 0f9606c87d4de8e40133c1d7a2dd178e7818d8d2 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Wed, 3 Mar 2021 19:05:47 +0100 Subject: [PATCH 11/14] Add missing test --- test/.eslintrc | 3 +++ test/iam.js | 14 +++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/test/.eslintrc b/test/.eslintrc index b03d657..0562c49 100644 --- a/test/.eslintrc +++ b/test/.eslintrc @@ -4,5 +4,8 @@ "globals": { "describe": true, "it": true + }, + "env": { + "mocha": true } } diff --git a/test/iam.js b/test/iam.js index c303d56..231cffb 100644 --- a/test/iam.js +++ b/test/iam.js @@ -23,7 +23,19 @@ describe('iam-based auth', () => { return token }) decorateWithIamToken(mockEvent) + }) + + it('should apply PGPORT to the auth-token request', async () => { + const mockEvent = { USE_IAM_AUTH: true, PGPORT: 2345 } + const token = 'foo' + AWSMOCK.mock('RDS.Signer', 'getAuthToken', (options) => { + expect(options.port).to.equal(mockEvent.PGPORT) + return token + }) + decorateWithIamToken(mockEvent) + }) - AWSMOCK.restore('RDS') + afterEach(() => { + AWSMOCK.restore('RDS.Signer') }) }) From 2f1d737b5380e6d9e4ccbeffb08561814aee26d2 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Fri, 5 Mar 2021 13:28:55 +0100 Subject: [PATCH 12/14] formatting Co-authored-by: James Hutchby --- lib/handler.js | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/handler.js b/lib/handler.js index 6276765..711d19b 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -2,7 +2,6 @@ const utils = require('./utils') const uploadS3 = require('./upload-s3') const pgdump = require('./pgdump') const decorateWithIamToken = require('./iam') - const encryption = require('./encryption') const DEFAULT_CONFIG = require('./config') From 14b2aac32ba45c5f0b140493d56369ff308a2b63 Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Fri, 5 Mar 2021 13:29:26 +0100 Subject: [PATCH 13/14] pin dep Co-authored-by: James Hutchby --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3e69b15..6c054cf 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ }, "devDependencies": { "aws-sdk": "2.595.0", - "aws-sdk-mock": "^5.1.0", + "aws-sdk-mock": "5.1.0", "chai": "4.2.0", "chai-as-promised": "7.1.1", "coveralls": "3.0.9", From 2afa59488ebb9f843dd231f35794046fc0a7b44a Mon Sep 17 00:00:00 2001 From: Hans Westerbeek Date: Mon, 8 Mar 2021 08:47:19 +0100 Subject: [PATCH 14/14] polish refactoring left-over Co-authored-by: James Hutchby --- lib/handler.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/handler.js b/lib/handler.js index 711d19b..8ac0532 100644 --- a/lib/handler.js +++ b/lib/handler.js @@ -48,4 +48,4 @@ async function handler(event) { } } -module.exports = handler, decorateWithIamToken +module.exports = handler