What the CISA GitHub Leak Teaches Every Team About Secrets

Share
What the CISA GitHub Leak Teaches Every Team About Secrets
A public GitHub repository exposing cloud credentials that should never have been committed.

The agency that tells the rest of the US government how to secure its systems left administrative AWS GovCloud keys and dozens of plaintext internal passwords sitting in a public GitHub repository for roughly six months. As reported by KrebsOnSecurity, which broke the story after being contacted by the researcher who found it, CISA has since published a postmortem on the incident. The details are worth reading not for the schadenfreude, but because every failure in the chain is one that a normal engineering team can and does make, and the lessons transfer directly.

Here's what happened, and what to actually take from it.

What Leaked

According to KrebsOnSecurity and GitGuardian, whose researcher Guillaume Valadon discovered the exposure, a public repository named "Private CISA" held 844 MB of sensitive material tied to CISA and DHS. Among the files: one literally titled importantAWStokens containing admin credentials to three AWS GovCloud accounts, and an AWS-Workspace-Firefox-Passwords.csv listing plaintext usernames and passwords for dozens of internal systems. Reporting also described SSH keys, authentication tokens, deployment logs, Kubernetes files, and CI/CD workflows in the repo.

The repository was maintained on a contractor's personal GitHub account, created in November 2025, and, per the reporting, the contractor had at one point manually disabled GitHub's built-in secret-scanning push protection in a commit. The one piece of good news, from GitGuardian's analysis: the repo was never forked, which limited the blast radius.

That's the setup. The interesting part is the response, because that's where the transferable lessons live.

Lesson 1: Secrets Belong in a Manager, Not in Git

This is the root cause and it's the most common one in the industry. Credentials were stored in plaintext files and committed to version control instead of being fetched from a secret manager at runtime. Once a secret is in Git history, it's there forever unless you rewrite history, and a single push to the wrong remote makes it public.

The fix is architectural, not a matter of being more careful. Secrets get injected at runtime from a vault (HashiCorp Vault, AWS/GCP Secrets Manager, or the sealed-secrets/External-Secrets pattern in Kubernetes), never written to a file that lives in the repo. This is the exact reasoning behind the GitOps secrets discipline I laid out in building a secure GitOps pipeline, a plaintext credential in a Git-tracked file is a credential in version history forever, so the design has to keep it out of the tree entirely rather than trusting people not to commit it.

⚠️ And the .csv of plaintext passwords is worth dwelling on: even inside a private repo, plaintext credential stores are a liability. The privacy of the repo is one config toggle away from public, as this incident proves. Encrypt at rest, store in a manager, and treat "it's a private repo" as zero security guarantee.

Lesson 2: Push Protection Only Works If You Can't Turn It Off

GitHub's secret scanning with push protection exists to block exactly this, and it was reportedly disabled by hand. That's the failure mode of any control an individual can override: it protects you right up until someone with a deadline switches it off.

The organizational answer is enforcing these controls at the org level where individual repos and users can't disable them, not leaving them as per-repo toggles. This is the enforcement gap I flagged in the six free GitHub security settings, push protection and branch rules only bite if they're mandated centrally. A control that a tired contractor can toggle off is a control you don't actually have. Enforce org-wide, audit for exceptions, and alert when protection gets disabled on any repo.

Lesson 3: Scan Continuously, Not Quarterly

The repo sat public for six months. What surfaced it was GitGuardian's continuous scanning of public GitHub, not any internal CISA process. CISA's own postmortem acknowledged the value of continuously scanning public repositories for exposed secrets, and Valadon's analysis made the point directly: comprehensive internal scanning could have caught the plaintext passwords and committed backups long before they ever left the building.

The lesson for any team: point secret-scanning at both directions. Scan your internal repos for committed secrets, and monitor public repos for your organization's secrets showing up where they shouldn't (a contractor's personal account, a fork, a mirror). Quarterly audits don't catch a six-month exposure; continuous monitoring does. This pairs with the supply-chain inventory logic of an SBOM, you can't protect what you don't know you have, whether that's a dependency or a credential.

Lesson 4: Make It Trivial to Report a Leak About You

This is the lesson CISA itself emphasized most, and it's the one most organizations get wrong. Per the postmortem, before the public notification, nine automated GitGuardian alerts about the exposed credentials went unanswered. The researcher then had to try multiple channels, emailing the contractor, submitting through CISA's vulnerability disclosure platform (which is meant for vulnerabilities in the broader ecosystem, not incidents affecting CISA itself), and ultimately going to a journalist, before anyone acted.

Valadon's framing, as quoted in the reporting, is the takeaway worth pinning up: letting nine notification emails go unanswered is how a one-day incident becomes a six-month exposure. Make it trivial to report a leak about you, not just about your products. The person reporting a leak to you is not the threat.

Concretely: publish a security.txt, but don't stop there. Put reporting instructions in several prominent places, and make sure a report about your own infrastructure doesn't land in a product-bug queue where it gets triaged as low-priority and ignored. CISA's own postmortem stressed that distinct reporting channels, separating "something's wrong with us" from "something's wrong with our products," are essential. If your only intake is a product security form, an urgent report about your leaked keys will die in the wrong queue.

Lesson 5: The Response Timeline Is Its Own Failure Mode

Even after acknowledging the alert, CISA reportedly took more than 48 hours to invalidate the AWS keys. The postmortem attributed this to the complexity of the agency's systems and its interconnections with federal and industry partners, and drew the lesson that organizations should maintain mature, well-tested key-management and rotation capabilities.

⚠️ This is the part teams underestimate. Knowing a key is compromised does you no good if rotating it takes two days because nobody's ever tested the rotation path under pressure. Every hour a known-compromised admin credential stays valid is an hour of exposure. Rotation has to be a rehearsed, fast operation, not a thing you figure out live during an incident. If you can't rotate every production secret quickly and confidently right now, that's a gap to close before you need it, not during.

What CISA Got Right

Worth noting, because it's instructive too. Per the postmortem, CISA's enhanced logging and its adoption of zero-trust principles in both production and development let it establish scope: the detailed logs allowed the agency to show the leaked credentials weren't used outside its environments and that no customer or mission data was exposed.

⚠️ But hold that claim at the right confidence level, and this is a general incident-response lesson. As security analysts noted, "no public proof of compromise" is not the same as "no compromise." Good logging lets you answer the narrower, harder questions, who accessed what, which credentials were valid during the window, which API calls were made, whether artifacts or workflows changed, and that's exactly why comprehensive logging is what turns "we hope it's fine" into "we can demonstrate what happened." It's the same argument for tamper-resistant, off-host logging, the evidence trail is what lets you bound an incident instead of guessing at it.

The Meta-Lesson: Publish the Postmortem

Valadon's assessment, per the reporting, was that the biggest positive is the postmortem itself, and that it may be the first time a national cybersecurity agency has publicly advocated for secrets scanning and for simplifying how researchers report issues. That transparency, being honest about what worked and what didn't, is the incident communication every organization should aspire to.

That's the real takeaway. The leak was avoidable and the response was slow, but publishing an honest analysis of both is how the whole industry gets better, and it's a lot more useful than the reflexive corporate instinct to say as little as possible.

Bottom Line

None of these failures required a sophisticated attacker, the exposure was a contractor committing plaintext secrets to a personal public repo with the safety net manually switched off. The lessons are boring and universal: fetch secrets from a manager at runtime, enforce push protection at the org level so nobody can disable it, scan continuously in both directions, make it trivially easy to report a leak about your own infrastructure, and rehearse credential rotation so it's fast when you need it. The agency that literally exists to prevent this made every ordinary mistake, which is precisely why the rest of us should treat it as a checklist rather than a punchline.


References