TL;DR: P0 Security shows a GitLab CI/CD pipeline using a GCP service account that starts read-only, fails on a write step, then succeeds after a five-minute just-in-time elevation to storage.objectCreator, illustrating how standing machine privilege turns routine builds into escalation paths. The real issue is persistent access, not pipeline automation.
At a glance
What this is: This demo shows how a GitLab pipeline can move from read-only service account access to time-bound elevation for a single write step, exposing the difference between standing and just-in-time machine privilege.
Why it matters: It matters because CI/CD service accounts often outlive the build step they support, and IAM teams need controls that bound privilege by task, duration, and approval rather than by convenience.
👉 Read P0 Security's video on just-in-time elevation for GitLab service accounts
Context
CI/CD service accounts are non-human identities that often carry more privilege than the build step requires. When those permissions stay in place after the task ends, the pipeline stops being a narrow delivery mechanism and becomes a persistent access path.
The operational problem is not GitLab itself. It is the governance pattern around machine identity access: scope is set for convenience, not for the exact action being performed, and revocation is delayed or manual.
This article shows a concrete example of temporary elevation for a GCP service account inside a GitLab pipeline, which is typical of the broader CI/CD privilege problem rather than an edge case.
Key questions
Q: What breaks when CI/CD service accounts do not use just-in-time access?
A: Standing access turns build automation into a persistent privilege path. The pipeline can keep writing, deploying, or modifying cloud resources long after the task that justified access has finished, which increases blast radius if the account is compromised or misused.
Q: Why do time-bound permissions reduce risk for GitLab pipelines?
A: Time-bound permissions reduce risk because they align access with a single build step instead of with the lifetime of the service account. That narrows the blast radius, improves auditability, and makes revocation automatic when the approved window ends. The control works only if elevation is scoped and expiry is enforced.
Q: How do security teams know when CI/CD access is too broad?
A: CI/CD access is too broad when routine build identities can reach signing, publishing, or repository-modification functions. A strong signal is any pipeline token that can alter artefacts without a separate review step. Teams should verify that routine automation can build software, but cannot independently decide what gets released.
Q: How should teams govern service account elevation in pipelines?
A: Teams should govern elevation as a temporary entitlement with approval, scope, and expiry, not as a permanent role change. The practical test is whether the identity returns to its baseline automatically after the job completes. If not, the programme is still relying on standing privilege with a shorter leash.
Technical breakdown
Why standing service account access becomes CI/CD risk
A service account in a pipeline is a machine identity, not a user, so its privilege should be tied to the smallest possible task. Standing access creates a large blast radius because every build, retry, and maintenance action can reuse the same entitlements. In GitLab and similar CI/CD systems, that often means a token or role can write, deploy, or reconfigure long after the initial job that justified it. The key technical issue is persistence: the credential remains valid across future runs unless governance actively narrows it.
Practical implication: scope CI/CD service accounts to the specific action set each job actually needs.
How just-in-time elevation changes the permission model
Just-in-time elevation moves authorization from provisioning time to execution time. Instead of pre-granting write access, the pipeline begins with read-only rights and requests a temporary privilege increase only when the job reaches the step that needs it. That makes access ephemeral, auditable, and easier to revoke automatically. The model works because the identity remains constrained until a specific build step proves the need for wider access. This is a governance control for non-human identities, not a change to CI/CD logic itself.
Practical implication: require time-bound approval before a pipeline can cross from read-only to write-capable access.
Why automatic reversion matters after the build completes
The security value does not come from elevation alone. It comes from the full lifecycle of that elevated state, including automatic rollback after the approved window expires. If the privilege remains active after the pipeline finishes, the control has failed and the machine identity again becomes overpowered relative to its purpose. Automatic reversion closes the gap between task completion and access removal, which is where many CI/CD governance failures persist. In practice, revocation needs to be part of the control, not a separate cleanup step.
Practical implication: make expiration and revocation part of the access event, not an after-the-fact housekeeping task.
Threat narrative
Attacker objective: The objective is to show how a machine identity can be safely constrained so a pipeline cannot retain write privileges beyond the step that needs them.
- Entry occurs through a GitLab pipeline running with a GCP service account that already has read access and can be elevated for a build step.
- Privilege escalation occurs when the pipeline requests temporary storage.objectCreator permissions to perform the write action.
- Impact is limited to the approved window because the elevated access is removed automatically after the short session ends.
Breaches seen in the wild
- tj-actions/changed-files compromise 2025: A stolen bot token let attackers poison tj-actions/changed-files so pipelines printed their CI/CD secrets to public logs (CVE-2025-30066).
- reviewdog Action compromise 2025: A stolen maintainer token poisoned reviewdog/action-setup, leaking CI secrets including the tj-actions bot token used in the next attack.
Read and download The State of NHI & AI Agent Breach Report 2026, covering 150+ breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
Standing privilege is the real CI/CD governance failure, not automation itself. A GitLab pipeline that can write whenever it runs is not just efficient delivery, it is persistent authority wrapped in automation. The article makes the control boundary clear: if a build step does not need write access from the outset, it should not inherit it. Practitioners should treat standing service account access as the exception, not the default.
Just-in-time elevation turns machine identity access into an event, not a condition. That shift matters because the access decision is made against a specific task, with approval, duration, and rollback attached to the same control. For CI/CD governance, this is the difference between managing a credential estate and managing an access moment. Teams should reframe machine identity governance around issuance and expiry, not around static role assignment.
Ephemeral build privilege is a stronger control pattern than compensating review. Once a service account can be elevated for five minutes and then return to baseline automatically, the programme no longer depends on humans remembering to clean up access. That is a material governance improvement for non-human identities because it reduces both dwell time and administrative drift. Security teams should measure whether pipeline privileges are temporary by design rather than temporary by intention.
CI/CD risk is increasingly a service account lifecycle problem. The article shows that a machine identity can begin read-only, receive short-lived elevated access, and then revert without manual intervention. That lifecycle is more important than the specific pipeline tool, because the same pattern applies across GitLab, GitHub Actions, Jenkins, and cloud roles. Practitioners should align service account governance to the full access lifecycle, not just to deployment events.
From our research library:
- 96% of organisations store secrets outside of secrets managers in vulnerable locations including code, config files, and CI/CD tools, according to the Ultimate Guide to NHIs.
- Only 5.7% of organisations have full visibility into their service accounts, according to the Ultimate Guide to NHIs.
- Read next: Service Account Security Guide
What this signals
Ephemeral credential trust debt: CI/CD programmes accumulate risk whenever temporary build access is easier to grant than to revoke. The longer a service account keeps write authority between jobs, the more the organisation depends on memory and process rather than on enforced expiry.
Pipeline teams should watch for environments where approval exists but reversion is manual or delayed, because that is usually where the governance gap hides. The control objective is not merely to obtain consent for elevation. It is to ensure the identity reverts before the next run can reuse the privilege.
Service account lifecycle control is now a delivery concern, not just an IAM concern: build systems, cloud buckets, and deployment roles are increasingly joined by the same identity pattern. That means the programme has to manage issuance, approval, expiry, and offboarding as one lifecycle across CI/CD and cloud access.
For practitioners
- Define pipeline-specific privilege baselines Map each GitLab job to the minimum role required for read, write, deploy, or artifact operations, and remove any persistent write grant that is not job-specific.
- Require approval before elevation Use a just-in-time request flow so the service account only receives write-capable access when a specific build step needs it and an approver has validated the request.
- Automate expiry and reversion Set elevated permissions to expire automatically at the end of the approved window, and verify the identity returns to its original role without manual cleanup.
- Audit CI/CD roles for write scope Review GitLab, GitHub Actions, and Jenkins service accounts for long-lived write access to buckets, registries, and infrastructure resources that should be task-scoped.
Key takeaways
- GitLab service accounts become materially safer when write access is issued only for the specific build step that needs it.
- The article's example shows how a read-only pipeline can still complete its job once temporary elevation is approved and later revoked.
- For CI/CD governance, automatic expiry is the control that separates just-in-time access from merely shortened standing privilege.
Standards & Framework Alignment
This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.
OWASP Non-Human Identity Top 10 addresses the attack and risk surface, while NIST SP 800-53 Rev 5 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-05 — Overprivileged NHI | The article centres on a GitLab service account that holds more privilege than the job needs. |
| NHI-07 — Long-Lived Secrets | The example depends on access that persists unless time-bound elevation removes it automatically. | |
| Recommendation — Reduce standing roles for pipeline service accounts and scope each identity to the minimum job function. Replace persistent pipeline credentials with time-bound access and enforce automatic expiry. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | Authenticator lifecycle controls are central to temporary elevation and revocation of machine access. |
| AC-6 — Least Privilege | Least privilege is the core control principle behind read-only start states and temporary write access. | |
| Recommendation — Use IA-5 to govern issuance, expiry, and revocation for pipeline authenticators and tokens. Apply AC-6 to ensure CI/CD identities begin with minimal access and elevate only when required. | ||
| NIST CSF 2.0 | PR.AA-05 — Access Permissions, Entitlements and Authorizations | The article is fundamentally about managing entitlements for a machine identity across its access lifecycle. |
| Recommendation — Govern pipeline entitlements so access is granted, limited, and removed according to task scope. | ||
Key terms
- Just-in-Time Access Request: Just-in-Time Access Request is a pattern that grants access only when it is needed and only for the duration required. It reduces standing privilege by making access temporary, policy driven, and task scoped. This approach is especially useful for contractors, sensitive systems, and short-lived operational work.
- Service Account: A special-purpose account used by applications, automated tools, or services rather than a human user to interact with systems, APIs, and infrastructure. Service accounts are a primary category of NHI and one of the most frequently exploited attack vectors.
- Standing Privilege: Standing privilege is access that remains active even when no immediate task requires it. For NHI programmes, it is a common failure mode because long-lived credentials and persistent roles create unnecessary exposure. Reducing standing privilege usually means tighter expiry, on-demand access, and clearer review of who or what still needs access.
- Privilege elevation: Privilege elevation is the process of granting an identity higher permissions for a specific task or time period. In a secure programme, it should be deliberate, bounded, and separately verified so that standard access does not quietly expand into broad administrative control.
What's in the full article
P0 Security's full video covers the operational detail this post intentionally leaves for the source:
- The exact GitLab pipeline sequence from read-only access to failed write and successful rerun.
- The temporary permission change from storage.objectViewer to storage.objectCreator in a GCP service account.
- The approval and expiry flow that automatically removes elevated access after five minutes.
- The live demonstration of how the same pipeline behaves again once access returns to baseline.
Deepen your knowledge
NHI governance, identity lifecycle management, and workload identity security are core topics in our NHI Foundation Level course, the industry's only accredited NHI security programme. If you are building or maturing an IAM programme, it is worth exploring.
Published by the NHIMG editorial team on September 30, 2026.
Updated on October 8, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org