mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 15:03:16 +00:00
PR#1 of the AWS migration. CDK TypeScript app under /infra: stacks open-swe-iam (four per-env GitHub-OIDC deploy roles) + open-swe-dev/-prod (per-env EC2 instance role + AMI cache). aws-cdk-lib pinned exact 2.260.0; kebab naming Aspect + 15 tests. IAM is synth-only (NOT deployed). Cleared the Phase-1 security gates: - T4 GPT-4.1 IAM cross-review (StringEquals trust; cdk-hnb659fds-* wildcard kept as org convention; AWS-RunShellScript timeboxed to T19). - T5 /sh-security-review: deploy roles split PER-ENV with env-scoped OIDC trust (dev=branch ref+tag dev, prod=environment:prod+tag prod) so a dev token cannot reach prod; re-verified block:false.
38 lines
1.8 KiB
TypeScript
38 lines
1.8 KiB
TypeScript
import * as cdk from "aws-cdk-lib";
|
|
import { Construct } from "constructs";
|
|
import { GithubDeployRoles } from "./constructs/github-deploy-roles";
|
|
|
|
/**
|
|
* Account-level IAM stack: the per-ENV GitHub OIDC deploy roles
|
|
* (githubdeploy-open-swe-{infra,app}-{dev,prod} — four roles).
|
|
*
|
|
* T5 OSWE-IAC-01/02 fix: roles are split per env with env-scoped OIDC trust, so
|
|
* a dev-branch token cannot reach prod (prod roles require the GitHub
|
|
* `prod` Environment manual-approval gate). They live in this dedicated stack
|
|
* rather than the env stacks because IAM roles are global and this stack ships
|
|
* FIRST (TODO.md BLOCK#3): the infra OIDC roles + the repo deploy-role-ARN
|
|
* secrets must exist before any infra/secrets CI step. Synth-only until the
|
|
* Phase-1 security gate (T4 + T5) clears (T6).
|
|
*/
|
|
export class OpenSweIamStack extends cdk.Stack {
|
|
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
|
|
super(scope, id, props);
|
|
|
|
const dev = new GithubDeployRoles(this, "DeployRolesDev", "dev");
|
|
const prod = new GithubDeployRoles(this, "DeployRolesProd", "prod");
|
|
|
|
cdk.Tags.of(this).add("project", "open-swe");
|
|
cdk.Tags.of(this).add("ManagedBy", "cdk");
|
|
|
|
const out = (id: string, role: { roleName?: string }, env: string, kind: string) =>
|
|
new cdk.CfnOutput(this, id, {
|
|
value: `arn:aws:iam::${this.account}:role/${role.roleName}`,
|
|
description: `OIDC role ARN for ${env} ${kind} deploys — set as the ${env} deploy-role secret.`,
|
|
});
|
|
|
|
out("InfraDeployRoleDevArn", dev.infraRole, "dev", "infra (CDK)");
|
|
out("AppDeployRoleDevArn", dev.appRole, "dev", "app (tag-scoped SSM + S3)");
|
|
out("InfraDeployRoleProdArn", prod.infraRole, "prod", "infra (CDK)");
|
|
out("AppDeployRoleProdArn", prod.appRole, "prod", "app (tag-scoped SSM + S3)");
|
|
}
|
|
}
|