mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-09-30 18:33:18 +00:00
Security review (6 detectors + proof-or-kill verifier) confirmed 1 critical and 1 high in the first revision, both inherited by mirroring the SAM copy's Resource "*" role grants: - C1 (critical): iam:UpdateAssumeRolePolicy on "*" with DenySelfMutation covering only three name patterns lets the principal repoint the AdministratorAccess CDK bootstrap role's trust policy to an external account. - C2 (high): the SAM justification for role/* (SAM auto-roles land at path / with no settable RolePath) does not transfer -- Terraform's aws_iam_role supports path. Fixes, closing the class at the root rather than by denylist: - All role writes, boundary sets and PassRole confined to role/tf-managed/*; reads split into a separate statement that keeps Resource "*". - DenySelfMutation extended to cdk-hnb659fds-*, OrganizationAccountAccessRole and seahaven-* as defense in depth. - OIDC provider made conditional (CreateOIDCProvider), mirroring the sibling substrate, so a first-create rollback is recoverable rather than wedging the stack in ROLLBACK_COMPLETE against a Retained orphan. - README corrected: the guardrail policy is NOT Retain (only the provider is), so the Deny backstops do not survive a stack delete. checkov CKV_AWS_109 no longer fires on this template, so no suppression is needed. The template header records every divergence from the SAM copy.
68 lines
3 KiB
TypeScript
68 lines
3 KiB
TypeScript
import * as cdk from "aws-cdk-lib";
|
|
import * as cfninc from "aws-cdk-lib/cloudformation-include";
|
|
import * as path from "path";
|
|
import { Construct } from "constructs";
|
|
|
|
export interface TerraformSubstrateStackProps extends cdk.StackProps {
|
|
/**
|
|
* Create the app.terraform.io OIDC identity provider in this account.
|
|
* Defaults to true - Phase-0 checks (2026-07-30) confirmed neither prod nor
|
|
* dev has one. Set false for an account that already has the provider: an
|
|
* account holds exactly ONE provider per URL, so a duplicate create fails.
|
|
*
|
|
* This flag also makes a first-create rollback recoverable. The provider is
|
|
* Retain, so if any other resource in this stack fails on FIRST create the
|
|
* provider survives as an orphan while the stack lands in ROLLBACK_COMPLETE
|
|
* (which cannot be updated). Recovery is to delete the stack and either
|
|
* remove the orphaned provider or redeploy with this false.
|
|
*/
|
|
createOidcProvider?: boolean;
|
|
}
|
|
|
|
/**
|
|
* Per-account HCP Terraform deploy substrate: the shared account-level
|
|
* resources every Terraform workspace pipeline needs -
|
|
* - app.terraform.io OIDC identity provider (conditional, see props), and
|
|
* - `seahaven-hcptf-iam-management`, the shared boundary-gated IAM
|
|
* guardrail policy every per-workspace APPLY role attaches.
|
|
*
|
|
* Deliberately NOT here: per-workspace hcptf-<stack> / hcptf-<stack>-plan
|
|
* roles. Those are appended to the template at each stack's migration time
|
|
* (accumulator pattern, parallel to per-repo githubdeploy-* roles) so an
|
|
* account never accumulates trust for workspaces that do not deploy to it.
|
|
*
|
|
* The IAM guardrail statements DERIVE FROM seahaven-cfn-exec-iam-management in
|
|
* lib/deploy-substrate/deploy-substrate.template.yaml but are deliberately
|
|
* STRICTER (role writes and PassRole confined to the tf-managed path, wider
|
|
* DenySelfMutation) - the SAM copy's Resource "*" grants were confirmed a
|
|
* critical escalation primitive by the 2026-07-30 security review, and its
|
|
* justification for them does not transfer to Terraform. See the provenance
|
|
* header in lib/terraform-substrate/terraform-substrate.template.yaml for the
|
|
* full divergence list, and for the boundary-ARN coupling to the
|
|
* seahaven-deploy-substrate stack (bin/app.ts carries the explicit
|
|
* addStackDependency; the ARN reference alone creates no CFN edge).
|
|
*/
|
|
export class TerraformSubstrateStack extends cdk.Stack {
|
|
constructor(
|
|
scope: Construct,
|
|
id: string,
|
|
props?: TerraformSubstrateStackProps,
|
|
) {
|
|
super(scope, id, props);
|
|
|
|
new cfninc.CfnInclude(this, "Substrate", {
|
|
templateFile: path.join(
|
|
__dirname,
|
|
"terraform-substrate",
|
|
"terraform-substrate.template.yaml",
|
|
),
|
|
parameters: {
|
|
CreateOIDCProvider: props?.createOidcProvider === false ? "false" : "true",
|
|
},
|
|
});
|
|
|
|
cdk.Tags.of(this).add("Project", "account-baseline");
|
|
cdk.Tags.of(this).add("Owner", "adam@seahavenind.com");
|
|
cdk.Tags.of(this).add("ManagedBy", "cdk");
|
|
}
|
|
}
|