CircleCI context dump: from a printed secret to the cloud account
A CI job that echoes your contexts hands an attacker production cloud credentials. Once printed, the whole context is burned, so you rotate all of it and deny the cloud sessions it issued.
A CI secret store concentrates the keys to your cloud, so one job that prints the context can hand an attacker production credentials. The principals are CI tokens and the secrets they expose, not a developer at a desk.
How the attack works
A CircleCI session or token authenticates from an IP and ASN not seen for the org and triggers a pipeline outside normal hours. A modified job step echoes or exports the project environment variables and attaches one or more contexts, printing or transmitting their values, including cloud OIDC config and a long-lived provider access key. That key then authenticates to the connected cloud account from the same IP and begins enumerating resources. In ATT&CK terms this is T1552, Unsecured Credentials, with T1195, Supply Chain Compromise, T1078, Valid Accounts, and T1648 for the job execution.
Why it works
Pipelines legitimately use contexts and environment variables, but they consume them without echoing them and do not produce attacker sign-ins. The tell is the chain: an unfamiliar-IP session runs a job that prints secret values, and those secrets then sign in to the cloud from the same IP. A long-lived static key in a broadly shared context is the root cause.
How to fix it
Revoke the CI session, treat every secret in the dumped contexts as exfiltrated and rotate all of them including the cloud key, and deny the cloud sessions already minted from those credentials. Rotating only part of the context leaves the rest valid. Forensics spans the CircleCI job and audit logs and the cloud provider’s audit log. For the class, replace long-lived cloud keys with short-lived OIDC-federated credentials, which make a context dump nearly worthless, scope and restrict context access, and scan job logs for secrets.
Practice it
We built this as a GraphLattice Range scenario so responders can rehearse cutting the CI cascade, rotating the whole context, and federating to OIDC.