Join our Newsletter — 33% off our NHI Course
Home› Guides› OWASP CI/CD Top 10 CICD-SEC-5 Insufficient PBAC Guide:…
Guide Software & AI Supply Chain

OWASP CI/CD Top 10 CICD-SEC-5 Insufficient PBAC Guide: Least Privilege for Pipeline Execution

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 26 October 2026 13 min read
On this page

When a pipeline step can reach more secrets, hosts and networks than its task needs, any code that runs in that step inherits all of it. OWASP lists this as CICD-SEC-5 Insufficient PBAC (Pipeline-Based Access Controls) in the Top 10 CI/CD Security Risks. PBAC decides how much damage follows a poisoned build, a malicious dependency or a compromised third-party action. This guide covers what PBAC means in practice, how to scope secrets, runners, host permissions and network egress per pipeline and per step, how to assess and measure it, and how it maps to NIST, CIS, ISO and MITRE frameworks. It is for platform engineers, DevSecOps teams and owners of CI/CD service identities, and goes deeper than the Top 10 CI/CD Security Risks overview.

Key takeaways

  • PBAC is about blast radius. OWASP states that the damage from malicious code in a pipeline "is determined by the granularity of the PBAC in the environment".
  • Three areas of control. Access within the execution environment (code, secrets, variables, other pipelines), permissions on the underlying host and other nodes, and ingress and egress filtering to the internet.
  • Scope to the step, not just the pipeline. A dependency install script, a test run and a deployment step need very different access, and OWASP calls for a separate context for package installation scripts.
  • Nodes must not carry state or mix trust levels. Revert execution nodes to a pristine state after every run and never share nodes between pipelines of different sensitivity.
  • Every pipeline is a non-human identity. Tokens, federated cloud roles and runner host credentials should each be scoped to one pipeline, one environment and one purpose.

What it is and who it applies to

OWASP's definition starts from the execution node: pipeline execution nodes have access to numerous resources inside and outside the execution environment, and when malicious code runs in a pipeline, adversaries use insufficient PBAC to abuse the pipeline's permissions and move laterally within or outside the CI/CD system. OWASP describes PBAC as the context in which each pipeline, and each step within it, runs, and says each should be limited to the exact data and resources it needs.

CICD-SEC-5 is the consequence half of an attack. Code gets into the pipeline through OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide scenarios, through OWASP CI/CD Top 10 CICD-SEC-3 Dependency Chain Abuse Guide scenarios, or through a compromised third-party action or tool; PBAC decides what that code can then reach. It applies to:

  • Anyone running self-hosted runners or agents: persistent hosts, shared Docker sockets and instance roles are the most common PBAC gaps.
  • Organisations with shared CI platforms: one Jenkins controller or runner fleet serving many teams lets one team's compromise reach another team's secrets.
  • Teams that deploy from CI: deployment credentials turn a build compromise into a production compromise.
  • Users of hosted CI services: the provider isolates jobs from each other, but the secrets, tokens and network paths you grant a job remain your responsibility.

Structure and key requirements

The OWASP entry lists what nodes typically do (access and build source code; obtain secrets from environment variables, vaults and cloud identity services such as the AWS metadata service; create, modify and deploy artefacts), the impact, and eight recommendations. The table groups the recommendations by control area.

Control areaOWASP recommendationPractical implementation
Node sharingDo not use a shared node for pipelines with different sensitivity or resource needsRunner groups or labelled agent pools per trust tier (public, internal build, release, production deploy)
Secret scopingEach pipeline and step gets only the secrets it requiresEnvironment-scoped secrets, protected variables, per-job vault roles, short-lived federated tokens
Node hygieneRevert the execution node to a pristine state after each runEphemeral or just-in-time runners, rebuilt containers or VMs per job
Host permissionsLeast-privilege OS user for the jobNon-root runner user, no sudo, no mounted Docker socket, rootless or VM-isolated container builds
Controller separationLimited job permissions on the controller; run jobs on dedicated nodesJenkins built-in node executors set to 0; Agent to Controller Access Control kept on
PatchingKeep execution nodes patchedRebuild runner images on a schedule; track runner agent versions
NetworkSegment so the node reaches only what it needs; avoid unlimited internet accessEgress allowlists, package proxy, blocked metadata endpoints, separate deploy network path
Install scriptsSeparate context for package installation scripts with no access to secretsInstall dependencies in a job without secrets, pass the result as an artefact; disable lifecycle scripts where possible

The OWASP impact statement is broad: malicious code in a pipeline node has the full permissions of the stage it runs in, can access secrets and the host, connect to any system the pipeline can reach, expose confidential data, move laterally beyond the CI environment, and deploy malicious artefacts down the pipeline, including to production.

Identity and NHI requirements

PBAC is least privilege applied to non-human identities. Each credential a pipeline holds should answer four questions: which pipeline, which step, which environment, how long.

IdentityOver-privileged patternScoped pattern
Job token (GitHub GITHUB_TOKEN, GitLab CI_JOB_TOKEN)Write access to contents, packages and pull requests for every jobWorkflow default permissions read-only; per-job grants such as contents: write only in the release job
Cloud accessStatic access keys in a CI variable with an admin role shared by all pipelinesOIDC federation with trust pinned to repo:ORG/REPO:environment:Production or a specific job_workflow_ref; separate roles for plan and apply
Runner host roleInstance profile on a self-hosted runner that every job can read through the metadata serviceNo instance role, or a minimal one, with job containers blocked from the metadata endpoint
Registry and publishing credentialsOne long-lived token reused across projects and available to test jobsTrusted publishing or per-project tokens available only to the release environment
Vault accessOne CI role that can read every pathPer-pipeline roles bound to job identity claims, limited to that pipeline's paths
Cross-pipeline accessJobs can trigger or read artefacts and caches of other pipelinesJob token allowlists, restricted cache scope, artefacts treated as untrusted input

GitHub documents that OIDC subject claims can include the environment name, and that cloud trust configuration accepts the exact subject string, for example in an AWS condition on token.actions.githubusercontent.com:sub. Trust policies written against a whole organisation or any branch defeat PBAC because any workflow can then assume the role. See the Workload Identity Federation Guide, the Secrets Management Guide and the CI/CD Pipeline Identity Security Guide. Credential storage and rotation are covered by the OWASP CI/CD Top 10 CICD-SEC-6 Insufficient Credential Hygiene Guide.

Implementation steps

  1. Map reachability (weeks 1 to 3). For each pipeline record its runners, the secrets and variables each job reads, its cloud roles and their trust policies, vault roles, host permissions, and the network destinations it actually contacts. Egress logs from a few weeks of normal runs give you the allowlist baseline.
  2. Define trust tiers. A workable model is four tiers: untrusted (fork and pull request builds), internal build and test, release and signing, and production deployment. Each tier gets its own runner group or agent pool, and higher tiers never run lower-tier jobs.
  3. Move secrets to the narrowest scope. Convert repository-wide secrets to environment secrets with required reviewers (GitHub) or protected variables tied to protected branches (GitLab). Bind vault and cloud roles to pipeline identity claims. Remove secrets from any job that does not use them.
  4. Split risky steps into separate jobs. Run dependency installation and tests in a job that has no secrets, publish the build output as an artefact, and let a separate job with credentials consume it. GitHub's guidance notes that jobs in the same workflow can interfere with each other through shared directories, environment variables or the Docker socket, so separation at job level is not a formality.
  5. Make nodes ephemeral. Replace persistent self-hosted runners with just-in-time or autoscaled ephemeral runners that run one job and are destroyed. GitHub notes that self-hosted runners have no guarantee of a clean environment and can be persistently compromised by untrusted workflow code.
  6. Harden the host. Run the job as a non-root user, remove sudo, do not mount the Docker socket into job containers, keep runner images patched, and on Jenkins set built-in node executors to 0 so no build runs with controller file system access.
  7. Restrict the network. Default-deny egress from runners, allow the package proxy, SCM, artefact registry and named deployment endpoints, and block cloud metadata endpoints from job workloads. Put production deployment paths on a separate network segment reachable only from the deploy tier. See the Network Segmentation Guide.
  8. Enforce and review. Encode tiers in organisation policy (runner group access lists, rulesets, reusable workflows) and review role trust policies quarterly like firewall rules.

Testing: start network controls in log-only mode and compare blocked destinations with the baseline before enforcing; pilot ephemeral runners on one team's pipelines; run a canary job in each tier that tries to read secrets, the metadata endpoint and an unapproved host, and confirm each attempt fails. Rollback: keep the previous runner pool registered but disabled during migration, and manage egress rules and trust policies as code so a change can be reverted by commit.

Decision guidance

ChoiceOption AOption BWhen to choose which
Runner modelPlatform-hosted ephemeral runnersSelf-hosted ephemeral runnersHosted for public repositories and small teams; self-hosted only when private network access or special hardware is needed, and then ephemeral
Secret deliveryCI-stored secrets scoped to environmentsFederated identity and vault roles per jobFederation wherever the target supports OIDC; stored secrets only for targets that do not, with environment scoping
Egress controlNetwork allowlist at the runner subnetPer-job proxy with policySubnet allowlist is enough for most; per-job policy for release and deploy tiers in large organisations
Organisation sizeSmall: hosted runners, read-only token default, environment secretsLarge: tiered runner groups, central reusable workflows, egress policy, trust policy reviewsEffort should follow the value of what the pipeline can deploy or sign

Evidence and assessment

An assessor should be able to pick any pipeline and see exactly what one of its steps could reach. Ask for:

  • Reachability map: per pipeline, the secrets, roles, runners and network destinations, with the owner of each.
  • Runner configuration: runner group or agent pool access lists, ephemeral settings, image build dates, OS user and Docker socket configuration.
  • Trust policies: cloud role trust documents for CI federation showing subject conditions.
  • Network policy: egress rules for runner subnets and metadata endpoint blocking.
  • Canary results: recent output of tier tests proving a low-tier job cannot reach high-tier secrets.

Detection and metrics

Monitor runner egress to destinations outside the allowlist, metadata endpoint requests from job workloads, cloud API calls by CI roles outside their expected actions or from unexpected repositories, secret reads from vault paths a pipeline does not normally use, and new registrations of self-hosted runners. Correlate CI audit logs with cloud and vault logs so a credential used outside a pipeline run stands out.

MetricTarget
Jobs with access to secrets they never useZero, measured from secret references versus usage
Self-hosted runners that are persistent or shared across trust tiersZero
CI federation trust policies without repository and environment or branch conditionsZero
Runner subnets with unrestricted internet egressZero for release and deploy tiers
Workflows with read-only default token permissions100 percent
Runner image ageWithin patch SLA, for example under 30 days

Mapping to other frameworks

FrameworkItemRelevance to PBAC
NIST SP 800-53 Rev. 5AC-6 Least Privilege; AC-6(9) Log Use of Privileged FunctionsMinimal permissions per pipeline and step; logging privileged use
NIST SP 800-53 Rev. 5AC-4 Information Flow Enforcement; SC-7 Boundary ProtectionEgress filtering and segmentation of runners
NIST SP 800-53 Rev. 5SC-39 Process Isolation; CM-7 Least FunctionalityEphemeral, separated nodes with minimal software and privileges
NIST CSF 2.0PR.AA-05; PR.IR-01; PR.PS-01Least-privilege permissions; protecting environments from unauthorised access; configuration management
CIS Controls v8.1Control 6 Access Control Management; Control 12 Network Infrastructure Management; Control 16 Application Software SecurityScoped access, network segmentation, secure build infrastructure
ISO/IEC 27001:2022 Annex AA.8.2 Privileged access rights; A.8.22 Segregation of networks; A.8.31 Separation of development, test and production environmentsRestricted pipeline privileges, segmented runner networks, separated deploy tier
MITRE ATT&CK v20T1552.001 Credentials In Files; T1552.005 Cloud Instance Metadata API; T1528 Steal Application Access Token; T1078.004 Cloud AccountsCredential theft from nodes and use of pipeline cloud identities
MITRE D3FENDD3-EI Execution Isolation; D3-NI Network Isolation; D3-OTF Outbound Traffic FilteringIsolated jobs, segmented networks, restricted egress

Common pitfalls

  • Every job sees every secret. In the Codecov breach, a modified uploader script sent the output of env from customers' CI jobs to an attacker server, exposing whatever tokens and keys those jobs carried. A coverage upload job that held no unrelated secrets would have exposed far less.
  • Relying on the platform to separate trust. Travis CI CVE-2021-41077 exposed public projects' secrets to forked pull request builds; secrets scoped to release environments would not have been present in those builds.
  • Shared caches and state across privilege levels. In the Ultralytics PyPI compromise, code run by a pull request workflow is believed to have poisoned the Actions cache later restored by the release build, and a leftover PyPI token was then used to publish further malicious versions.
  • Organisation-wide cloud trust. An OIDC trust policy accepting any repository in the organisation lets an unrelated, low-trust workflow assume a production role.
  • Docker socket and root on the runner. OWASP cites a Teleport CI finding where a pull request could run a privileged container and escalate to root on the node, leading to secret exfiltration and release of malicious artefacts.
  • Open internet egress. Unrestricted outbound access makes exfiltration a single request and lets build steps fetch unvetted code. The CI/CD Pipeline Compromise Playbook covers response when a node is compromised.

Practitioner checklist

  • Map, per pipeline and step, the secrets, roles, hosts and network destinations it can reach.
  • Define trust tiers and give each its own runner group or agent pool.
  • Scope secrets to environments or protected branches and remove unused secret references.
  • Run dependency installation and tests in jobs without secrets.
  • Replace persistent runners with ephemeral or just-in-time runners.
  • Run jobs as non-root without the Docker socket; set Jenkins built-in node executors to 0.
  • Default-deny runner egress and block metadata endpoints from job workloads.
  • Pin every CI federation trust policy to repository plus environment or branch claims.
  • Set default job token permissions to read-only.
  • Run tier canary tests after every runner or policy change.

Standards and references

Related NHI Mgmt Group resources: Top 10 CI/CD Security Risks · OWASP CI/CD Top 10 CICD-SEC-4 Poisoned Pipeline Execution Guide · CI/CD Pipeline Identity Security Guide · GitHub and GitHub Actions Security Guide · Workload Identity Federation Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 26 October 2026. Spotted an error? Use our contact page.
NHI Mgmt Group — the #1 independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org