mirror of
https://github.com/Sea-Haven-Industries/seahaven-account-baseline.git
synced 2026-08-04 16:56:14 +00:00
refactor(prod): drop cross-account CMK grant (slack-bot decommissioned 2026-07-23)
The AllowMgmtSlackBotReadViaDynamoDb key-policy statement targeted the seahaven-slack-bot roles, which were decommissioned 2026-07-23. Its successor sh-mcp is undeployed and uses same-account DynamoDB access, so no cross-account reader of the CMK-encrypted purchase-orders table exists. The prod CMK + SSM param + alarm-topic stacks remain (procurement-ingest still imports them). Add a scoped cross-account grant if/when a real cross-account consumer deploys.
This commit is contained in:
parent
c1347fcdb5
commit
313df882ba
1 changed files with 9 additions and 34 deletions
43
bin/app.ts
43
bin/app.ts
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env node
|
||||
import "source-map-support/register";
|
||||
import * as cdk from "aws-cdk-lib";
|
||||
import * as iam from "aws-cdk-lib/aws-iam";
|
||||
import { AccountBaselineStack } from "../lib/account-baseline-stack";
|
||||
import { AlarmTopicStack } from "../lib/alarm-topic-stack";
|
||||
import { BackupOffsiteStack } from "../lib/backup-offsite-stack";
|
||||
|
|
@ -173,44 +172,20 @@ new DynamoDbCmkStack(app, "dynamodb-cmk", {
|
|||
// `site-alerts` by constructed in-account ARN, so both must exist in prod
|
||||
// BEFORE that app's first prod deploy. Same stack names as mgmt (unique
|
||||
// per-account); distinct CDK ids.
|
||||
const prodDynamoCmk = new DynamoDbCmkStack(app, "dynamodb-cmk-prod", {
|
||||
stackName: "seahaven-dynamodb-cmk",
|
||||
env: { account: PROD_ACCOUNT, region: "us-east-1" },
|
||||
});
|
||||
|
||||
// seahaven-slack-bot stays in mgmt but reads the CMK-encrypted purchase-orders
|
||||
// table cross-account after the migration. The base statement's
|
||||
// kms:CallerAccount pin (correctly) excludes foreign callers, so the mgmt bot
|
||||
// roles need their own statement. Delegation-to-IAM per this stack's header:
|
||||
// PrincipalArn is wildcarded by stack prefix because CFN role suffixes rotate;
|
||||
// each bot role must ALSO carry an identity-policy grant on this key ARN
|
||||
// (added in the slack-bot repo's cutover PR).
|
||||
//
|
||||
// ⚠️ CUTOVER TRAP: the slack-bot's existing pattern resolves the CMK via SSM
|
||||
// /seahaven/dynamodb/cmk-arn — that parameter is ACCOUNT-LOCAL and in mgmt
|
||||
// resolves the MGMT key forever. The cutover PR's identity grant must use the
|
||||
// PROD key ARN (this stack's DynamoDbCmkArn output), never the mgmt param;
|
||||
// reusing the SSM pattern grants the wrong key and fails only at runtime.
|
||||
// No cross-account key-policy statement: the only cross-account reader of the
|
||||
// CMK-encrypted purchase-orders table (seahaven-slack-bot) was decommissioned
|
||||
// 2026-07-23, and its successor sh-mcp is undeployed and uses same-account
|
||||
// DynamoDB access. When/if a cross-account consumer materializes, add a
|
||||
// correctly-scoped grant then (target its real roles + account).
|
||||
//
|
||||
// Recovery note (failed FIRST create): the key is RETAIN, its alias/SSM param
|
||||
// are not — a CREATE_FAILED rollback orphans an unaliased rotation-enabled
|
||||
// key. Before re-running the deploy, list unaliased CMKs in prod and schedule
|
||||
// deletion of the orphan.
|
||||
prodDynamoCmk.key.addToResourcePolicy(
|
||||
new iam.PolicyStatement({
|
||||
sid: "AllowMgmtSlackBotReadViaDynamoDb",
|
||||
effect: iam.Effect.ALLOW,
|
||||
principals: [new iam.AccountPrincipal(ACCOUNT)],
|
||||
actions: ["kms:Decrypt", "kms:DescribeKey"],
|
||||
resources: ["*"],
|
||||
conditions: {
|
||||
StringEquals: { "kms:ViaService": "dynamodb.us-east-1.amazonaws.com" },
|
||||
ArnLike: {
|
||||
"aws:PrincipalArn": `arn:aws:iam::${ACCOUNT}:role/seahaven-slack-bot-*`,
|
||||
},
|
||||
},
|
||||
}),
|
||||
);
|
||||
new DynamoDbCmkStack(app, "dynamodb-cmk-prod", {
|
||||
stackName: "seahaven-dynamodb-cmk",
|
||||
env: { account: PROD_ACCOUNT, region: "us-east-1" },
|
||||
});
|
||||
|
||||
new AlarmTopicStack(app, "alarm-topic-prod", {
|
||||
stackName: "seahaven-alarm-topic",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue