Ship Fast — but Guard Faster

post thumb
Best Practice
by Christian Schneider / on 24 Jan 2026

Securing DevOps Itself

TL;DR
Your CI/CD pipelines have become high-leverage attack targets—not your application code. This post distills the Break-the-Chain controls from my Real-World DevOps Attacks keynote: replace long-lived credentials with OIDC federation, pin all actions to SHA hashes, sign artifacts with Sigstore, enforce minimal GITHUB_TOKEN permissions, and isolate your build environments.

This blog post is not about scanning your application code for vulnerabilities — that topic has been written about endlessly. Instead, it’s about securing your DevOps itself: your workflows, automation, secrets, registries, and supply chains — the infrastructure attackers increasingly target.

According to GitGuardian’s 2025 State of Secrets Sprawl report, secret-scanning tools detected 23.8 million leaked credentials in public repositories last year — and that’s only what was found. In another incident, a single poisoned workflow compromised 23,000+ repositories in March 2025. And that’s not even counting the Shai-Hulud worm, which spread through the npm ecosystem twice in late 2025. Speed multiplies everything, delivery and disaster.

This post distills the defensive Break‑the‑Chain controls from my Real‑World DevOps Attacks keynote into an actionable field manual. We’ll skip the blow‑by‑blow incident autopsies (watch the keynote to see those) and instead focus on what actually blocks, detects, and contains the next breach.

Four Attack Vectors

Modern CI/CD pipelines present attackers with four primary entry points, each requiring a distinct defensive mindset.

Secrets & Credentials are the most obvious target — long‑lived tokens sitting in environment variables, config files, or workflow logs. Recent breaches have demonstrated how a single compromised secret store can cascade into customer breaches across an entire ecosystem.

Workflow & Action Poisoning exploits the trust we place in automation. Malicious pull requests or hijacked third‑party actions execute attacker code inside your runner with your permissions. The tj‑actions/changed‑files incident showed how one compromised action can harvest secrets from thousands of downstream projects within hours.

Artifact & Registry Tampering targets the outputs of your build process. Unsigned images, poisoned packages, or hijacked release binaries become trojans delivered through your own deployment pipelines. Some attacks on build tooling went undetected for months while quietly exfiltrating credentials from CI environments worldwide.

Dependency & Supply Chain Compromise remains the most insidious vector. Typosquatting, maintainer takeovers, and malicious lifecycle scripts exploit the implicit trust in open‑source ecosystems. The XZ Utils backdoor proved that even heavily‑scrutinized projects can be subverted through patient social engineering.

Let’s examine the Break‑the‑Chain controls for each.

Secrets Hygiene

Secrets are the crown jewels and require layered protection.

SHORT means eliminating long‑lived credentials entirely. The goal is to replace static Personal Access Tokens with OIDC federation wherever possible. GitHub Actions can authenticate directly with AWS, Azure, and GCP using short‑lived, automatically‑rotated tokens that never touch disk. No static keys to leak. No secrets to rotate manually. The authentication happens through cryptographic identity verification rather than shared secrets.

SHRINK addresses the blast radius when credentials do leak. Every secret should have the smallest permission set possible. For the built‑in GITHUB_TOKEN, explicitly declare read‑only defaults at the repository level. Never grant write permissions unless the job demonstrably requires them — and document why.

SEPARATE isolates secret access by environment. Use GitHub Environments to gate production secrets behind approval workflows and branch protections. Staging secrets should never unlock production resources. This separation ensures that compromising a development workflow doesn’t automatically grant access to production infrastructure.

SHIELD means detecting and responding to leaks before attackers can exploit them. Enable secret scanning with push protection — when a secret is detected, the commit is blocked before it reaches the repository. Combine this with automated rotation and comprehensive audit logging so you can trace exactly who accessed what and when.

Workflow Hardening

Workflows are code — treat them with the same rigour you apply to application security.

LOCK addresses the mutability problem. Tags are mutable — a compromised maintainer can retag a malicious release to an existing version number, and every workflow referencing that tag will silently start running attacker code. Always pin actions to the full commit SHA, which is immutable. Use Dependabot or Renovate to automate SHA updates while preserving this immutability guarantee.

LIMIT restricts the power of the GITHUB_TOKEN. Set the repository default to read‑only and require explicit permission elevation per job. This forces developers to think about what permissions each workflow actually needs rather than running everything with maximum privileges.

SCAN means analyzing workflow files for dangerous patterns before they reach production. Flag patterns like pull_request_target combined with actions/checkout of the PR head — this combination allows untrusted code from external contributors to execute with write permissions to your repository.

RESTRICT controls which actions can run at all. Use GitHub’s Actions Policies to allow only actions from verified creators or your organization. Block marketplace actions by default and explicitly allowlist vetted dependencies. This prevents developers from casually adding untrusted automation.

SANDBOX addresses the self‑hosted runner problem. If you use self‑hosted runners, treat them as ephemeral and untrusted. Spin up fresh VMs per job, never persist state between runs, and network‑isolate them from production infrastructure. A compromised runner should never become a pivot point into your internal network.

Artifact Integrity

If you can’t verify it, you can’t trust it. Cryptographic guarantees about your build outputs are essential.

SIGN creates a verifiable chain of custody. Use Sigstore and Cosign to sign container images and binaries. Keyless signing with OIDC identity ties signatures to your CI/CD workflow identity rather than long‑lived signing keys that could be stolen. The signature proves who built the artifact.

ATTEST proves where and how an artifact was built. SLSA (Supply‑chain Levels for Software Artifacts) attestations capture the build environment, inputs, and process. GitHub Actions can generate SLSA Level 3 attestations automatically, providing tamper‑evident provenance that auditors and downstream consumers can verify.

VERIFY closes the loop by enforcing signature checks before deployment. Configure your container runtime to reject unsigned images. In Kubernetes, use admission controllers like Sigstore Policy Controller or Kyverno to block any image that lacks valid signatures or attestations from reaching your clusters.

REPRODUCE provides the ultimate defense: reproducible builds allow independent verification that source code produces a specific binary. If anyone can rebuild your artifact from source and get bit‑for‑bit identical output, you’ve eliminated single points of compromise in your build infrastructure.

Dependency Security

Your dependencies are your attack surface. The npm ecosystem learned this painfully in November 2025 when the Shai‑Hulud 2.0 worm — dubbed “The Second Coming” — compromised 796 npm packages totalling over 20 million weekly downloads. The self‑replicating malware hijacked maintainer accounts from widely‑used projects, then used npm’s preinstall lifecycle hooks to execute before installation even completed. It harvested credentials from local filesystems and cloud environments, exfiltrating them to attacker‑controlled repositories. The attack included a “dead man’s switch” that threatened to wipe user home directories if its channels were severed.

A disciplined approach helps contain such attacks.

MIRROR means pulling dependencies through a private registry like Artifactory, Nexus, or GitHub Packages. This provides caching, auditability, and — critically — a kill‑switch. When an upstream package is compromised, you can block it at your mirror before it reaches any build environment.

LOCK enforces deterministic builds. Commit package-lock.json, go.sum, or requirements.txt with pinned hashes. Reject builds where lockfiles are missing or modified without explicit review. This prevents silent dependency updates that could introduce compromised versions.

SCAN detects malicious patterns before they execute. npm packages can run arbitrary code during preinstall, postinstall, and similar hooks — exactly how Shai‑Hulud spread. Use tools that analyze lifecycle scripts before installation, or disable them entirely in CI with npm ci --ignore-scripts. For rapid incident response scanning, I’ve open‑sourced quick‑npm‑module‑scanner, a lightweight tool that lets you scan for adjustable IoCs when new threats emerge.

ISOLATE segments your build environments. Run dependency installation in isolated, network‑restricted containers. If a malicious package attempts to exfiltrate data, network policies should block egress to anything except your approved registries.

In response to Shai‑Hulud, npm has accelerated its security roadmap. Trusted publishing — which uses OIDC tokens instead of stored credentials — means there’s nothing to steal from developer machines. npm provenance ensures published packages match a trusted workflow origin; if stolen tokens are used outside that path, publish attempts are rejected. In December 2025, npm permanently revoked all classic tokens and replaced them with short‑lived session tokens. These ecosystem‑level changes don’t eliminate risk, but they significantly raise the bar for attackers.

Five Moves This Month

Theory is worthless without action. Here are five concrete improvements you can schedule immediately:

Audit your GITHUB_TOKEN permissions. Review all workflows. Set repository defaults to read‑only. Explicitly declare minimal permissions per job. This single change limits the blast radius of any workflow compromise.

Replace one PAT with OIDC. Pick your most sensitive deployment workflow. Migrate from static credentials to OIDC federation with your cloud provider. Once you’ve done it once, the pattern becomes repeatable.

Pin all actions to SHAs. Replace tag references with commit SHAs across all your workflows. Configure Dependabot to manage updates while maintaining immutability.

Enable secret scanning with push protection. This single setting prevents the most common class of credential leaks before they happen. The friction is minimal; the protection is substantial.

Run a 45‑minute threat huddle. Gather your team. Sketch your CI/CD data flows on a whiteboard. Ask: “Where could an attacker inject code? What would they steal? How would we know?” Document the risks and prioritize mitigations.

Think Like an Attacker

The controls above are reactive — they address known attack patterns. To stay ahead, you need to think like an attacker.

Threat modeling your CI/CD infrastructure reveals blind spots that checklists miss. Map your pipelines end‑to‑end: source control, build triggers, secret stores, artifact registries, deployment targets. For each component, ask what trust boundaries exist, what happens if this component is compromised, and how you would detect it.

If you want help building a threat model tailored to your infrastructure, or need hands‑on guidance implementing these controls, check out my DevSecOps Pipeline consulting and Agile Threat Modeling services.

Closing Thoughts

DevOps velocity is a competitive advantage — but only if your pipelines don’t become the attack vector. The incidents we’ve seen aren’t sophisticated nation‑state operations; they’re opportunistic exploitation of basic hygiene failures.

The good news: the Break‑the‑Chain controls are straightforward. Short‑lived credentials, pinned dependencies, signed artifacts, minimal permissions. None of these require exotic tooling or massive budgets. They require discipline and prioritization.

Ship fast. Guard faster.

Web Security Bootcamp
Join my upcoming two-day online training event:
17. – 18. February 2026 (click here for details)