Git, CI/CD & GitOpsXC · CI Platform SecurityCloudAccess
Cloud access from CI — what cloud credentials do
What you'll learn
- Explain what an IAM role, a service account, and a subscription identity enable from a CI runner
- Verify the assumed identity with aws sts get-caller-identity before every privileged step
- Distinguish the trust policy on the cloud side from the workflow declaration on the forge side
- Recognise the failure modes of long-lived cloud keys versus OIDC federation
Prerequisites
Verified against Git 2.55.x teaching target; 2.40+ minimum · GitHub Actions continuous service; Aug 2026 documentation baseline · Argo CD v3.5.x teaching target; v3.0+ minimum · Flux v2.9.x · Sigstore Cosign v3.1.x · SLSA v1.2 · OCI Distribution Specification v1.1 · Git LFS v3.7.1 · Kubernetes (cross-course target) 1.36.x
A cloud credential that the CI assumes is a production credential. The role the workflow declares can read every resource the role can reach — including the production databases, the production object stores, the production secrets, and the production network. A CI job that assumes a misconfigured IAM role is a CI job that reads production silently. The discipline is two-fold: trust OIDC federation to issue the right token for the right job, and verify the assumed identity before every privileged step.
What a cloud credential enables
A cloud credential on a CI runner enables every capability the identity has been granted. The blast radius is the union of the identity’s grants.
flowchart TB
CRED["Cloud credential"]
CRED --> I["Identity layer"]
I --> R1["Compute"]
I --> R2["Storage"]
I --> R3["Database"]
I --> R4["Network"]
I --> R5["Secrets"]
I --> R6["Container"]
A narrow role limits the radius; a broad role with AdministratorAccess makes the radius the entire account. The categories are the same on every cloud: IAM in AWS, service accounts in GCP, subscription identities in Azure. The blast radius scales with the grants.
Verify the assumed identity
The first thing a CI step does after assuming a cloud
identity is verify which identity it assumed. AWS
provides aws sts get-caller-identity; GCP provides
gcloud auth list; Azure provides az account show:
aws sts get-caller-identity
The output names the account, the user/role ARN, and the session identifier. The CI engineer writes a test that parses the ARN and asserts it matches the expected role for the workflow; a mismatch fails the step before any privileged call. The verification catches a wrong trust policy, a wrong role, a leaked credential, and a misconfigured OIDC federation.
Trust policy and workflow declaration
OIDC federation requires two configurations that must
agree. The forge side: the workflow declares which role
it wants to assume via
aws-actions/configure-aws-credentials or equivalent.
The cloud side: the IAM role’s trust policy declares
which forge, repository, branch, and workflow path may
assume the role.
flowchart LR
subgraph FORGE["Forge side"]
W["Workflow declares role"]
end
subgraph CLOUD["Cloud side"]
T["Trust policy: repo plus branch plus workflow"]
end
FORGE -->|"Token validated"| CLOUD
CLOUD -->|"STS token issued"| JOB["Job, scoped, ~1h"]
A trust policy that allows '*' for the repository is a
trust policy that allows any repo on the forge to assume
the role. The structural fix is to scope the trust policy
to the repository, branch, and workflow path; the
operational rule is to review the trust policy every
time the workflow file changes.
Production discipline
- OIDC federation for cloud access. Every cloud has an OIDC integration; every workflow declares the role it needs; every trust policy is scoped to repo, branch, and workflow path.
- Verify the assumed identity before every privileged
step.
aws sts get-caller-identity,gcloud auth list,az account show. - No long-lived cloud keys on runners. No IAM user keys, no service account JSON files, no static credentials on disk or in environment variables.
- Trust policy is part of code review. The PR diff includes both the workflow and the trust policy.
- Audit the cloud surface quarterly. Every role the CI assumes, every trust policy, every OIDC issuer.
Cross-course references
- Part XC-01 (What the CI platform can touch) maps the cloud surface in the wider blast radius.
- Part XLI-03 (Production credentials on runners) covers why OIDC is the structural fix.
- Part XLIII-04 (OIDC in AWS) covers the practical AWS configuration.
- AWS for Production Sysadmins — Part XXXI (IAM) covers the trust policies that gate role assumption.
Quiz
Knowledge check · 4 questions
Q1. A CI workflow assumes an IAM role via OIDC. What is the first step the workflow should run after the assumption?
Q2. An OIDC trust policy that allows any repository (`'*'`) on the forge to assume the role is functionally equivalent to a static AWS access key on a shared runner.
Q3. Explain why the verification step (`aws sts get-caller-identity`) is structural rather than cosmetic in an OIDC-based CI workflow.
Q4. Diagnose a CI compromise that exfiltrated a production AWS account via a permissive OIDC trust policy.
Team T's deploy job assumes an IAM role via OIDC. The role's trust policy uses `'*'` for the repository because the team wanted multiple repos to deploy. An attacker opens a fork in an unrelated public repo, requests an OIDC token for the team's role, and the trust policy accepts it. The attacker uses the STS token to list every S3 bucket in the production account and to read the contents of the production backups bucket.
Passing score: 75%. Answers are checked in this browser.