Skip to main content
CICD-SEC-2

Inadequate Identity and Access Management

The pipeline accumulates identities — human, machine, and inherited — that nobody has counted, scoped or retired.

If this is new to you

Every integration you add to a CI system creates an identity. A deploy key here, a service account there, a personal access token somebody generated for a one-off migration in 2022. Adding one takes a minute. Removing one takes somebody remembering it exists.

The result, in almost every organisation, is a pile of credentials that can reach production and have no owner. Nobody created them maliciously. Nobody is watching them either. That pile is what an attacker is hoping to find, because a credential with no owner is a credential whose theft nobody will notice.

What to do about it

Start with an inventory, and treat the difficulty of producing it as the finding. If it takes you a day to list every identity that can write to production, that is not a reporting problem — you cannot review what you cannot enumerate.

Then check each one resolves to a current human. Anything that does not is an orphan, and orphans should be deleted rather than documented.

Give every pipeline its own identity rather than sharing one. It costs nothing and it means your audit log names the actor instead of naming the mechanism. "deploy-bot did it" is not an audit trail.

Going deeper

The structural fix is to stop storing long-lived credentials at all. Most CI platforms can now exchange a short-lived OIDC token with your cloud provider, so the pipeline proves who it is at run time and receives a credential that expires in minutes. There is nothing sitting in a settings page to steal.

The other half is offboarding. Almost every organisation removes a leaver's human accounts and forgets the machine identities they created. Make machine credentials part of the same checklist.

Words used on this page
Service account
A non-human identity used by software rather than a person. Convenient, and the usual home of forgotten permissions.
OIDC federation
Letting your CI platform prove its identity to your cloud provider at run time, in exchange for a credential that expires quickly — instead of storing a permanent secret.
Least privilege
Giving an identity exactly the access it needs and nothing more. Easy to state, tedious to actually do, which is why it is usually skipped.

Why this matters

CI systems collect identities faster than any other part of an engineering organisation: every integration adds one, and almost nothing removes one. The result is a large set of credentials with production reach and no owner, which is exactly the asset an attacker is looking for.

What it looks like in practice

If any of these sound familiar, that is the point — most of them are things somebody did for a sensible reason on a busy afternoon.

  • Service accounts created for a one-off migration that still have write access years later.
  • A single shared deploy user, so every action in the audit log is attributed to 'deploy'.
  • Local accounts that survive an offboarding because they were never linked to the identity provider.
  • Personal access tokens with no expiry, belonging to someone who changed teams.
  • Registry credentials shared between the build system and developers' laptops.

Check your own pipeline

Questions you can actually answer, rather than a maturity score. If you cannot answer one of them, that is itself the finding — and a more useful one than a number.

  1. Can you enumerate every identity with write access to production?

    Write the list down. If it takes more than an hour to produce, that is the finding — you cannot review what you cannot list.

  2. Is every one of them attributable to a current employee or a named owner?

    Cross-reference against the identity provider. Anything that does not resolve is an orphan.

  3. Do machine credentials expire?

    A token with no expiry is a permanent credential; treat its age as its blast radius.

How to fix it

  • Federate. Identities that live only in the CI system are the ones that outlive their owners — use short-lived OIDC-issued credentials instead of stored tokens where the platform supports it.
  • Give each pipeline its own identity, scoped to what that pipeline touches, so the audit log names the actor rather than the mechanism.
  • Set expiry on everything, and treat renewal as a scheduled task rather than an incident.
  • Make offboarding cover machine identities, not only human ones.

Did this get you to an answer?

No text box on purpose — please do not paste production logs anywhere

Risk taxonomy from OWASP Top 10 CI/CD Security Risks (Daniel Krivelevich and Omer Gil, September 2022, CC BY-SA 4.0). Explanations, checks, fixes and definitions written for this site.