IAM — Identity & Access
IAM roles, policies, and GitHub OIDC provider for Ontopix services and CI/CD workflows.
Directory: global/iam/
Files: roles.tf, policies.tf, github_oidc.tf, github_oidc_roles.tf, outputs.tf, variables.tf
What It Manages
All IAM roles, policy attachments, and the GitHub Actions OIDC identity provider.
Module Scope
The iam/ module owns two categories of resources:
- The shared OIDC provider — a single
aws_iam_openid_connect_providerused by all GitHub Actions roles across all modules. - Cross-cutting GitHub Actions OIDC roles — roles whose target AWS service is not centrally managed in this repository (e.g. Terraform state access, Lambda deploy). Service-specific roles live in their respective modules instead (
ecr/owns ECR roles,codeartifact/owns CodeArtifact roles). - Service roles — non-OIDC roles for AWS services (Amplify, App Runner, CDK, Lambda).
When adding a new GitHub Actions OIDC role, place it in the module that manages the target service. If no such module exists (e.g. S3 deploy, CloudFront invalidation), add it here in iam/. See the Request IAM Role guide.
GitHub OIDC Provider
A single OIDC provider enables all GitHub Actions workflows across the ontopix organization to authenticate to AWS without long-lived credentials:
aws_iam_openid_connect_provider.github_actions
# URL: https://token.actions.githubusercontent.com
# Audience: sts.amazonaws.com
This provider is shared by the CodeArtifact and ECR module roles, as well as the cross-cutting OIDC roles defined in this module.
GitHub Actions OIDC Roles
Cross-cutting OIDC roles for CI and deploy workflows. Trust tiers follow ADR-003.
The tier model enforces a code vs infrastructure boundary: GHA can update code in existing resources (Deploy tier) but never create, delete, or configure resources (developer-only via terraform apply). See ADR-003 for the full philosophy and tradeoff analysis.
| Role | Tier | Permissions | Restricted To |
|---|---|---|---|
GitHubActions-Terraform-PlanRole | CI | TF state read + ReadOnlyAccess + AgentCore read | Any branch, all ontopix/* repos |
GitHubActions-Lambda-DeployRole | Deploy | Lambda deploy + invoke, S3 artifacts, SSM read | master/pre/dev branches only |
Audit Role
A read-only role for security auditing and compliance reviews. Auditors can inspect configurations across all AWS services without risk of accidental modifications or access to sensitive data.
| Role | Trusted Principals | Purpose |
|---|---|---|
AuditRole | albert.puigsech@ontopix.ai, josepmaria.roca@ontopix.ai, jano.carrion@ontopix.ai | Security and compliance reviews |
Attached policies:
| Policy | Type | Purpose |
|---|---|---|
ReadOnlyAccess | AWS Managed | Broad read access across all services |
SecurityAudit | AWS Managed | Security-focused read access (IAM, VPC, CloudTrail, GuardDuty, Config) |
NewServiceReadAccess | Inline | Read access for services too new for ReadOnlyAccess (Bedrock, AgentCore) |
DenySecretsAndSensitiveData | Inline (Deny) | Blocks access to secret values, SSM parameters, S3 objects, KMS decrypt, DynamoDB data |
To assume the role:
aws sts assume-role \
--role-arn "arn:aws:iam::{ACCOUNT_ID}:role/AuditRole" \
--role-session-name "audit-$(date +%Y%m%d)"
Service Roles
| Role | Service | Purpose |
|---|---|---|
AmplifyAdmin | Amplify | Administrate Amplify apps |
AmplifyDeveloper | Amplify | Develop Amplify apps |
Amplify-admin-role | Amplify | Backend deployment |
cdk-cfn-exec-role-*-us-east-1 | CloudFormation | CDK execution (us-east-1) |
cdk-cfn-exec-role-*-eu-central-1 | CloudFormation | CDK execution (eu-central-1) |
ontopix-schemas-schemas-deployer | Lambda | Schemas deployment |
mcp-lambda-edge-role-dev | Lambda@Edge | Edge functions |
mcp-hello-world-apprunner-* | App Runner | MCP Hello World service |
mcp-hello-calendar-apprunner-* | App Runner | MCP Hello Calendar service |
mcp-hello-orders-apprunner-* | App Runner | MCP Hello Orders service |
Policy Attachments
| Role | Policy | Type |
|---|---|---|
| AmplifyAdmin | AdministratorAccess-Amplify | AWS Managed |
| schemas-deployer | AWSLambdaBasicExecutionRole | AWS Managed |
| lambda-edge | AWSLambdaBasicExecutionRole | AWS Managed |
| Terraform-PlanRole | GitHubActions-TerraformPlanAccess | Custom |
| Terraform-PlanRole | ReadOnlyAccess | AWS Managed |
| Lambda-DeployRole | GitHubActions-LambdaDeployAccess | Custom |
| AuditRole | ReadOnlyAccess | AWS Managed |
| AuditRole | SecurityAudit | AWS Managed |
| AuditRole | NewServiceReadAccess | Inline |
| AuditRole | DenySecretsAndSensitiveData | Inline (Deny) |
Lambda Deploy: S3 Artifact Convention
The GitHubActions-Lambda-DeployRole supports S3-based Lambda deployments for any project that follows the bucket naming convention:
{project}-{env}-lambda-artifacts[-optional-suffix]
What the role provides:
| Capability | Actions | Resource Scope |
|---|---|---|
| Deploy Lambda code | UpdateFunctionCode, GetFunction | All Lambda functions in account |
| Upload/read S3 artifacts | PutObject, GetObject | *-*-lambda-artifacts*/lambdas/* |
| List artifact versions | ListBucket | *-*-lambda-artifacts* |
| Post-deploy smoke tests | InvokeFunction | All Lambda functions in account |
| SSM drift detection | GetParameter, GetParametersByPath | All SSM parameters in account |
How it works:
- Your project creates an S3 bucket in its
.infra/following the naming convention (e.g.,myproject-dev-lambda-artifacts) - Your deploy workflow uploads Lambda ZIPs to
s3://{bucket}/lambdas/{component}/{version}-{sha}.zip - The workflow calls
aws lambda update-function-code --s3-bucket {bucket} --s3-key lambdas/{component}/{version}-{sha}.zip - Post-deploy smoke tests invoke each Lambda with a test event to verify health
- Optional SSM drift detection reads parameters to compare against source of truth
No infra PR needed — the IAM policy uses a convention-based S3 pattern. Any bucket matching *-*-lambda-artifacts* is automatically accessible.
How to Request a New Role
See the Request IAM Role guide.