Migrate secrets from SSM to Secrets Manager

API tokens and credentials must live in Secrets Manager per
secrets-and-config.md, but the four original payment Lambdas still
read 10 SecureString SSM params. Move them to three grouped secrets
(slack-bot-token plaintext, boa-check-mgmt and boa-reporting as JSON),
matching the pattern the expense Lambdas already use. IAM is scoped to
secretsmanager:GetSecretValue per secret; the VPC Lambdas reach the
public endpoint over the existing NAT path. Test/reissue scripts and
the client-ssm dependency are updated/removed accordingly.

Refs: #3
This commit is contained in:
Adam Moussa 2026-06-02 20:29:18 -04:00
parent f2d8471cef
commit 90accf2f39
10 changed files with 96 additions and 169 deletions

22
package-lock.json generated
View file

@ -13,7 +13,6 @@
"@aws-sdk/client-s3": "^3.1059.0", "@aws-sdk/client-s3": "^3.1059.0",
"@aws-sdk/client-secrets-manager": "^3.1059.0", "@aws-sdk/client-secrets-manager": "^3.1059.0",
"@aws-sdk/client-sqs": "^3.1059.0", "@aws-sdk/client-sqs": "^3.1059.0",
"@aws-sdk/client-ssm": "^3.1059.0",
"@aws-sdk/lib-dynamodb": "^3.1059.0", "@aws-sdk/lib-dynamodb": "^3.1059.0",
"csv-parse": "^6.2.1", "csv-parse": "^6.2.1",
"mailparser": "^3.9.9" "mailparser": "^3.9.9"
@ -337,27 +336,6 @@
"node": ">=20.0.0" "node": ">=20.0.0"
} }
}, },
"node_modules/@aws-sdk/client-ssm": {
"version": "3.1059.0",
"resolved": "https://registry.npmjs.org/@aws-sdk/client-ssm/-/client-ssm-3.1059.0.tgz",
"integrity": "sha512-c6VaL8BKDeDSHWz59ELsYZcQit7r4aofVm07acWnxw1DQy5amQagOymPDhYwIpB6H3wZNMDu4FK3FxecNDzGww==",
"license": "Apache-2.0",
"dependencies": {
"@aws-crypto/sha256-browser": "5.2.0",
"@aws-crypto/sha256-js": "5.2.0",
"@aws-sdk/core": "^3.974.16",
"@aws-sdk/credential-provider-node": "^3.972.49",
"@aws-sdk/types": "^3.973.10",
"@smithy/core": "^3.24.6",
"@smithy/fetch-http-handler": "^5.4.6",
"@smithy/node-http-handler": "^4.7.6",
"@smithy/types": "^4.14.3",
"tslib": "^2.6.2"
},
"engines": {
"node": ">=20.0.0"
}
},
"node_modules/@aws-sdk/core": { "node_modules/@aws-sdk/core": {
"version": "3.974.16", "version": "3.974.16",
"resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.16.tgz", "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.974.16.tgz",

View file

@ -12,7 +12,6 @@
"@aws-sdk/client-s3": "^3.1059.0", "@aws-sdk/client-s3": "^3.1059.0",
"@aws-sdk/client-secrets-manager": "^3.1059.0", "@aws-sdk/client-secrets-manager": "^3.1059.0",
"@aws-sdk/client-sqs": "^3.1059.0", "@aws-sdk/client-sqs": "^3.1059.0",
"@aws-sdk/client-ssm": "^3.1059.0",
"@aws-sdk/lib-dynamodb": "^3.1059.0", "@aws-sdk/lib-dynamodb": "^3.1059.0",
"csv-parse": "^6.2.1", "csv-parse": "^6.2.1",
"mailparser": "^3.9.9" "mailparser": "^3.9.9"

View file

@ -1,16 +1,16 @@
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb"); const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient, ScanCommand } = require("@aws-sdk/lib-dynamodb"); const { DynamoDBDocumentClient, ScanCommand } = require("@aws-sdk/lib-dynamodb");
const { SSMClient, GetParameterCommand } = require("@aws-sdk/client-ssm"); const { SecretsManagerClient, GetSecretValueCommand } = require("@aws-sdk/client-secrets-manager");
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient({ region: "us-east-1" })); const ddb = DynamoDBDocumentClient.from(new DynamoDBClient({ region: "us-east-1" }));
const ssm = new SSMClient({ region: "us-east-1" }); const secrets = new SecretsManagerClient({ region: "us-east-1" });
const BOA_BASE_URL = "https://api.bofa.com"; const BOA_BASE_URL = "https://api.bofa.com";
async function getSSMParam(name) { async function getSecretJson(secretId) {
const { Parameter } = await ssm.send( const { SecretString } = await secrets.send(
new GetParameterCommand({ Name: name, WithDecryption: true }) new GetSecretValueCommand({ SecretId: secretId })
); );
return Parameter.Value; return JSON.parse(SecretString);
} }
async function getAccessToken(applicationID, clientId, clientSecret) { async function getAccessToken(applicationID, clientId, clientSecret) {
@ -115,13 +115,7 @@ async function getAccessToken(applicationID, clientId, clientSecret) {
} }
// Get credentials // Get credentials
const [appId, clientId, clientSecret, accountNumber, companyId] = await Promise.all([ const { appId, clientId, token: clientSecret, accountNumber, companyId } = await getSecretJson("payments-dashboard/boa-check-mgmt");
getSSMParam("/payments-dashboard/boa-check-mgmt-app-id"),
getSSMParam("/payments-dashboard/boa-check-mgmt-client-id"),
getSSMParam("/payments-dashboard/boa-check-mgmt-token"),
getSSMParam("/payments-dashboard/boa-account-number"),
getSSMParam("/payments-dashboard/boa-company-id"),
]);
// Fill in account number // Fill in account number
for (const item of issueList) { for (const item of issueList) {

View file

@ -8,16 +8,16 @@
* node scripts/test-boa-prod.js * node scripts/test-boa-prod.js
*/ */
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const BASE_URL = "https://api.bofa.com"; const BASE_URL = "https://api.bofa.com";
async function getSSMParam(name) { async function getSecretJson(secretId) {
const { Parameter } = await ssm.send( const { SecretString } = await secrets.send(
new GetParameterCommand({ Name: name, WithDecryption: true }) new GetSecretValueCommand({ SecretId: secretId })
); );
return Parameter.Value; return JSON.parse(SecretString);
} }
async function getAccessToken(applicationID, clientId, clientSecret) { async function getAccessToken(applicationID, clientId, clientSecret) {
@ -44,27 +44,19 @@ async function getAccessToken(applicationID, clientId, clientSecret) {
} }
async function main() { async function main() {
console.log("Loading credentials from SSM...\n"); console.log("Loading credentials from Secrets Manager...\n");
const [ const checkMgmt = await getSecretJson("payments-dashboard/boa-check-mgmt");
checkMgmtAppId, const reporting = await getSecretJson("payments-dashboard/boa-reporting");
checkMgmtClientId,
checkMgmtSecret, const checkMgmtAppId = checkMgmt.appId;
reportingAppId, const checkMgmtClientId = checkMgmt.clientId;
reportingClientId, const checkMgmtSecret = checkMgmt.token;
reportingSecret, const reportingAppId = reporting.appId;
accountNumber, const reportingClientId = reporting.clientId;
bankId, const reportingSecret = reporting.token;
] = await Promise.all([ const accountNumber = reporting.accountNumber;
getSSMParam("/payments-dashboard/boa-check-mgmt-app-id"), const bankId = reporting.bankId;
getSSMParam("/payments-dashboard/boa-check-mgmt-client-id"),
getSSMParam("/payments-dashboard/boa-check-mgmt-token"),
getSSMParam("/payments-dashboard/boa-reporting-app-id"),
getSSMParam("/payments-dashboard/boa-account-info-client-id"),
getSSMParam("/payments-dashboard/boa-account-info-token"),
getSSMParam("/payments-dashboard/boa-account-number"),
getSSMParam("/payments-dashboard/boa-bank-id"),
]);
console.log("Credentials loaded.\n"); console.log("Credentials loaded.\n");

View file

@ -11,17 +11,17 @@
* node scripts/test-boa-sandbox.js * node scripts/test-boa-sandbox.js
*/ */
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const SANDBOX_BASE = "https://api-sb.bofa.com"; const SANDBOX_BASE = "https://api-sb.bofa.com";
const AUTH_URL = `${SANDBOX_BASE}/authn/v1/client-authentication`; const AUTH_URL = `${SANDBOX_BASE}/authn/v1/client-authentication`;
async function getSSMParam(name) { async function getSecretJson(secretId) {
const { Parameter } = await ssm.send( const { SecretString } = await secrets.send(
new GetParameterCommand({ Name: name, WithDecryption: true }) new GetSecretValueCommand({ SecretId: secretId })
); );
return Parameter.Value; return JSON.parse(SecretString);
} }
async function getAccessToken(applicationID, clientId, clientSecret) { async function getAccessToken(applicationID, clientId, clientSecret) {
@ -51,23 +51,17 @@ async function getAccessToken(applicationID, clientId, clientSecret) {
} }
async function main() { async function main() {
console.log("Loading credentials from SSM...\n"); console.log("Loading credentials from Secrets Manager...\n");
const [ const checkMgmt = await getSecretJson("payments-dashboard/boa-check-mgmt");
checkMgmtClientId, const reporting = await getSecretJson("payments-dashboard/boa-reporting");
checkMgmtSecret,
accountInfoClientId, const checkMgmtClientId = checkMgmt.clientId;
accountInfoSecret, const checkMgmtSecret = checkMgmt.token;
accountNumber, const accountInfoClientId = reporting.clientId;
companyId, const accountInfoSecret = reporting.token;
] = await Promise.all([ const accountNumber = checkMgmt.accountNumber;
getSSMParam("/payments-dashboard/boa-check-mgmt-client-id"), const companyId = checkMgmt.companyId;
getSSMParam("/payments-dashboard/boa-check-mgmt-token"),
getSSMParam("/payments-dashboard/boa-account-info-client-id"),
getSSMParam("/payments-dashboard/boa-account-info-token"),
getSSMParam("/payments-dashboard/boa-account-number"),
getSSMParam("/payments-dashboard/boa-company-id"),
]);
console.log("Credentials loaded.\n"); console.log("Credentials loaded.\n");

View file

@ -1,17 +1,20 @@
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, ScanCommand, UpdateCommand } from "@aws-sdk/lib-dynamodb"; import { DynamoDBDocumentClient, ScanCommand, UpdateCommand } from "@aws-sdk/lib-dynamodb";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient()); const ddb = DynamoDBDocumentClient.from(new DynamoDBClient());
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const TABLE_NAME = process.env.TABLE_NAME; const TABLE_NAME = process.env.TABLE_NAME;
const BOA_BASE_URL = process.env.BOA_BASE_URL; const BOA_BASE_URL = process.env.BOA_BASE_URL;
async function getSSMParam(name) { let cachedCreds;
const { Parameter } = await ssm.send( async function getReportingCreds() {
new GetParameterCommand({ Name: name, WithDecryption: true }) if (cachedCreds) return cachedCreds;
const { SecretString } = await secrets.send(
new GetSecretValueCommand({ SecretId: process.env.BOA_REPORTING_SECRET_NAME })
); );
return Parameter.Value; cachedCreds = JSON.parse(SecretString);
return cachedCreds;
} }
async function getAccessToken(applicationID, clientId, clientSecret) { async function getAccessToken(applicationID, clientId, clientSecret) {
@ -34,13 +37,7 @@ async function getAccessToken(applicationID, clientId, clientSecret) {
} }
export const handler = async () => { export const handler = async () => {
const [appId, clientId, clientSecret, accountNumber, bankId] = await Promise.all([ const { appId, clientId, token: clientSecret, accountNumber, bankId } = await getReportingCreds();
getSSMParam(process.env.BOA_REPORTING_APP_ID_PARAM),
getSSMParam(process.env.BOA_REPORTING_CLIENT_ID_PARAM),
getSSMParam(process.env.BOA_REPORTING_SECRET_PARAM),
getSSMParam(process.env.BOA_ACCOUNT_NUMBER_PARAM),
getSSMParam(process.env.BOA_BANK_ID_PARAM),
]);
const bearerToken = await getAccessToken(appId, clientId, clientSecret); const bearerToken = await getAccessToken(appId, clientId, clientSecret);

View file

@ -1,20 +1,23 @@
import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3"; import { S3Client, GetObjectCommand } from "@aws-sdk/client-s3";
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand, PutCommand, UpdateCommand, ScanCommand } from "@aws-sdk/lib-dynamodb"; import { DynamoDBDocumentClient, GetCommand, PutCommand, UpdateCommand, ScanCommand } from "@aws-sdk/lib-dynamodb";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
import { parse } from "csv-parse/sync"; import { parse } from "csv-parse/sync";
const s3 = new S3Client(); const s3 = new S3Client();
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient()); const ddb = DynamoDBDocumentClient.from(new DynamoDBClient());
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const TABLE_NAME = process.env.TABLE_NAME; const TABLE_NAME = process.env.TABLE_NAME;
const BOA_BASE_URL = process.env.BOA_BASE_URL; const BOA_BASE_URL = process.env.BOA_BASE_URL;
async function getSSMParam(name) { let cachedCreds;
const { Parameter } = await ssm.send( async function getCheckMgmtCreds() {
new GetParameterCommand({ Name: name, WithDecryption: true }) if (cachedCreds) return cachedCreds;
const { SecretString } = await secrets.send(
new GetSecretValueCommand({ SecretId: process.env.BOA_CHECK_MGMT_SECRET_NAME })
); );
return Parameter.Value; cachedCreds = JSON.parse(SecretString);
return cachedCreds;
} }
async function getAccessToken(applicationID, clientId, clientSecret) { async function getAccessToken(applicationID, clientId, clientSecret) {
@ -97,13 +100,7 @@ async function backfillBoA() {
console.log(`Backfill: ${toSubmit.length} checks to submit`); console.log(`Backfill: ${toSubmit.length} checks to submit`);
const [appId, clientId, clientSecret, accountNumber, companyId] = await Promise.all([ const { appId, clientId, token: clientSecret, accountNumber, companyId } = await getCheckMgmtCreds();
getSSMParam(process.env.BOA_CHECK_MGMT_APP_ID_PARAM),
getSSMParam(process.env.BOA_CHECK_MGMT_CLIENT_ID_PARAM),
getSSMParam(process.env.BOA_CHECK_MGMT_SECRET_PARAM),
getSSMParam(process.env.BOA_ACCOUNT_NUMBER_PARAM),
getSSMParam(process.env.BOA_COMPANY_ID_PARAM),
]);
const bearerToken = await getAccessToken(appId, clientId, clientSecret); const bearerToken = await getAccessToken(appId, clientId, clientSecret);
const BOA_BATCH_SIZE = 100; const BOA_BATCH_SIZE = 100;
@ -379,13 +376,7 @@ export const handler = async (event) => {
// Submit to CashPro if there are any new issues or cancels // Submit to CashPro if there are any new issues or cancels
if (newChecks.length || cancelChecks.length) { if (newChecks.length || cancelChecks.length) {
const [appId, clientId, clientSecret, accountNumber, companyId] = await Promise.all([ const { appId, clientId, token: clientSecret, accountNumber, companyId } = await getCheckMgmtCreds();
getSSMParam(process.env.BOA_CHECK_MGMT_APP_ID_PARAM),
getSSMParam(process.env.BOA_CHECK_MGMT_CLIENT_ID_PARAM),
getSSMParam(process.env.BOA_CHECK_MGMT_SECRET_PARAM),
getSSMParam(process.env.BOA_ACCOUNT_NUMBER_PARAM),
getSSMParam(process.env.BOA_COMPANY_ID_PARAM),
]);
const bearerToken = await getAccessToken(appId, clientId, clientSecret); const bearerToken = await getAccessToken(appId, clientId, clientSecret);

View file

@ -8,13 +8,13 @@ import {
BatchWriteCommand, BatchWriteCommand,
} from "@aws-sdk/lib-dynamodb"; } from "@aws-sdk/lib-dynamodb";
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs"; import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
import { simpleParser } from "mailparser"; import { simpleParser } from "mailparser";
const s3 = new S3Client(); const s3 = new S3Client();
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient()); const ddb = DynamoDBDocumentClient.from(new DynamoDBClient());
const sqs = new SQSClient(); const sqs = new SQSClient();
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const TABLE_NAME = process.env.TABLE_NAME; const TABLE_NAME = process.env.TABLE_NAME;
const CHANNEL_ID = process.env.PAYROLL_CHANNEL_ID; const CHANNEL_ID = process.env.PAYROLL_CHANNEL_ID;
@ -23,13 +23,10 @@ const QUEUE_URL = process.env.PAYROLL_BATCH_QUEUE_URL;
let cachedToken; let cachedToken;
async function getSlackToken() { async function getSlackToken() {
if (cachedToken) return cachedToken; if (cachedToken) return cachedToken;
const { Parameter } = await ssm.send( const { SecretString } = await secrets.send(
new GetParameterCommand({ new GetSecretValueCommand({ SecretId: process.env.SLACK_BOT_TOKEN_SECRET_NAME })
Name: process.env.SLACK_BOT_TOKEN_PARAM,
WithDecryption: true,
})
); );
cachedToken = Parameter.Value; cachedToken = SecretString;
return cachedToken; return cachedToken;
} }

View file

@ -1,21 +1,18 @@
import { DynamoDBClient } from "@aws-sdk/client-dynamodb"; import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, GetCommand, ScanCommand } from "@aws-sdk/lib-dynamodb"; import { DynamoDBDocumentClient, GetCommand, ScanCommand } from "@aws-sdk/lib-dynamodb";
import { SSMClient, GetParameterCommand } from "@aws-sdk/client-ssm"; import { SecretsManagerClient, GetSecretValueCommand } from "@aws-sdk/client-secrets-manager";
const ddb = DynamoDBDocumentClient.from(new DynamoDBClient()); const ddb = DynamoDBDocumentClient.from(new DynamoDBClient());
const ssm = new SSMClient(); const secrets = new SecretsManagerClient();
const TABLE_NAME = process.env.TABLE_NAME; const TABLE_NAME = process.env.TABLE_NAME;
let cachedToken; let cachedToken;
async function getSlackToken() { async function getSlackToken() {
if (cachedToken) return cachedToken; if (cachedToken) return cachedToken;
const { Parameter } = await ssm.send( const { SecretString } = await secrets.send(
new GetParameterCommand({ new GetSecretValueCommand({ SecretId: process.env.SLACK_BOT_TOKEN_SECRET_NAME })
Name: process.env.SLACK_BOT_TOKEN_PARAM,
WithDecryption: true,
})
); );
cachedToken = Parameter.Value; cachedToken = SecretString;
return cachedToken; return cachedToken;
} }

View file

@ -241,7 +241,7 @@ Resources:
Timeout: 60 Timeout: 60
Environment: Environment:
Variables: Variables:
SLACK_BOT_TOKEN_PARAM: /payments-dashboard/slack-bot-token SLACK_BOT_TOKEN_SECRET_NAME: payments-dashboard/slack-bot-token
PAYROLL_CHANNEL_ID: C0AV5RBMYKU PAYROLL_CHANNEL_ID: C0AV5RBMYKU
PAYROLL_BATCH_QUEUE_URL: !Ref PayrollBatchQueue PAYROLL_BATCH_QUEUE_URL: !Ref PayrollBatchQueue
Events: Events:
@ -265,8 +265,11 @@ Resources:
BucketName: !Sub seahaven-payroll-emails-${AWS::AccountId} BucketName: !Sub seahaven-payroll-emails-${AWS::AccountId}
- DynamoDBCrudPolicy: - DynamoDBCrudPolicy:
TableName: !Ref DashboardTable TableName: !Ref DashboardTable
- SSMParameterReadPolicy: - Version: "2012-10-17"
ParameterName: payments-dashboard/slack-bot-token Statement:
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:payments-dashboard/slack-bot-token-*
- SQSSendMessagePolicy: - SQSSendMessagePolicy:
QueueName: !GetAtt PayrollBatchQueue.QueueName QueueName: !GetAtt PayrollBatchQueue.QueueName
- SQSPollerPolicy: - SQSPollerPolicy:
@ -281,11 +284,7 @@ Resources:
Environment: Environment:
Variables: Variables:
BOA_BASE_URL: https://api.bofa.com BOA_BASE_URL: https://api.bofa.com
BOA_CHECK_MGMT_APP_ID_PARAM: /payments-dashboard/boa-check-mgmt-app-id BOA_CHECK_MGMT_SECRET_NAME: payments-dashboard/boa-check-mgmt
BOA_CHECK_MGMT_CLIENT_ID_PARAM: /payments-dashboard/boa-check-mgmt-client-id
BOA_CHECK_MGMT_SECRET_PARAM: /payments-dashboard/boa-check-mgmt-token
BOA_ACCOUNT_NUMBER_PARAM: /payments-dashboard/boa-account-number
BOA_COMPANY_ID_PARAM: /payments-dashboard/boa-company-id
VpcConfig: VpcConfig:
SubnetIds: SubnetIds:
- !Ref PrivateSubnet - !Ref PrivateSubnet
@ -307,16 +306,11 @@ Resources:
BucketName: !Sub seahaven-payments-csv-${AWS::AccountId} BucketName: !Sub seahaven-payments-csv-${AWS::AccountId}
- DynamoDBCrudPolicy: - DynamoDBCrudPolicy:
TableName: !Ref DashboardTable TableName: !Ref DashboardTable
- SSMParameterReadPolicy: - Version: "2012-10-17"
ParameterName: payments-dashboard/boa-check-mgmt-app-id Statement:
- SSMParameterReadPolicy: - Effect: Allow
ParameterName: payments-dashboard/boa-check-mgmt-client-id Action: secretsmanager:GetSecretValue
- SSMParameterReadPolicy: Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:payments-dashboard/boa-check-mgmt-*
ParameterName: payments-dashboard/boa-check-mgmt-token
- SSMParameterReadPolicy:
ParameterName: payments-dashboard/boa-account-number
- SSMParameterReadPolicy:
ParameterName: payments-dashboard/boa-company-id
- Version: "2012-10-17" - Version: "2012-10-17"
Statement: Statement:
- Effect: Allow - Effect: Allow
@ -338,7 +332,7 @@ Resources:
- !Ref LambdaSecurityGroup - !Ref LambdaSecurityGroup
Environment: Environment:
Variables: Variables:
SLACK_BOT_TOKEN_PARAM: /payments-dashboard/slack-bot-token SLACK_BOT_TOKEN_SECRET_NAME: payments-dashboard/slack-bot-token
Events: Events:
SlackEvent: SlackEvent:
Type: HttpApi Type: HttpApi
@ -348,8 +342,11 @@ Resources:
Policies: Policies:
- DynamoDBReadPolicy: - DynamoDBReadPolicy:
TableName: !Ref DashboardTable TableName: !Ref DashboardTable
- SSMParameterReadPolicy: - Version: "2012-10-17"
ParameterName: payments-dashboard/slack-bot-token Statement:
- Effect: Allow
Action: secretsmanager:GetSecretValue
Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:payments-dashboard/slack-bot-token-*
- Version: "2012-10-17" - Version: "2012-10-17"
Statement: Statement:
- Effect: Allow - Effect: Allow
@ -373,11 +370,7 @@ Resources:
Environment: Environment:
Variables: Variables:
BOA_BASE_URL: https://api.bofa.com BOA_BASE_URL: https://api.bofa.com
BOA_REPORTING_APP_ID_PARAM: /payments-dashboard/boa-reporting-app-id BOA_REPORTING_SECRET_NAME: payments-dashboard/boa-reporting
BOA_REPORTING_CLIENT_ID_PARAM: /payments-dashboard/boa-account-info-client-id
BOA_REPORTING_SECRET_PARAM: /payments-dashboard/boa-account-info-token
BOA_ACCOUNT_NUMBER_PARAM: /payments-dashboard/boa-account-number
BOA_BANK_ID_PARAM: /payments-dashboard/boa-bank-id
Events: Events:
DailySchedule: DailySchedule:
Type: Schedule Type: Schedule
@ -388,16 +381,11 @@ Resources:
Policies: Policies:
- DynamoDBCrudPolicy: - DynamoDBCrudPolicy:
TableName: !Ref DashboardTable TableName: !Ref DashboardTable
- SSMParameterReadPolicy: - Version: "2012-10-17"
ParameterName: payments-dashboard/boa-reporting-app-id Statement:
- SSMParameterReadPolicy: - Effect: Allow
ParameterName: payments-dashboard/boa-account-info-client-id Action: secretsmanager:GetSecretValue
- SSMParameterReadPolicy: Resource: !Sub arn:aws:secretsmanager:${AWS::Region}:${AWS::AccountId}:secret:payments-dashboard/boa-reporting-*
ParameterName: payments-dashboard/boa-account-info-token
- SSMParameterReadPolicy:
ParameterName: payments-dashboard/boa-account-number
- SSMParameterReadPolicy:
ParameterName: payments-dashboard/boa-bank-id
- Version: "2012-10-17" - Version: "2012-10-17"
Statement: Statement:
- Effect: Allow - Effect: Allow