In 2024, 23.8 million secrets were leaked into public GitHub repositories. API keys, passwords, tokens. A 25 percent increase on the year before.
That number gets quoted often enough to have gone numb. Here is the one that should not.
Of the secrets leaked in 2022, GitGuardian reports that 70 percent were still active when they published in 2025.
Three years. Still valid. Nobody rotated them, because rotation requires somebody to know it happened, care that it happened, and have the authority to break whatever depends on that key.
Those three conditions rarely land on the same person. The scanner knows. The developer cares. The platform team owns the outage. So the key stays live and everybody's individual behaviour was reasonable.
A leaked credential is a condition, not an event
Most organizations treat credential exposure as an incident. Something occurs, a ticket opens, it closes.
The 70 percent figure says otherwise. A leaked key is a state your infrastructure is in, and it persists until somebody deliberately ends it. The commit that exposed it is ancient history. The key still opens the door.
This is worth naming clearly because it changes what the control is. Scanning tells you a secret exists in a repository. That is detection. Rotation is the control, and it is the part that requires a human to accept downtime in a system they may not own.
Ask how many keys your organization rotated last quarter, then ask how many it scanned. The gap between those numbers is the actual exposure.
The asymmetry is structural. Scanning is cheap, automated and safe. Rotation is manual, risky and touches production. So one number climbs every year and the other does not, and the reporting looks like progress.
The assistant raises the rate
Into that pre-existing condition arrived coding assistants, and the data on what they changed is unflattering.
GitGuardian's analysis, reported in April 2025, found that public repositories using GitHub Copilot exposed secrets in 6.4 percent of cases, against 4.6 percent across public repositories generally. A 40 percent higher incidence.
Consider why that could be, because the interesting answer is not that the model types passwords. It suggests something about pace. Assistants raise the volume of code produced per developer, and secrets get committed at roughly a constant rate per unit of code written in a hurry. More code, more hurry, more keys.
There is a second effect worth watching. Assistants produce plausible boilerplate, and boilerplate is exactly where a placeholder credential goes to become permanent. The model suggests a connection string with a key in it, the developer substitutes a real value to make it run, and the line ships looking like every other line.
Nothing here requires anyone to be careless. It requires a suggestion that is 95 percent right, arriving at the moment somebody wants to see the thing work.
And 45 percent of the code carries a known flaw
The secrets are the narrow problem. Veracode measured the wider one in 2025.
They built 80 coding tasks across four languages and four vulnerability classes, then gave those tasks to more than 100 models. Across all models and all tasks, 55 percent of generations produced secure code. In the other 45 percent, the model introduced a known security flaw.
The finding that should reset expectations is what happened over time. Security performance was largely unchanged as the models improved, and the newest and largest models were not safer than the smaller ones. They were better at making code that works.
That is not a gap that closes with the next release. It is a consequence of what these systems were optimized against.
Two of the category results are worth carrying into a conversation with engineering, because they are specific enough to act on. Cross-site scripting and log injection failed at rates far above the average, and Java was the weakest of the four languages tested. If you know which flaws the generator favours, you know which rules to enforce in the pipeline.
Why correctness and security came apart
Training and evaluation have focused hard on whether generated code does the thing that was asked. There are benchmarks for that, and progress on them has been genuine and fast.
Security is a different property. It is about what the code also permits, which is invisible in any test that checks whether the feature works. Code with a SQL injection flaw passes its functional tests. That is what makes the flaw survive.
So the assistant is being graded on one axis and deployed against two. Nothing malfunctioned. The system delivered exactly what it was measured on.
The control that quietly stopped scaling
Code review was the mechanism that used to catch this. A second person read the diff.
That control was designed for a world where writing was slow. It assumed the reviewer and the author worked at comparable speed, so the review was a real gate rather than a formality. Raise generation throughput several times over while reviewer headcount stays flat and review becomes approval.
This is the same shape as every other problem of its kind. The volume of a probabilistic system's output exceeded the capacity of the human step that was supposed to check it, and the human step is still on the diagram.
Worse, the reviewer's incentive changed. Reading a colleague's code carried social weight, because a mistake was attributable to a person. Reading generated code feels like proofreading a machine, and people skim machines.
What actually helps
The effective controls are unglamorous, automated and older than the problem.
Secret scanning before the commit lands, not after. A key caught in a pre-commit hook was never exposed. A key caught in a nightly scan is already a rotation project.
Short-lived credentials, so exposure has an expiry even when nobody notices. This is the single highest-return change available, because it turns the 70 percent statistic into a non-event.
Static analysis in the pipeline, blocking on the vulnerability classes the research says these models produce. You know which ones. They were published.
Make the gate binding rather than advisory. A scanner that files a ticket is a reporting tool. A scanner that fails the build is a control, and the difference is a configuration flag somebody has to be willing to set.
And treat generated code as third-party code. It came from outside your organization, no engineer on your team can explain every line, and it is entering your build. That is the definition you already use for a dependency.
That reframe does more work than any single tool. Dependencies already have a review path, an owner, a scanning requirement and a way to be removed. Generated code has none of those in most organizations, despite arriving in far greater volume.
The test to run this week
Take the most recently merged pull request that contained AI-assisted code. Answer three questions.
Did a static analysis tool run against it before merge, and did it have authority to block. Did a secret scanner run before the commit, not after. And how long is the shortest-lived credential in that service, in hours.
If the third answer is measured in years, you already have the 70 percent problem. You just have not had the leak yet.
Run the same three questions against a service nobody has touched in 18 months. That is where the long-lived credentials live, because nothing has forced anyone to look.
Then ask the question for the person who owns engineering. Generation throughput went up this year. By how much did review capacity go up?
Sources
GitGuardian, The State of Secrets Sprawl 2025, March 2025. 23.8 million secrets reached public GitHub in 2024, a 25% rise, and 70% of secrets leaked in 2022 were still active. 4.6% of public repositories contain a secret against 35% of private ones. Company-published.
Leyden, J., AI programming copilots are worsening code security and leaking more secrets, CSO Online, April 2025. Public repositories using GitHub Copilot exposed secrets in 6.4% of cases against 4.6% overall, a 40% higher rate. Trade reporting.
Veracode, 2025 GenAI Code Security Report, July 2025. Across 80 coding tasks given to over 100 models, 55% of generations were secure, meaning 45% introduced a known flaw. Performance was largely unchanged as models improved at correctness. Company-published.
