seahaven-prod account baseline (Phase 5) (#50)
Some checks are pending
Deploy / deploy-management (push) Waiting to run
Deploy / deploy-external-dev (push) Waiting to run
Deploy / deploy-security (push) Waiting to run
Deploy / deploy-dev (push) Waiting to run
Deploy / deploy-prod (push) Waiting to run

* Add seahaven-prod member baseline (Phase 5)

Account 011934824531 is the target for all new production stacks; the
management account is frozen for new workloads. First proven exercise
of the automatic enrollment sweep (Enabled in 124s, no manual
create-members) and of AutoEnableStandards=NONE (no pre-enabled
standards, so CFN owns FSBP + CIS v3.0 cleanly). Default VPC deleted;
budget starts at $100 and resizes as tenants land.

* Apply Phase-5 review findings

Fleet gap closed: EBS encryption-by-default + IAM password policy were
management-account-only (the runbook's unscoped 'applied' claim hid
it); now applied and verified in all three member accounts, runbook
scoped per account. README stack inventory corrected (eleven stacks,
org-governance rows restored). Sweep comments reconciled: the
automatic enrollment sweep is proven (seahaven-prod, ~2min).
This commit is contained in:
Adam Moussa 2026-07-14 17:17:55 -04:00 • committed by GitHub
parent 0a7c1bc450
commit 2303a54ebc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 54 additions and 8 deletions

View file

@ -50,3 +50,12 @@ jobs:
stack-name: "seahaven-dev-baseline" stack-name: "seahaven-dev-baseline"
secrets: secrets:
deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN_DEV }} deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN_DEV }}
deploy-prod:
uses: Sea-Haven-Industries/.github/.github/workflows/cd-cdk.yaml@3cde673b9d05c0e68aac4d997d582f2543853d20 # main
with:
node-version: "24"
stacks: "prod-baseline"
stack-name: "seahaven-prod-baseline"
secrets:
deploy-role-arn: ${{ secrets.AWS_DEPLOY_ROLE_ARN_PROD }}

View file

@ -28,9 +28,11 @@ Stacks (deployed by the CD workflow — one job per target account):
| `seahaven-regional-baseline-us-east-2` | 328440206208 | us-east-2 | Bedrock invocation logging + AWS Config recorder + Security Hub (INFRA-91 / INFRA-16) | | `seahaven-regional-baseline-us-east-2` | 328440206208 | us-east-2 | Bedrock invocation logging + AWS Config recorder + Security Hub (INFRA-91 / INFRA-16) |
| `seahaven-backup` | 328440206208 | us-east-1 | Primary AWS Backup vault + plan + role (C-7) | | `seahaven-backup` | 328440206208 | us-east-1 | Primary AWS Backup vault + plan + role (C-7) |
| `seahaven-backup-offsite` | 328440206208 | us-west-2 | Governance-locked offsite copy vault (C-7) | | `seahaven-backup-offsite` | 328440206208 | us-west-2 | Governance-locked offsite copy vault (C-7) |
| `seahaven-org-governance` | 328440206208 | us-east-1 | AWS Organizations OU tree + SCPs (incl. the cdk-imported external-dev guardrails) |
| `seahaven-external-dev-baseline` | 396287094661 | us-east-1 | Member-account baseline: Config, GuardDuty, Security Hub (FSBP + CIS v3.0), Access Analyzer, flow logs, budget | | `seahaven-external-dev-baseline` | 396287094661 | us-east-1 | Member-account baseline: Config, GuardDuty, Security Hub (FSBP + CIS v3.0), Access Analyzer, flow logs, budget |
| `seahaven-security-baseline` | 001520130573 | us-east-1 | Member-account baseline for the delegated security-admin account (same construct set) | | `seahaven-security-baseline` | 001520130573 | us-east-1 | Member-account baseline for the delegated security-admin account (same construct set) |
| `seahaven-dev-baseline` | 710827005802 | us-east-1 | Member-account baseline for internal dev/staging (org-managed detection — no local GuardDuty/SecurityHub) | | `seahaven-dev-baseline` | 710827005802 | us-east-1 | Member-account baseline for internal dev/staging (org-managed detection — no local GuardDuty/SecurityHub) |
| `seahaven-prod-baseline` | 011934824531 | us-east-1 | Member-account baseline for production workloads (org-managed detection; mgmt account frozen for new workloads) |
## CDK app ## CDK app
@ -43,12 +45,12 @@ the TypeScript source — no separate compile step needed for `cdk synth` /
| Path | Role | | Path | Role |
|---|---| |---|---|
| `cdk.json` | CDK config: `app` synth command, `watch` includes/excludes, `context` feature flags | | `cdk.json` | CDK config: `app` synth command, `watch` includes/excludes, `context` feature flags |
| `bin/app.ts` | App entry point — instantiates every stack with an explicit kebab-case `stackName` and its target `env` (account `328440206208`, per-region) | | `bin/app.ts` | App entry point — instantiates every stack with an explicit kebab-case `stackName` and its target `env` (five accounts, per-account/per-region) |
| `lib/*-stack.ts` | Stack definitions (one class per stack; larger stacks compose the constructs in `lib/*.ts`) | | `lib/*-stack.ts` | Stack definitions (one class per stack; larger stacks compose the constructs in `lib/*.ts`) |
| `tsconfig.json` | TypeScript compiler options (`outDir: cdk.out`) | | `tsconfig.json` | TypeScript compiler options (`outDir: cdk.out`) |
| `package.json` | Pinned `aws-cdk-lib`, CDK CLI, and the `build` / `synth` / `diff` / `deploy` npm scripts | | `package.json` | Pinned `aws-cdk-lib`, CDK CLI, and the `build` / `synth` / `diff` / `deploy` npm scripts |
`bin/app.ts` synthesizes nine stacks across three regions and four accounts: `bin/app.ts` synthesizes eleven stacks across three regions and five accounts:
| Construct id | Stack name | Account | Region | Source | | Construct id | Stack name | Account | Region | Source |
|---|---|---|---|---| |---|---|---|---|---|
@ -58,9 +60,11 @@ the TypeScript source — no separate compile step needed for `cdk synth` /
| `regional-baseline-us-east-2` | `seahaven-regional-baseline-us-east-2` | 328440206208 | us-east-2 | `lib/regional-baseline-stack.ts` | | `regional-baseline-us-east-2` | `seahaven-regional-baseline-us-east-2` | 328440206208 | us-east-2 | `lib/regional-baseline-stack.ts` |
| `backup-offsite` | `seahaven-backup-offsite` | 328440206208 | us-west-2 | `lib/backup-offsite-stack.ts` | | `backup-offsite` | `seahaven-backup-offsite` | 328440206208 | us-west-2 | `lib/backup-offsite-stack.ts` |
| `backup` | `seahaven-backup` | 328440206208 | us-east-1 | `lib/backup-stack.ts` | | `backup` | `seahaven-backup` | 328440206208 | us-east-1 | `lib/backup-stack.ts` |
| `org-governance` | `seahaven-org-governance` | 328440206208 | us-east-1 | `lib/org-governance-stack.ts` |
| `external-dev-baseline` | `seahaven-external-dev-baseline` | 396287094661 | us-east-1 | `lib/member-baseline-stack.ts` | | `external-dev-baseline` | `seahaven-external-dev-baseline` | 396287094661 | us-east-1 | `lib/member-baseline-stack.ts` |
| `security-baseline` | `seahaven-security-baseline` | 001520130573 | us-east-1 | `lib/member-baseline-stack.ts` | | `security-baseline` | `seahaven-security-baseline` | 001520130573 | us-east-1 | `lib/member-baseline-stack.ts` |
| `dev-baseline` | `seahaven-dev-baseline` | 710827005802 | us-east-1 | `lib/member-baseline-stack.ts` (orgManagedDetection) | | `dev-baseline` | `seahaven-dev-baseline` | 710827005802 | us-east-1 | `lib/member-baseline-stack.ts` (orgManagedDetection) |
| `prod-baseline` | `seahaven-prod-baseline` | 011934824531 | us-east-1 | `lib/member-baseline-stack.ts` (orgManagedDetection) |
Member-account stacks deploy with per-account credentials — the CD workflow Member-account stacks deploy with per-account credentials — the CD workflow
runs one job per account, each assuming that account's OIDC deploy role. Local runs one job per account, each assuming that account's OIDC deploy role. Local
@ -71,6 +75,7 @@ deploys/diffs assume `OrganizationAccountAccessRole` in the target account.
| 396287094661 (external-dev) | `githubdeploy-seahaven-external-dev-baseline` | `AWS_DEPLOY_ROLE_ARN_EXTDEV` | | 396287094661 (external-dev) | `githubdeploy-seahaven-external-dev-baseline` | `AWS_DEPLOY_ROLE_ARN_EXTDEV` |
| 001520130573 (security) | `githubdeploy-seahaven-org-baseline` | `AWS_DEPLOY_ROLE_ARN_SECURITY` | | 001520130573 (security) | `githubdeploy-seahaven-org-baseline` | `AWS_DEPLOY_ROLE_ARN_SECURITY` |
| 710827005802 (dev) | `githubdeploy-seahaven-org-baseline` | `AWS_DEPLOY_ROLE_ARN_DEV` | | 710827005802 (dev) | `githubdeploy-seahaven-org-baseline` | `AWS_DEPLOY_ROLE_ARN_DEV` |
| 011934824531 (prod) | `githubdeploy-seahaven-org-baseline` | `AWS_DEPLOY_ROLE_ARN_PROD` |
Shared constructs (`DetectiveControls`, `FlowLogs`, `GovernanceToggles`) are Shared constructs (`DetectiveControls`, `FlowLogs`, `GovernanceToggles`) are
prefix-parameterized — construct ids and physical names must stay prefix-parameterized — construct ids and physical names must stay
@ -236,7 +241,11 @@ recording is never interrupted.
### CLI-applied governance toggles (no CloudFormation resource) ### CLI-applied governance toggles (no CloudFormation resource)
These account toggles have no native CloudFormation resource, so they are applied These account toggles have no native CloudFormation resource, so they are applied
via CLI and recorded here. Applied 2026-06-01. via CLI and recorded here — **per account** (they are account-scoped; a new
member account has NONE of them until applied). Applied: 328440206208
(2026-06-01); 001520130573, 710827005802, 011934824531 (2026-07-14 — EBS
encryption-by-default + password policy, verified per account; Inspector2 via
delegated admin; cost-allocation tags are org-level).
```bash ```bash
# M-3 EBS encryption-by-default (new volumes; existing 5 plaintext volumes are H-19-adjacent) # M-3 EBS encryption-by-default (new volumes; existing 5 plaintext volumes are H-19-adjacent)

View file

@ -13,6 +13,7 @@ const ACCOUNT = "328440206208";
const EXTERNAL_DEV_ACCOUNT = "396287094661"; const EXTERNAL_DEV_ACCOUNT = "396287094661";
const SECURITY_ACCOUNT = "001520130573"; const SECURITY_ACCOUNT = "001520130573";
const DEV_ACCOUNT = "710827005802"; const DEV_ACCOUNT = "710827005802";
const PROD_ACCOUNT = "011934824531";
// All 5 VPCs in 328440206208 / us-east-1 (4 custom + default), audit Agent 7. // All 5 VPCs in 328440206208 / us-east-1 (4 custom + default), audit Agent 7.
// Index-derived logical IDs — append only, never reorder. // Index-derived logical IDs — append only, never reorder.
@ -105,8 +106,9 @@ new MemberBaselineStack(app, "security-baseline", {
// Internal dev/staging workloads (NOT the external-dev engagement account). // Internal dev/staging workloads (NOT the external-dev engagement account).
// Created 2026-07-14 AFTER org delegation went live: GuardDuty detector + // Created 2026-07-14 AFTER org delegation went live: GuardDuty detector +
// Security Hub hub are org-managed — enrolled via delegated-admin // Security Hub hub are org-managed — enrolled via delegated-admin
// create-members and verified Enabled (the AUTOMATIC new-account sweep // create-members and verified Enabled (the AUTOMATIC sweep was later proven
// remains unexercised; do not rely on it without verifying). Standards and // on seahaven-prod, ~2min; still verify enrollment before any org-managed
// stack's first deploy). Standards and
// the account analyzer stay CFN-owned (SH-DEV-001/SH-DEVBASE-002). Same // the account analyzer stay CFN-owned (SH-DEV-001/SH-DEVBASE-002). Same
// lifecycle rule as the other new accounts: root-harden at org ROOT, then // lifecycle rule as the other new accounts: root-harden at org ROOT, then
// move-account into the nonprod OU (ou-nbuj-zpt5ka98) — NO WORKLOADS until // move-account into the nonprod OU (ou-nbuj-zpt5ka98) — NO WORKLOADS until
@ -128,6 +130,31 @@ new MemberBaselineStack(app, "dev-baseline", {
orgManagedDetection: true, orgManagedDetection: true,
}); });
// ── Member-account baseline: seahaven-prod (Phase 5) ────────────────────────
// Target for ALL new production stacks (mgmt 328440206208 is frozen for new
// workloads). First tenant: proposal-system redeploy. Detection is org-managed
// (AUTO-enrolled by the sweep in 124s — first proven exercise, 2026-07-14 —
// and verified Enabled before this stack's first deploy); standards + account
// analyzer are CFN-owned per the Phase-4 review. Default VPC DELETED (prod
// workloads use purpose-built VPCs). Same lifecycle rule: root-harden at org
// ROOT, then move-account into the prod OU (ou-nbuj-5lc2wp6h) — NO WORKLOADS
// until the account is inside the OU. Budget starts at $100 and is resized as
// tenants land; AWS Backup vaults are added with the first stateful tenant
// (cross-account restore test = definition of done for that change).
new MemberBaselineStack(app, "prod-baseline", {
stackName: "seahaven-prod-baseline",
env: { account: PROD_ACCOUNT, region: "us-east-1" },
namePrefix: "seahaven-prod",
monthlyBudgetUsd: 100,
budgetAlertEmail: "aws@seahaven.com",
ownerEmail: "adam@seahaven.com",
// Append-only, never reorder (index-derived logical IDs). Empty: no VPCs
// exist yet; append ids via PR as purpose-built VPCs land.
flowLogVpcIds: [],
managedByTag: "seahaven-org-baseline",
orgManagedDetection: true,
});
// ── Shared DynamoDB CMK (INFRA-95 / M-3) ───────────────────────────────────── // ── Shared DynamoDB CMK (INFRA-95 / M-3) ─────────────────────────────────────
// Dedicated, standalone stack so the customer-managed key for sensitive // Dedicated, standalone stack so the customer-managed key for sensitive
// finance/PII DynamoDB tables is an independent shared dependency for the owning // finance/PII DynamoDB tables is an independent shared dependency for the owning

View file

@ -22,9 +22,10 @@ export interface MemberBaselineStackProps extends cdk.StackProps {
/** Value for the ManagedBy tag on every resource in the stack. */ /** Value for the ManagedBy tag on every resource in the stack. */
readonly managedByTag: string; readonly managedByTag: string;
/** /**
* TRUE for accounts created after org delegation (2026-07-14): GuardDuty / * TRUE for accounts created after org delegation (2026-07-14): the GuardDuty
* Security Hub / analyzer are org-managed (auto-enrolled), so the stack must * detector and Security Hub hub are org-managed (auto-enrolled), so the
* not create local duplicates. Default FALSE (pre-delegation accounts). * stack must not create local duplicates. Standards and the account analyzer
* remain CFN-owned either way. Default FALSE (pre-delegation accounts).
*/ */
readonly orgManagedDetection?: boolean; readonly orgManagedDetection?: boolean;
} }