This installment concludes a three-part series on strengthening Cilium’s CI/CD pipeline. The first entry dealt with access controls, the second with dependency hardening, and now this final piece addresses the remaining concerns: isolating CI from production signing credentials, signing and validating every release, and identifying the security gaps that still need attention.
Securing access credentials
We design under the assumption that any single defense layer could potentially be breached. If a CI pipeline were ever compromised, it’s critical that the attacker gains access to nothing of consequence.
Sensible baseline protections
Out of the box, our GITHUB_TOKENs are restricted to read-only access on contents and packages. Any workflow requiring elevated privileges must explicitly request them, ensuring that a workflow forgetting to declare its permissions won’t inadvertently receive broad write access across the entire organization.
We maintain two separate sets of container registry credentials housed within distinct GitHub protected environments:
- CI credentials are permitted to push images only to our development registry (
quay.io/cilium/*-ci) and are accessible solely to CI builds. Even in a scenario where a CI workflow is compromised, these credentials lack the ability to push to any production image tags. - Production credentials are safeguarded behind the
releaseenvironment, which mandates explicit maintainer authorization before any workflow execution can access them. No fork, feature branch, or CI process has any pathway to those secrets. Only release builds triggered by a tag, and subsequently approved by a maintainer, can reach them.
In the worst case — a full CI breach — an attacker could potentially publish a malicious -ci tagged image. They would be unable to publish anything to quay.io/cilium/cilium:v1.x.x or docker.io/cilium/cilium:v1.x.x. The credentials simply aren’t present on the runner.
Every actions/checkout invocation is also configured with persist-credentials: false, ensuring the GITHUB_TOKEN is never stored in the runner’s git configuration where a subsequent step could retrieve it.
Signing and validating every artifact we distribute
Each container image we publish — including cilium, operator-*, hubble-relay, and clustermesh-apiserver — gets signed via Sigstore Cosign using keyless OIDC authentication. There are no static signing keys that could be compromised.
A reusable composite action orchestrates the entire signing workflow:
.github/actions/cosign/action.yaml- name: Install Cosign
uses: sigstore/cosign-installer@cad07c2e89fa2edd6e2d7bab4c1aa38e53f76003 # v4.1.1
- name: Generate SBOM
uses: anchore/sbom-action@e22c389904149dbc22b58101806040fa8d37a610 # v0.24.0
with:
artifact-name: sbom_${{ inputs.sbom_name }}.spdx.json
output-file: ./sbom_${{ inputs.sbom_name }}.spdx.json
image: ${{ inputs.image_tag }}
- name: Sign Container Image
shell: bash
run: cosign sign -y "${{ inputs.image }}"
- name: Attach SBOM Attestation
shell: bash
run: |
cosign attest -y
--predicate "./sbom_${{ inputs.sbom_name }}.spdx.json"
--type spdxjson
"${{ inputs.image }}"
This process runs for every release image build as well as for our Helm chart OCI artifacts. Instructions for verification are documented in the Cilium project documentation.
Release builds also execute inside designated protected environments (release, release-tool, release-helm), ensuring that production registry credentials are gated by environment protection rules. Triggering a release build from a fork or feature branch is not possible.
The Cilium security team
If you’ve ever submitted a security vulnerability report to the project — whether through GitHub’s security advisories or via security@cilium.org — you’ve already engaged with Cilium’s Security Team. Beyond managing vulnerability reports, the team also manages the operational aspects of supply chain security:
- Regularly auditing and rotating credentials and permissions across the entire GitHub organization.
- When necessary, performing incident investigations and security audits.
- Monitoring trends in our reported security issues alongside broader industry developments in order to propose mitigations and controls where our security posture needs strengthening.
Further safeguards
A couple of smaller but notable items worth calling out:
- Tag immutability. Once a GitHub release has been created, neither the tags nor the assets associated with it can be altered. This is configured through the repository’s Settings → Releases section.
- DCO sign-off enforcement. Every commit is required to include a
Signed-off-byline. Ourmaintainers-little-helperconfiguration automatically applies adont-merge/needs-sign-offlabel to pull requests lacking a valid sign-off, thereby preventing any merge until one is added. - Third-party security audits. We’ve undergone assessments by ADA Logics, and we maintain a publicly accessible threat model.
Remaining work ahead
We conducted an audit of our .github/ directory against current industry best practices (OpenSSF Scorecard, SLSL, and StepSecurity guidance), and uncovered several meaningful gaps. The most significant ones include:
- No SLSA provenance. Every
docker/build-push-actioncall currently hasprovenance: falseset. While we do sign images with Cosign, we don’t generate SLSA build provenance attestations. Consumers can confirm who signed an image, but not the precise process of how it was built. Adoptingslsa-framework/slsa-github-generator(or at minimum enabling BuildKit-native provenance generation) is on our roadmap. - No dependency review at PR time. We rely on Renovate’s
vulnerabilityAlertsfeature to flag dependencies with known vulnerabilities, but this is reactive rather than preventive. Integratingactions/dependency-review-actionwould allow us to catch malicious or vulnerable new dependencies before they get merged into the codebase. - No
govulncheckin CI. We do fuzz testing and run linters, but we haven’t yet incorporated Go’s official vulnerability scanner, which verifies whether our code actually invokes vulnerable functions rather than simply checking whether a vulnerable package appears in go.sum. - 68 internal
@mainreferences. A significant number of conformance and scale-test workflows currently referencecilium/cilium/.github/actions/set-commit-status@main, which is a mutable branch reference. While this carries lower risk than a third-party tag, it conflicts with our SHA-pinning policy. The plan is to migrate all of our composite actions out of thecilium/ciliumrepository into a dedicated one, which would eliminate the need for@mainreferences altogether.
A few other minor findings from the same audit:
- We’re not using an OpenSSF Scorecard workflow to continuously monitor supply chain health.
- Our
SECURITY-INSIGHTS.ymlfile expired in January 2025 and hasn’t been renewed yet. (We actually spotted this while drafting this article.) - We’re missing a
go mod verifystep to check that the vendor directory matches the checksums in go.sum.
If any of these feel like a good starting point, we’d welcome a pull request.
GitHub’s 2026 Actions security roadmap and how it connects to our work
When GitHub published its Actions security roadmap in April 2026, it outlined platform-level improvements across three areas: ecosystem, attack surface, and infrastructure. Reading it felt like confirmation of the very issues we’ve been navigating for years, and a clear sign the platform is finally meeting the needs of large open-source projects. Here’s how those plans align with our current setup.
Dependency locking: putting SHA pinning front and center
We lock every action to a specific SHA and depend on Renate to keep them updated, but we still have a blind spot with transitive references. GitHub’s planned dependencies section in workflow YAML would pin all direct and transitive dependencies by commit SHA, verifying hashes before any execution begins. That would close our gap.
Policy-driven execution: consolidating the rules we currently enforce per file
We limit who can trigger workflows (via Ariane’s allow-list), which events are permitted (through per-workflow settings), and who can approve releases (using protected environments). Right now, these rules are spread across dozens of YAML files and a custom bot, so getting a complete picture means reviewing every single file.
GitHub’s planned workflow execution protections, built on rulesets, would allow us to define all these controls at the organization level: specifying who can trigger workflows, which events are allowed, and which repositories the rules cover. We could ban pull_request_target across the entire organization except for the workflows where we’ve carefully designed a safe two-phase checkout, instead of depending on code reviews and CODEOWNERS to enforce it.
Scoped secrets: fixing the implicit inheritance issue
Separating CI credentials from production credentials is one of our strongest safeguards, but within any given environment, secrets remain broadly accessible: any workflow running in that environment can use them.
Scoped secrets would let us tie credentials to specific workflow paths, branches, or even individual reusable workflows. A release credential, for example, could be restricted not just to the release environment but to the exact release.yaml workflow file, so a new workflow added to that environment—whether by accident or an attacker—wouldn’t automatically gain access to those credentials.
The roadmap also decouples secret management from repository write access. GitHub plans to introduce a dedicated custom role for secret management, which matches the least-privilege principle we already apply to workflow permissions but haven’t yet implemented for secret administration.
Native egress firewall
GitHub’s planned native egress firewall would restrict outbound network traffic from GitHub-hosted runners. Operating at Layer 7 outside the runner VM makes it tamper-proof even if an attacker gains root access inside the runner. Organizations could specify allowed domains, IP ranges, and HTTP methods, with everything else blocked.
This matters less for Cilium than for others. Our most security-sensitive workflows already use credential isolation and least-privilege permissions, which limits what any compromised step could do even with full network access. Creating a precise egress allow-list would require considerable effort. Public preview is expected in 6 to 9 months, so we’ll reassess then.
Actions data stream: bringing observability to CI
Our workflows generate logs, but we lack centralized telemetry. If a workflow starts acting unexpectedly—pulling in unfamiliar dependencies, taking much longer than usual, or making unusual network requests—we’d have to catch it through manual observation.
The Actions Data Stream would stream near real-time execution data to external systems like S3 or Azure Event Hub, covering workflow execution details, dependency resolution patterns, and eventually network activity.
The bigger picture
Supply chain security is fundamentally about repeatedly asking “what if this thing I rely on gets compromised?” and then adding layers that contain the damage when that happens.
We’ve implemented defense in depth: access controls ensuring only trusted individuals can trigger builds, pinned digests so a hijacked tag can’t reach us, least-privilege permissions preventing a rogue action from stealing secrets, credential isolation keeping CI completely separate from production, and signatures so users can verify what they’re running.
None of this makes us invincible. But security through obscurity isn’t real protection, and the flip side is equally true: the more openly source projects share their defenses, the higher the barrier becomes for attackers everywhere. You’ve seen ours, including the parts that need work. If you manage CI/CD for an open-source project and have solved something we haven’t, please open an issue, write about it, or join us on Slack. The open-source supply chain is only as robust as its most vulnerable project, and the only way to strengthen it is together.
André Martins is a Cilium maintainer and Software Engineer at Isovalent, Cisco. Feroz Salam is a member of the Cilium Security Team and a Security Engineer at Isovalent, Cisco. Find Cilium on GitHub and connect with the community on Slack.



