mirror of
https://github.com/Sea-Haven-Industries/seahaven-org-baseline.git
synced 2026-09-30 06:53:17 +00:00
* feat(iam): lock app-owned HCP IAM and add bootstrap SCP (PLAT-143) * fix(iam): pin HCP boundary ARNs and bootstrap trust window (PLAT-143) Null on iam:PermissionsBoundary accepted any ceiling, including AdministratorAccess. Import apply cannot self-mutate hcptf-* while bootstrap trust is iam-bootstrap only; add a time-boxed exact StringEquals workspace grant instead of StringLike.
117 lines
4.9 KiB
TypeScript
117 lines
4.9 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";
|
|
import { ShocFrontendResources } from "./terraform-substrate/shoc-frontend-resources";
|
|
|
|
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;
|
|
|
|
/**
|
|
* Enable the two SHOC backend tf-poc HCP roles. Defaults false so the
|
|
* external-dev base-stack create is role-free.
|
|
*/
|
|
enableShocBackendPocRoles?: boolean;
|
|
|
|
/**
|
|
* Enable the four existing SHOC backend dev/staging HCP roles. Defaults
|
|
* false because these names must enter the stack through CloudFormation
|
|
* resource import, never a normal create/update.
|
|
*/
|
|
enableShocBackendLiveRoles?: boolean;
|
|
|
|
/**
|
|
* Enable the SHOC frontend tf-poc HCP roles after its exact CloudFront
|
|
* identifiers and deploy-role guardrails have been reconciled.
|
|
*/
|
|
enableShocFrontendPocRoles?: boolean;
|
|
|
|
/**
|
|
* Enable the SHOC frontend dev/staging HCP roles after the existing GitHub
|
|
* deploy roles have their exact boundaries and manager tags.
|
|
*/
|
|
enableShocFrontendLiveRoles?: boolean;
|
|
|
|
/** Exact tf-poc site identifiers; empty values keep its roles disabled. */
|
|
shocFrontendPocDistributionId?: string;
|
|
shocFrontendPocOriginAccessControlId?: string;
|
|
shocFrontendPocFunctionName?: string;
|
|
shocFrontendPocHostedZoneId?: string;
|
|
shocFrontendPocCertificateArn?: string;
|
|
}
|
|
|
|
/**
|
|
* Per-account HCP Terraform deploy substrate. Prod/dev still carry the
|
|
* shared seahaven-hcptf-iam-management policy and the eight existing
|
|
* hcptf-<stack> pairs until PLAT-147 deletes those stacks. New prod/dev
|
|
* per-workspace IAM is not added here: app Terraform owns it, bootstrapped
|
|
* by the CLI-owned hcptf-bootstrap pair (PLAT-144/PLAT-145).
|
|
*
|
|
* External-dev conditions out the shared manager and uses exact inline
|
|
* policies for SHOC import roles. That IAM stays in this repo (PLAT-148).
|
|
*
|
|
* 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);
|
|
|
|
const substrate = new cfninc.CfnInclude(this, "Substrate", {
|
|
templateFile: path.join(
|
|
__dirname,
|
|
"terraform-substrate",
|
|
"terraform-substrate.template.yaml",
|
|
),
|
|
parameters: {
|
|
CreateOIDCProvider: props?.createOidcProvider === false ? "false" : "true",
|
|
EnableShocBackendPocRoles:
|
|
props?.enableShocBackendPocRoles === true ? "true" : "false",
|
|
EnableShocBackendLiveRoles:
|
|
props?.enableShocBackendLiveRoles === true ? "true" : "false",
|
|
},
|
|
});
|
|
|
|
if (props?.env?.account === "396287094661") {
|
|
new ShocFrontendResources(this, "ShocFrontend", {
|
|
template: substrate,
|
|
enablePocRoles: props?.enableShocFrontendPocRoles === true,
|
|
enableLiveRoles: props?.enableShocFrontendLiveRoles === true,
|
|
pocDistributionId: props?.shocFrontendPocDistributionId ?? "",
|
|
pocOriginAccessControlId:
|
|
props?.shocFrontendPocOriginAccessControlId ?? "",
|
|
pocFunctionName: props?.shocFrontendPocFunctionName ?? "",
|
|
pocHostedZoneId: props?.shocFrontendPocHostedZoneId ?? "",
|
|
pocCertificateArn: props?.shocFrontendPocCertificateArn ?? "",
|
|
});
|
|
}
|
|
|
|
cdk.Tags.of(this).add("Project", "account-baseline");
|
|
cdk.Tags.of(this).add("Owner", "adam@seahavenind.com");
|
|
cdk.Tags.of(this).add("ManagedBy", "cdk");
|
|
}
|
|
}
|