Most organisations have spent the last few years tightening human access. Engineers log in through SSO with MFA, maybe even through just-in-time access that eliminates standing admin on the cloud console. And then, sitting quietly in the corner of the same environment, is a Jenkins server with permanent, broad cloud credentials that nobody has reviewed in two years — running arbitrary code from every pull request in the organisation. The humans got governed. The machines did not.
This article is about that blind spot: the non-human identities in your CI/CD pipeline. Why they accumulate standing credentials, why they are often the single largest unmanaged blast radius in a cloud estate, and how agentic just-in-time access replaces permanent secrets with short-lived, auto-revoking credentials — across GCP, Azure, and AWS, and without rewriting your pipelines. (For the specific AWS-and-Jenkins mechanics of scoping down an over-privileged pipeline role, see the companion piece on securing Jenkins pipelines with JIT; this piece takes the broader non-human-identity view.)
The Non-Human Identity Problem
A non-human identity is any principal that is not a person: a CI/CD pipeline, a build agent, a service account, a Lambda or Cloud Function, a Kubernetes service account, and now AI coding agents. They vastly outnumber human identities in a modern cloud estate, and they share a dangerous property — they almost always run on standing credentials.
The reasons are structural. A pipeline needs to deploy at 3 AM when no human is awake to approve anything, so it holds a permanent credential. A service account authenticates workloads that run continuously, so its key never expires. These credentials are provisioned once, early, often broadly (“just give it the access it needs and we’ll tighten it later”), and then they are forgotten. Nobody reviews them in the quarterly access review because the access review is implicitly about people. The result is a large population of powerful, permanent, unreviewed credentials that no governance process touches.
Why CI/CD Is the Worst Place for Standing Secrets
Among non-human identities, the CI/CD pipeline is the most dangerous place to leave standing credentials, for three compounding reasons.
It Runs Untrusted Code by Design
A build server exists to execute code from every branch and every pull request. That is its job. Which means it executes code that has not been reviewed, from contributors who may not be fully trusted, including — increasingly — code suggested by AI agents. If that pipeline holds broad cloud credentials, then anyone who can open a pull request has a path to exercising those credentials. A malicious or compromised PR does not need to breach your cloud; it just needs to run inside your build.
Its Permissions Accumulate and Never Shrink
Pipeline permissions grow the way all pipeline permissions grow: the first job needed to push an artifact, so storage write was added; the next needed to update a service, so that was added; by the fifteenth pipeline the policy was unreadable and someone granted broad admin “temporarily.” The permission set only ever ratchets upward, because removing a permission risks breaking a build, and nobody wants to be the person who broke the deploy. So the pipeline ends up with far more standing access than any single job requires — and holds it permanently, including the overwhelming majority of the time when no build is running at all.
Its Credentials Leak Easily
CI/CD credentials end up in environment variables, in pipeline configuration, in build logs, in cached layers, and sometimes — because the pipeline is defined as code in the same repository it builds — committed to the source control system itself. A pipeline credential is one of the most leak-prone secrets in the whole estate, and when it leaks, it leaks with whatever broad standing permissions it accumulated. For a team using GitHub for source and Jenkins for builds, the secret that deploys to production can be one misconfigured log line or one over-shared repository away from exposure.
Put together: the most exposed execution environment holds the most over-privileged, most leak-prone, most permanent credentials in your cloud. That is why, once human access is under control, CI/CD non-human identity is usually the next-largest risk on the board.
The Fix: Elevation for the Window That Needs It, Nothing the Rest of the Time
The principle that fixed human standing access fixes machine standing access too: access should exist only during the bounded window it is actually needed, and vanish afterward. For a pipeline, that window is the deploy step — a few seconds or minutes out of a day — not the 24 hours a day the credential currently sits available.
Agentic JIT applies the request → elevate → auto-revoke lifecycle to non-human identities:
- Register the identity once. The pipeline, build agent, or service is registered as a known non-human principal with a defined baseline of what it may request.
- It runs with minimal or no standing privilege. Between builds, the identity holds little or nothing. There is no permanent broad credential sitting idle for an attacker to find.
- It elevates for the step that needs it. When the deploy step runs, an SDK or CI-library call requests exactly the scoped access that step requires — deploy to this service, push to this registry — for the few seconds it takes.
- Access auto-revokes immediately. The moment the step completes, the elevation is gone. There is no window after the deploy where the credential lingers.
- Every elevation is logged and attributed. The audit trail records which pipeline, which run, which step, which permissions, and ties it back to the commit and the change that triggered it.
The effect is that the standing, broad, permanent credential — the thing that made the pipeline such a large blast radius — simply stops existing. The pipeline still deploys exactly as before. What changes is that for the 23 hours and 59 minutes a day it is not deploying, it has nothing worth stealing.
Across GCP, Azure, and AWS — and the AI Agents Too
A multi-cloud team cannot solve this one cloud at a time. A FinTech running primarily on GCP with an Azure footprint, deploying through Jenkins to both, needs the pipeline’s elevation to work the same way regardless of which cloud the deploy targets. Agentic JIT runs the same lifecycle across GCP, Azure, and AWS, so there is one model for pipeline elevation rather than a different standing-credential problem per cloud.
The same mechanism extends to the newest and least-governed non-human identities: AI coding agents. Tools like Claude Code, Cursor, and Kiro increasingly act inside developer and CI workflows, and they default to holding whatever credentials the environment hands them. Coding Agent JIT mints, scopes, and destroys credentials for these agents with a human in the loop — so the agent gets seconds-level access to do its task and nothing afterward, rather than inheriting a standing secret. For a team adopting AI coding tools (a matter of when, not if), getting non-human identity governance in place now means the agents arrive into a governed environment rather than becoming the next unmanaged blast radius.
What This Looks Like in Practice
The adoption path for a team with an over-privileged Jenkins setup is incremental, not a rebuild:
- Inventory the standing credentials. Identify what the pipeline role actually holds versus what any single job needs. The gap is usually large and surprising.
- Register the pipeline as a non-human identity and define the scoped permissions each step legitimately requires.
- Insert elevation at the steps that need it via the SDK or CI library, so the deploy step requests scoped access just-in-time instead of relying on the standing role.
- Strip the standing credential down to minimal or nothing once elevation is in place. The broad permanent grant that was the whole problem is removed.
- Extend to the other clouds and to AI agents so the governance model is uniform across every non-human principal, not just the first pipeline you fixed.
Because the pipeline keeps deploying through the same steps and the same tools, there is no disruption to developer workflow — the change is beneath the surface, in how the credential is obtained and how long it lasts.
Why Secret Vaults and Short-Lived Tokens Aren’t the Whole Answer
A reasonable objection at this point is: “we already use a secrets manager, and our pipeline fetches credentials at runtime instead of hardcoding them — isn’t that solved?” Secret managers are genuinely good and worth using, but they solve a different problem than the one described here. A vault governs where the credential is stored and how it is retrieved. It does not govern whether the credential should exist at all between builds, or how broad it is, or whether anyone reviews it.
Consider what a vault-based setup still leaves open. The credential in the vault is typically long-lived — the vault secures its storage, but the secret itself is a standing, broad grant that happens to live behind an API. When the pipeline fetches it, the credential is now in the build environment’s memory, its environment variables, and potentially its logs, with the same broad permissions it always had. A compromised build step reads it straight out of the vault using the pipeline’s own vault access. The vault moved the credential; it did not reduce the credential’s power or its lifetime once retrieved.
Short-lived tokens — OIDC federation from the CI system into the cloud, for example — are a real improvement and closer to the right idea, because the token the pipeline receives expires. But in common configurations the role that token assumes is still broad and standing, so the pipeline gets a short-lived credential to a long-lived, over-privileged role. The lifetime problem is addressed; the scope problem is not. The deploy step can still do far more than it needs, and a compromised step can do all of it during the token’s validity window.
Agentic JIT is complementary to both: use the vault for storage and OIDC for federation if you have them, but add the elevation layer that ensures the permissions themselves are scoped to the step and granted only for its window. The combination is what gets you to a pipeline that holds minimal standing power, obtains exactly what each step needs when it needs it, and gives it all back immediately — rather than a well-stored, well-federated path to a role that is still too powerful for too long.
The Audit and Compliance Angle
There is a compliance dimension to this that often goes unstated. SOC 2 and ISO 27001 access-control requirements do not distinguish between human and non-human principals — they ask that privileged access be restricted, justified, and reviewable, full stop. An auditor who is paying attention will ask not only “who are your privileged users?” but “what service accounts and pipelines have privileged access to production, and how is that governed?” For most teams, the honest answer about the Jenkins role is uncomfortable: it has broad standing access, nobody reviews it, and there is no record of what it did tied to a specific change.
Agentic JIT turns that uncomfortable answer into a defensible one. Because every elevation is scoped, time-boxed, and logged against the pipeline run and the triggering commit, the evidence for “how is privileged pipeline access governed?” becomes the same kind of ledger that JIT produces for human access: here is every elevation, what it was scoped to, how long it lasted, and which change justified it. The non-human identities move from being the ungoverned exception in the audit to being covered by the same access-governance story as everyone else — which is exactly the direction frameworks are pushing as service accounts and automation become a larger share of what actually touches production.
The Takeaways
- Non-human identities are the forgotten standing-access problem. Pipelines, service accounts, and AI agents hold permanent credentials that human-focused access reviews never touch.
- CI/CD is the worst place for standing secrets because it runs untrusted code, accumulates permissions that never shrink, and leaks credentials easily.
- The blast radius is real: the most exposed execution environment holds the most over-privileged, most permanent credentials in the estate.
- Agentic JIT elevates for the deploy window and auto-revokes — so the standing broad credential stops existing, while the pipeline deploys exactly as before.
- It has to span every cloud and every non-human principal, including AI coding agents, or the risk just relocates to whatever you did not cover.
If your humans are governed but your Jenkins server still holds permanent broad cloud credentials, you have moved the largest blast radius in your environment, not removed it. The durable fix is to make the pipeline’s power exist only in the seconds it is deploying.
Book a Free Assessment to see agentic JIT replacing standing pipeline credentials across GCP, Azure, and AWS.
Related Resources
- Build JIT: Securing Jenkins CI/CD Pipelines with Just-in-Time Access
- Understanding Non-Human Identities
- Why AI Coding Agents Become an Identity and Credential Risk
- JIT for Jenkins Pipelines and Non-Human Identities
- What is a CI/CD Pipeline?
- What is Zero Standing Privilege?
- Securing AI Coding Agents at Scale for Enterprise Development Teams