Skip to main content

IAM Roles & Policies

After the Phase 7 cleanup of 2026-05-14 the legacy EC2 instance roles + their 9 custom policies are gone. The production-active set is:

  • ECS task roles for backend + bg-tasks (carry the runtime AWS permissions).
  • ECS execution roles for Fargate runtime (image pull, logs, secrets).
  • github-actions-role for CI/CD via OIDC.
  • EC2-SSM-Profile for the only remaining EC2 (Jitsi).
  • A handful of single-purpose roles (aiqlick-scheduler-role, aiqlick-canary-role-dev, aiqlick-rum-dev-unauth-role, aiqlick-aws-config-role).

No static access keys are used anywhere.

ECS task roles (active)

These are the runtime roles every Fargate task assumes. Each carries one inline policy that covers the full app-level permission surface; no managed policies are attached, so the per-env grants are visible in one place.

RoleTrust principalInline policyUsed by
aiqlick-ecs-backend-task-role-prodecs-tasks.amazonaws.comBackendTaskPolicybackend-prod ECS service
aiqlick-ecs-backend-task-role-devecs-tasks.amazonaws.comBackendTaskPolicybackend-dev ECS service
aiqlick-ecs-bg-task-role-prodecs-tasks.amazonaws.comBgTaskPolicybg-tasks-prod ECS service
aiqlick-ecs-bg-task-role-devecs-tasks.amazonaws.comBgTaskPolicybg-tasks-dev ECS service

BackendTaskPolicy grants

  • S3 CRUD on aiqlick-uploads/* and aiqlick-dev-uploads/*
  • SQS send/receive on aiqlick-{mail,notifications-delivery,notifications-fanout,inbound-jobs,inbound-cvs,agent-docs,bg-events}-{env} + their DLQs
  • SNS publish on arn:aws:sns:eu-north-1:842697652860:aiqlick-pubsub-{env}
  • EventBridge PutEvents on aiqlick-events-{env}
  • AppConfig read on the e6qub9k application's {env} environment + zatlet7 profile
  • Secrets Manager read on aiqlick-backend/{env}*
  • X-Ray PutTraceSegments / PutTelemetryRecords

BgTaskPolicy grants

  • Bedrock InvokeModel / InvokeModelWithResponseStream (eu-north-1 + cross-region inference profiles)
  • Rekognition DetectFaces (eu-west-1)
  • Transcribe StartStreamTranscription (eu-west-1)
  • Polly SynthesizeSpeech, DescribeVoices (eu-west-1)
  • S3 CRUD on uploads buckets
  • SQS receive/delete on aiqlick-{inbound-jobs,inbound-cvs,agent-docs,bg-events}-{env} + DLQs
  • SNS publish on aiqlick-pubsub-{env}
  • EventBridge PutEvents on aiqlick-events-{env}
  • AppConfig read
  • Secrets Manager read on aiqlick-backend/{env}*
  • X-Ray

The repo source for these is at aiqlick-backend/infrastructure/ecs/iam/ and background-tasks/infrastructure/ecs/iam/.

ECS execution roles

These are the roles Fargate itself assumes to launch a task — distinct from the task role, which the running app uses.

RoleTrust principalGrants
aiqlick-ecs-execution-role-prodecs-tasks.amazonaws.comECR pull, CloudWatch Logs CreateLogStream/PutLogEvents on /ecs/aiqlick-*-prod, Secrets Manager GetSecretValue on aiqlick-backend/production*
aiqlick-ecs-execution-role-devecs-tasks.amazonaws.comSame shape, scoped to *-dev log groups + aiqlick-backend/development* secret

The execution role's secretsmanager:GetSecretValue is what hydrates _BUNDLE_JSON into the container at task startup — see Secrets Management.

CI/CD role

github-actions-role

Authentication: OIDC federation with GitHub Actions (no static credentials).

PolicyGrants
AmazonEC2ContainerRegistryPowerUserPush + pull images to/from ECR
aiqlick-ecs-deploy-policy (inline)ecs:RegisterTaskDefinition, ecs:UpdateService, ecs:RunTask, ecs:DescribeServices, ecs:DescribeTasks, ecs:Wait*; iam:PassRole on the four ECS task roles + the two execution roles
AmazonSSMFullAccessSSM commands — used only by the Jitsi deploy workflow now (backend / BG / FE / docs deploys talk to ECS APIs directly, no SSM)
github-actions-amplify-policyRead-only access to Amplify (build status monitor)

OIDC trust policy

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::842697652860:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:AiQlickProject/*:*"
}
}
}
]
}

The sub condition scopes access to the AiQlickProject GitHub organization. Individual workflows assume this role using aws-actions/configure-aws-credentials@v4 with role-to-assume.

EC2 (Jitsi only)

ProfileUsed byGrants
EC2-SSM-Profile (instance profile only — no role attached today)aiqlick-jitsiAmazonSSMManagedInstanceCore (SSM agent). Jitsi doesn't talk to AWS services directly.

The legacy aiqlick-{backend,ai}-ec2-role and their 9 custom policies were deleted in the Phase 7 cleanup of 2026-05-14.

Other AWS service roles

RoleTrust principalPurpose
aiqlick-scheduler-rolescheduler.amazonaws.comEventBridge Scheduler → invokes the aiqlick-cron-destination API destination for cron POSTs into the backend. Idle until CRON_MODE=external is flipped.
aiqlick-canary-role-devlambda.amazonaws.comCloudWatch Synthetics canary execution.
aiqlick-rum-dev-unauth-roleCognito identity poolCloudWatch RUM unauthenticated identity for browser RUM.
aiqlick-aws-config-roleconfig.amazonaws.comAWS Config aggregator.
CodeBuildServiceRole-aiqlick-backendcodebuild.amazonaws.comCodeBuild (used by the support-backend-rust pipeline).

Security groups

See Network & DNS — Security Groups for the canonical SG inventory. The legacy aiqlick-backend-sg and aiqlick-ai-dev-private-sg were deleted in the Phase 7 cleanup.

Cross-region service access

The bg-tasks ECS task role accesses these services in other regions via the eu-north-1 NAT gateway:

ServiceRegionAccessed by
Rekognitioneu-west-1 (Ireland)aiqlick-ecs-bg-task-role-{dev,prod}
Transcribeeu-west-1 (Ireland)aiqlick-ecs-bg-task-role-{dev,prod}
Polly (Neural TTS)eu-west-1 (Ireland)aiqlick-ecs-bg-task-role-{dev,prod}
SSO Identity Centerus-east-1Console login only

ACM certs for CloudFront and Amplify must live in us-east-1 (AWS requirement); ALB certs live in eu-north-1 with the ALB.