Almost every modern application is assembled by an automated pipeline, and that pipeline can’t do its job without credentials. The credentials might include a key to pull a private dependency, a token to push an image, and a password to run a migration. Credentials are leaked far more often than most teams realize. In 2024 alone, more than 23.7 million new secrets were detected in public GitHub commits, a 25% jump over the prior year (GitGuardian), and stolen credentials show up in roughly 36% of all breaches (Verizon DBIR 2026).
This guide covers what secrets are, where and how they leak across the CI/CD pipeline, why they’re so hard to catch, what an exposed secret puts at risk, and the practices that reduce that risk.
What Are Secrets in Software Development?
A secret is any credential that authenticates or authorizes access to a system: passwords, API keys, OAuth and access tokens, SSH and private keys, TLS and code-signing certificates, database connection strings, and cloud credentials like AWS IAM or Azure AD keys. What matters operationally is that they don’t share a blast radius: a scoped, read-only API token is very different from a code-signing certificate that can poison every downstream consumer. The resulting potential damage demands the cases be handled differently; many scanners treat both cases the same way.
The more important shift is that most secrets no longer belong to people. They authenticate non-human identities (NHIs): services, pipelines, and bots talking to one another, which now outnumber human users by more than an order of magnitude in most environments. NHIs tend to carry long-lived credentials that rarely expire or rotate and often have no clear owner, which is exactly why secrets sprawl is so persistent and why NHI governance has become its own security discipline. These credentials also don’t all look alike to a scanner: a well-formed AWS key has a recognizable shape, but a generic database password or custom internal token does not, and these “generic” secrets now make up the majority of detected leaks while being the hardest to catch automatically.
Why Secrets Leaks Are a Growing Problem in CI/CD Pipelines
Secrets leakage isn’t being slowly solved; it’s worsening, for structural reasons. The number of credentials in circulation keeps climbing, since every new microservice, integration, and automated job needs its own identity. Pipelines are built on third parties: adding a dependency or CI action takes one or two lines of config, and each one runs inside your trusted build with access to its environment (the OWASP Top 10 CI/CD Security Risks project flags this through dependency chain abuse and ungoverned third-party services). Pipelines hold the keys to production by design; privileged, automated, and run with little human review, which makes them an efficient target.
Two newer pressures compound this. AI coding assistants accelerate output and exposure alike, with studies finding AI-assisted repositories leak secrets at higher-than-average rates. And “it’s only in a private repo” doesn’t hold up as roughly a third of scanned private repositories contain at least one plaintext secret, and a misconfiguration or breach can make a private repo public in an instant.
Where Secrets Leaks Commonly Occur in the CI/CD Pipeline
Secrets surface at nearly every stage from commit to deployment:
- Source code and commit history: hardcoded keys, .env files, and config, which live on in Git history even after deletion.
- CI/CD configuration files: workflow YAML and pipeline definitions that reference, or embed, credentials.
- Environment variables: secrets injected at runtime, available to every step and dependency it pulls in.
- Build logs: a stray echo or verbose debug flag can write a live credential into retained, readable output.
- Artifacts and container images: secrets baked into images are a durable attack surface; large-scale scans of public Docker images have uncovered tens of thousands of live cloud keys.
- Collaboration tools: secrets pasted into Slack, Jira, or Confluence, where there are few safeguards.
Teams often assume their existing tooling closes these gaps, but each control sees only a slice. A secrets manager secures storage and injection, yet secrets still leak through manual workarounds, misconfigurations, malicious code insertion, and inconsistent enforcement. Software composition analysis (SCA) flags dependencies with known vulnerabilities or malicious code, but it reasons from manifests and known-bad databases. It can’t catch a trusted dependency that turns malicious at build time, or a script that exfiltrates a secret while the pipeline runs. Both are necessary; neither watches the build’s runtime behavior.
How Secrets Leak During the Build Process
The build’s runtime is the blind spot most secrets strategies never address. To be useful, a secret must be decrypted and injected into an environment variable or memory at the exact moment the build runs, so in that window it isn’t a file a scanner can inspect, but a live value inside a running process that anything in that process can read.
That’s a meaningful opening, because a lot of untrusted code runs inside the trusted build. Attackers use techniques OWASP groups under Poisoned Pipeline Execution: malicious pull requests, unsanitized workflow inputs, and “pwn request” patterns that trick a pipeline into running attacker-controlled code with full access to its secrets. A compromised dependency or tampered CI action does the same from the inside.
In the tj-actions/changed-files compromise (CVE-2025-30066), attackers put a malicious commit in the action’s own repository and repointed its version tags at it. Pipelines ran the poisoned code with no change to their own workflow files, and it leaked secrets through the build logs, where a source scan would never catch it.
The most insidious version modifies a build script only while it runs, then erases the evidence. For example, injecting a single line during execution:
The secret is exfiltrated, and the command is gone before anyone inspects the repository. Real incidents have followed this pattern. The Ultralytics attack among them, where the malicious behavior lived in the running pipeline, not in committed source. Because the offending code never persists, repository-focused defenses never see it.
Why Secrets Leaks Are Difficult for DevSecOps Teams to Detect
The standard defenses each have a specific blind spot:
- Static scanners read code at rest. They catch a key committed to a file but inspect what’s written down, not what happens at runtime. So, a secret injected only during the build, or exfiltrated by code-modified mid-execution, isn’t there to scan.
- Secrets managers secure storage, not behavior. A vault hands a secret to the process that asks for it but has no visibility into what that process then does. If the requester is compromised, the vault never sees the malicious call made with it.
- Pattern-based detection misses generic secrets. Even GitHub’s push protection depends on known patterns and misses credentials like MySQL and MongoDB connection strings, which is why catching generic secrets now requires a separate AI-powered detection feature and an explicit opt-in for non-provider patterns.
- Volume buries the signal. High false-positive rates train teams to skim alerts, so real leaks get lost.
The results show up in remediation data: breaches involving stolen credentials take an average of 246 days to identify and contain (IBM Cost of a Data Breach 2025). A leaked secret isn’t a brief exposure. It’s an open door that often stays open for the better part of the year.
The Security Risks of Secrets Exposure
A single leaked credential is rarely the end of the story. It’s usually the first step:
- Direct access to production: databases, cloud accounts, and internal services, reached with valid credentials that raise no alarms.
- Supply-chain compromise: a leaked pipeline credential lets an attacker tamper with the build and ship malicious code downstream. The Codecov breach exfiltrated secrets across thousands of pipelines; the SolarWinds compromise pushed tainted software to roughly 18,000 organizations.
- Lateral movement: over-permissioned NHIs let an attacker pivot across an environment.
- Data breaches and ransomware: stolen credentials are used to exfiltrate data or, in the case of valid cloud keys, encrypt storage and hold it for ransom.
- Business fallout: regulatory penalties, breach-notification costs, lost trust, and reputational harm that outlasts the incident.
The throughline: secrets are leverage. Whatever an exposed credential can touch, an attacker can touch, and pipeline credentials tend to touch a lot.

Figure: Layered controls to reduce secrets exposure.
How Security Teams Can Prevent Secrets Leaks
No single control eliminates secrets leakage, but a layered set of practices sharply reduces how often secrets leak and how much damage they do:
- Stop hardcoding; centralize in a vault and inject secrets at runtime.
- Scan before secrets reach history with pre-commit and pre-push Git hooks; platform-native tooling like GitHub secret scanning and push protection blocks known formats at commit time.
- Lean on provider-side revocation. When a known token format leaks publicly, GitHub’s secret scanning partner program notifies the issuing provider so the credential can be revoked, often before it’s used; treat any partner alert as an immediate rotate-and-investigate trigger.
- Prefer short-lived, dynamic secrets and automate rotation.
- Enforce least privilege for every identity, with an inventory of what each can reach.
- Pin and verify third parties by immutable commit SHA, not mutable tags.
- Keep secrets out of logs by masking output and disabling verbose debug logging.
- Map controls to a framework: the OWASP Top 10 CI/CD Security Risks, especially CICD-SEC-6 (Insufficient Credential Hygiene).
Protecting Secrets Requires Securing the Build Pipeline
Nearly all of those practices share one trait: they protect code at rest and secrets at the point of injection. Vaults secure storage; scanners inspect what’s written down; rotation limits the blast radius after the fact. These are essential; but they leave the build’s runtime largely undefended, and that’s precisely where the hardest leaks happen. When a secret is live in memory and untrusted code runs alongside it, the question shifts from “is this credential stored safely?” to “what is this build actually doing right now?” Which requires watching behavior during execution: the connections a build opens, the processes it spawns, where it sends data, and whether any of it deviates from normal.
This is the gap InvisiRisk’s Build Application Firewall (BAF) is built to close. It acts as a runtime firewall for the pipeline, enforcing egress and registry policy as the build runs, flagging secret-shaped data heading to unexpected destinations, and using anomaly detection to catch novel/abnormal behavior, the kind that modifies a script mid-run and disappears before a scanner could see it. Foundational hygiene secures your secrets at rest; securing the build pipeline itself, while it executes, closes the runtime blind spot that storage-focused tools can’t reach.
To see how InvisiRisk protects credentials during the build, read Why Your Secrets Faucet Is Still Leaking or request a demo.


