diff --git a/infra/lib/github-oidc-stack.ts b/infra/lib/github-oidc-stack.ts index 020af9a..6646706 100644 --- a/infra/lib/github-oidc-stack.ts +++ b/infra/lib/github-oidc-stack.ts @@ -144,7 +144,10 @@ export class GithubOidcStack extends cdk.Stack { role.addToPolicy(new iam.PolicyStatement({ sid: "InspectMigrationTask", actions: ["ecs:DescribeTaskDefinition"], - resources: [arn("ecs", "task-definition/TemplateApp*")], + // AWS authorizes this read API against "*", even for an exact task ARN. + // Rollout independently binds the returned task to this account/candidate. + resources: ["*"], + conditions: { StringEquals: { "aws:RequestedRegion": this.region } }, })); role.addToPolicy(new iam.PolicyStatement({ sid: "InspectMigrationCluster", diff --git a/infra/test/github-deployment-iam.test.ts b/infra/test/github-deployment-iam.test.ts index 6ade997..f870ffc 100644 --- a/infra/test/github-deployment-iam.test.ts +++ b/infra/test/github-deployment-iam.test.ts @@ -105,3 +105,12 @@ test("hosted external qualification reads scoped metadata and assets without pro const values = statements.filter(statement => JSON.stringify(statement.Action).includes("secretsmanager:GetSecretValue")); assert.equal(values.length, 1); assert.equal(values[0].Sid, "ReadClerkBuildConfiguration"); }); + +test("migration task inspection uses AWS-supported resource scope and stays regional", () => { + const statements = Object.values(template().findResources("AWS::IAM::Policy")) + .flatMap(resource => resource.Properties.PolicyDocument.Statement); + const inspection = statements.find(statement => statement.Sid === "InspectMigrationTask"); + assert.equal(inspection.Action, "ecs:DescribeTaskDefinition"); + assert.equal(inspection.Resource, "*"); + assert.deepEqual(inspection.Condition, { StringEquals: { "aws:RequestedRegion": "us-east-1" } }); +});