TL;DR: A Buildkite pipeline pattern uploads policy files to Cerbos Hub on main-branch changes using environment-stored client credentials and a Docker-based agent step, according to Cerbos. The governance issue is not the upload itself, but the standing trust and secret handling assumptions embedded in pipeline execution.
At a glance
What this is: This is a CI/CD deployment pattern for pushing Cerbos policies from Buildkite to Cerbos Hub, and its key issue is that the setup relies on environment-held secrets and agent trust rather than short-lived, tightly scoped pipeline identity.
Why it matters: It matters because IAM, NHI, and platform teams need to treat build agents as identity-bearing execution points, where secret storage, branch gating, and upload scope determine whether policy deployment is controlled or exposed.
Context
This article is about CI/CD identity governance in Buildkite, where a pipeline step uploads Cerbos policies to Cerbos Hub when changes land on the main branch. The security question is not whether automation exists, but whether the agent, environment variables, and repository-mounted execution model create a durable secret exposure surface.
CI/CD pipelines often blur the line between build automation and privileged access. When a pipeline depends on agent-side environment secrets and a Docker invocation that inherits those values, the control problem shifts to secret handling, branch trust, and the scope of what the pipeline is allowed to change.
For IAM teams, this is a lifecycle issue as much as a delivery issue: the credentials, agent host, and repository controls all have to stay aligned. The article describes a common operational pattern rather than an unusual exception, which is why it is useful as a governance example.
Key questions
Q: What breaks when CI/CD policy uploads rely on agent-stored secrets?
A: The main failure is that the build agent becomes a standing secret boundary, so any compromise, reuse, or leakage on that host can expose the credentials that authorize policy uploads. That turns a routine pipeline into a privileged identity endpoint, which increases the blast radius of misconfiguration and weak host hygiene.
Q: Why do environment-stored pipeline credentials increase governance risk?
A: Because they extend the lifetime and reach of the credential beyond the single job that needs it. A secret stored in a host environment file can be copied, inherited by child processes, or left in place long after the pipeline event has finished, which weakens accountability and revocation.
Q: How should teams separate policy deployment from ordinary CI builds?
A: Treat policy deployment as a privileged path with its own authorization boundary, not as a side effect of a normal build. That usually means isolating the upload step, narrowing who can change the pipeline definition, and ensuring read-only builds cannot mutate policy state.
Q: What is the difference between container isolation and credential isolation in CI?
A: Container isolation limits the process environment, but credential isolation governs whether the job ever receives authority in the first place. A short-lived container can still execute with durable host-held secrets, so runtime isolation does not remove the need for strict secret issuance and scope control.
Technical breakdown
How Buildkite agent secrets are exposed to pipeline steps
Buildkite agents commonly source secrets from the host environment, which means the credential boundary lives on the machine running the agent rather than inside the pipeline definition itself. In this pattern, the pipeline step shells out to Docker and passes environment variables through to the container, so the container inherits the agent’s trust context. That is convenient for automation, but it also means secret exposure can happen through host configuration, process inspection, logs, or reuse of the same agent for multiple jobs.
Practical implication: Treat the agent host as a privileged secret boundary and reduce the number of credentials that exist there in the first place.
Why main-branch policy uploads create standing trust
A main-branch trigger makes the upload path feel controlled, but the actual authority rests with a client ID and client secret that are present before the job starts. That is standing privilege in CI/CD form: the pipeline does not ask for access at the moment of change, it already has it. The result is a trust model that assumes the repository, branch protection, and agent environment are all trustworthy at execution time, which is a much larger assumption set than the upload step alone suggests.
Practical implication: Map every policy-upload job to the minimum authority it needs and remove broad write access from default build execution paths.
What Docker adds to the policy upload chain
Using Docker as the execution wrapper isolates the toolchain only partially. The container can still read mounted repository content and inherited environment values, which means the security model depends on how the agent launches the container, what it mounts, and whether sensitive values are filtered before the process starts. In practice, this is a composition problem: CI/CD job security, container runtime controls, and secret management all have to work together, or the weakest layer defines the exposure window.
Practical implication: Review container launch patterns in CI/CD as part of identity governance, not as a separate platform-only concern.
Breaches seen in the wild
- CI/CD pipeline exploitation case study: Credentials in an exposed .git/config let a researcher edit a Bitbucket pipeline so it planted their SSH key on the server. No victim was named.
- 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 our 52 NHI Breaches Analysis report for a comprehensive view of breaches impacting Non-Human Identities including AI Agents.
NHI Mgmt Group analysis
CI/CD policy uploads are really identity events, not just deployment steps. The upload is only safe if the build identity, the host identity, and the policy store authority are all narrowly defined. Once client credentials live on the agent machine, the control plane moves out of the repository and into a broader machine trust boundary. The practitioner conclusion is that policy delivery must be governed like any other privileged non-human identity.
Standing credentials on build agents create secret handling debt. This article shows the familiar gap between where teams want the secret to live and where it actually ends up living. A system-wide environment file is operationally simple, but it also extends the credential’s lifetime and increases the number of places it can be exposed. The conclusion is that CI/CD secret placement should be treated as a lifecycle decision, not a convenience choice.
Build pipelines can silently overgrant write authority to routine automation. The instruction to use Read & Write credentials for policy uploads is functionally a privilege decision, not a documentation detail. That means access scope has to be justified for the exact job, not inherited from the broader platform role. The practitioner conclusion is that pipeline write paths should be separated from read-only build paths wherever possible.
Buildkite-style uploads illustrate an identity blast radius problem. The same agent that reads repository content, receives secrets from the host, and invokes a container becomes the pivot point for policy changes. If any one layer is overexposed, the blast radius includes both the policy store and the repository-linked execution path. The conclusion is that build-agent privilege, secret storage, and artifact mutability need to be governed together.
Ephemeral execution does not automatically mean ephemeral trust. Even when the policy upload happens inside a short-lived container, the credentials supporting it are still standing on the host unless they are issued and revoked per job. The control assumption is that runtime isolation alone is enough; this article shows that assumption is incomplete. The conclusion is to separate container ephemerality from credential ephemerality when reviewing CI/CD identity design.
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.
- Read next: Guide to the Secret Sprawl Challenge
What this signals
Identity blast radius: CI/CD pipelines that upload policy or configuration content should be reviewed as identity-bearing systems, because the host, container, and repository can all become implicit trust anchors. When those anchors share the same credentials, compromise of one layer can reach policy state and adjacent automation paths.
The stronger control question is not whether Buildkite can run the job, but whether the job should hold a reusable secret at all. For many teams, the right design pressure is toward narrower issuance, tighter branch protection, and explicit separation between read-only delivery and write-capable governance actions.
For practitioners
- Separate build and write paths Keep routine CI jobs read-only and reserve policy-upload authority for a narrowly scoped pipeline or approval path that is isolated from general build execution.
- Move secrets off the agent host Avoid placing long-lived client credentials in system-wide environment files on Buildkite agents, and prefer tighter secret injection patterns with shorter exposure windows.
- Scope credentials to the upload job Use credentials that only permit the exact Cerbos Hub store operation required for policy replacement, rather than broad reusable write access across jobs.
- Harden repository-triggered policy changes Require branch protection and change control for any pipeline step that can modify policy state, so a main-branch push does not become an unchecked governance shortcut.
- Audit container inheritance in CI Review what the Docker step inherits from the agent process, including environment variables, mounted paths, and any values that could leak into logs or child processes.
Key takeaways
- This pattern exposes the familiar CI/CD weakness where convenience-driven secret placement creates a privileged host boundary.
- The article shows that policy uploads depend on standing credentials, Docker inheritance, and branch-triggered automation rather than on ephemeral, job-scoped authority.
- Teams should separate policy mutation from general builds, reduce host-held secrets, and treat build agents as part of identity governance.
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, NIST CSF 2.0 and CIS Controls v8 set the governance and control requirements practitioners need to meet.
| Framework | Control / Reference | Relevance |
|---|---|---|
| OWASP Non-Human Identity Top 10 | NHI-02 — Secret Leakage | Agent environment secrets are the central exposure point in this CI/CD pattern. |
| NHI-05 — Overprivileged NHI | The upload step uses write authority that should be tightly scoped to the exact task. | |
| NHI-07 — Long-Lived Secrets | The article relies on reusable client credentials rather than job-scoped authority. | |
| Recommendation — Remove long-lived secrets from agent hosts and monitor CI paths for secret leakage. Limit pipeline credentials to the narrowest write scope needed for policy upload. Replace durable client secrets with shorter-lived issuance wherever the workflow allows. | ||
| NIST SP 800-53 Rev 5 | IA-5 — Authenticator Management | CI client secrets are authenticators whose lifecycle and protection need explicit control. |
| Recommendation — Apply authenticator lifecycle controls to CI secrets and revoke them when no longer needed. | ||
| NIST CSF 2.0 | PR.AA-05 — Access Permissions, Entitlements and Authorizations | The pipeline’s write path depends on permission scope and authorization boundaries. |
| Recommendation — Review CI entitlements so build jobs only have the authorizations they actually require. | ||
| CIS Controls v8 | CIS-5 — Account Management | The article is fundamentally about how machine accounts and secrets are managed across the CI path. |
| Recommendation — Inventory and retire unused CI accounts and credentials before they become stale access paths. | ||
Key terms
- Build Agent Secret Boundary: The machine or runtime boundary where a CI agent holds credentials that authorize downstream automation. In practice, this is a high-trust non-human identity zone because any process inheriting those secrets can act with the agent’s authority.
- 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.
- Pipeline Write Scope: The precise set of changes a CI job is allowed to make to repositories, policy stores, or deployment targets. Narrow write scope reduces the chance that routine build automation can mutate security-critical state beyond the intended task.
- Secrets Inheritance: The passing of credentials from a host or parent process into child jobs, containers, or scripts. This is a common CI/CD exposure path because it can make secrets available to more execution layers than the operator intended.
Deepen your knowledge
NHI governance, identity lifecycle management, and secrets management 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 or NHI programme, it is worth exploring.
Published by the NHIMG editorial team on June 11, 2026.
Updated on October 6, 2026.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM, and Agentic AI security. nhimg.org