Skip to content

Epic: Scope machine-to-machine IAM permissions to projects using the project tag #206

Closed
11 of 11 issues completed

Description

@ale210

Overview

We need incubator to generate a CI/CD role per project, and an ECS execution role and an ECS task role for each container, whose permissions are granted only against resources tagged with that project's project tag. Today two of those three roles share permissions across every project, and the project tag is not consistent enough to authorize against.

Action Items

Tracked as sub-issues. This issue closes when they do.

Resources/Instructions

The permission matrix this epic implements:

Role Project-scoped grant
CI/CD role ECR, ECS
ECS execution role ECR (image pull), Secrets (SSM parameters)
ECS task role S3, Cognito

Each role additionally keeps whatever it needs to function at all — the execution role writes logs, the task role has ECS Exec. Note the execution role's ECR access is a project-scoped grant in its own right, not incidental: it pulls the container image, and it should be able to pull only its own project's images, in the same way the CI/CD role should be able to push only its own project's images.

The three identities and where they are defined:

  1. CI/CD role — terraform/modules/cicd_integration/main.tf. Already one per project, and its trust policy is already scoped to that project's repository. Its permissions are not: all four roles attach the single shared policy incubator_builder, which grants ECR push to every repository and ecs:UpdateService on every service in the cluster.
  2. ECS task role — aws_iam_role.instance in terraform/modules/container/main.tf. Already one per container.
  3. ECS execution role — a hardcoded ARN in terraform/modules/container/main.tf, one role shared by all ten containers, carrying AmazonSSMFullAccess. This is the largest gap against the design and the widest permission in the account. It becomes one role per container, generated by the module alongside the task role.

How the project value reaches a policy: policies name the project literally, interpolated by Terraform, rather than self-referencing ${aws:PrincipalTag/project}. The project tag on the roles themselves is for inventory and reporting, not authorization.

Sequencing matters. Tag-based access control fails closed, so a policy conditioned on a tag that is missing or wrong denies access rather than over-granting. The tag-correctness issues must land and be verified before any policy issue does.

Naming trap: the shared execution role is named incubator-prod-ecs-task-role while the actual task roles are named ecs-container-*. The names are inverted relative to their function.

Dependency: #184 brings the shared execution role under Terraform.

Activity

  1. added this to the 02 - Security milestone on Sep 2, 2026
  2. changed the title [-]Scope machine-to-machine IAM permissions to projects using the project tag[/-] [+]Epic: Scope machine-to-machine IAM permissions to projects using the project tag[/+] on Sep 2, 2026
  3. moved this from New Issue Review to Prioritized Backlog in CoP: DevOps: Project Boardon Sep 5, 2026
  4. moved this from Prioritized Backlog to Done in CoP: DevOps: Project Boardon Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions