Secrets Management for SaaS Founders (CISA Breach Lessons)

Table of Contents
I'm rotating three of my own secrets this week. Three keys ended up where they didn't belong, I caught it fast, and I have a nightly backup as a safety net while I cycle them out. I'm telling you this before I tell you anything about CISA, because I'd rather be the founder who admits the near-miss than the one who pretends his setup is perfect.
What finally made me stop procrastinating on it was reading about the CISA leak.
A contractor for the Cybersecurity and Infrastructure Security Agency maintained a public GitHub repository called "Private-CISA" that exposed administrative credentials to three AWS GovCloud accounts, dozens of plaintext passwords, and internal deployment configs [S1]. It was created on November 13, 2025, and stayed public until security researchers flagged it on May 15, 2026 [S1]. That's six months. This wasn't a sophisticated attack. Someone disabled GitHub's default secret detection, committed files named "importantAWStokens" and "AWS-Workspace-Firefox-Passwords.csv," and left them open to anyone with an internet connection [S1].
Guillaume Valadon from GitGuardian called it "the worst leak that I've witnessed in my career" [S1]. Philippe Caturegli from Seralys confirmed the credentials could authenticate to three AWS GovCloud accounts at a high privilege level and reach CISA's internal artifactory, the repository of every code package used to build their software [S1]. The keys stayed valid for 48 hours after the repo was taken offline [S1].
If this can happen to a federal cybersecurity agency, it can happen to your SaaS. The difference is you don't have a security team to clean up after you. You have you, at night, rotating keys.
Why early-stage founders get this wrong
We treat secrets management as a future problem. You're shipping fast, the team is one or two people, everyone has admin anyway. A Stripe key in a .env file feels harmless when two people touch the codebase.
It doesn't stay harmless. Research cited by secrets management platforms found 96% of organizations have secrets scattered across code, config files, and multiple environments [S3]. Toyota, Mercedes-Benz, government institutions, and modern tech companies have all leaked credentials on GitHub [S2]. The CISA contractor used the repo as a working scratchpad, syncing backups and credentials across environments, and many passwords followed a pattern of the platform name plus the current year [S1]. Every one of those was a shortcut that felt reasonable in the moment and became indefensible once it was public.
For a SaaS holding customer data, a single leaked database credential or API key can mean direct access to production data, the ability to impersonate your app to third-party services, mandatory breach notifications, and the reputational hit that ends early traction. Organizations that automate detection cut breach costs by $1.9 million on average [S3]. I am not at that scale, and I still don't want to be the cautionary tweet.
Automated scanning is the cheapest thing you'll do all month
The CISA contractor explicitly disabled GitHub's default setting that blocks publishing keys in public repos [S1]. That's removing the safety from a loaded gun. Scanning tools exist to catch exactly this.
git-secrets, trufflehog, and GitGuardian scan repos for patterns that match API keys, tokens, certificates, and other credentials [S2]. Wired into your pipeline, they block commits with secrets before those commits ever reach the remote. Here's the basic setup I'd start with.
Install git-secrets locally:
git clone https://github.com/awslabs/git-secrets
cd git-secrets
make install
Wire it into your repo:
cd /path/to/your/repo
git secrets --install
git secrets --register-aws
That adds pre-commit hooks that scan for AWS credentials. Add custom patterns for broader coverage, then add a scanning step to your CI/CD pipeline so every pull request is checked and merges are blocked when a secret is found. The point is that it's automatic. Manual review fails because humans miss things when they're moving fast. I missed something when I was moving fast. That's the whole reason I'm writing this.
Stop secrets from existing in your code at all
Scanning catches accidental commits. Proper storage means the secret was never in the code to begin with. The CISA repo held plaintext credentials in CSV files and config backups [S1]. Those should never be committed, even to a private repo.
Environment variables are the baseline. Instead of hardcoding a key in source, read it from process.env and keep the real value in a .env file that's listed in your .gitignore. That works locally but doesn't solve distribution: how do you get secrets to teammates, staging, and production without DMing them or committing them?
Secret management services. AWS Secrets Manager, Doppler, and similar tools encrypt secrets at rest, give you audit logs, and integrate with your deploys [S2] [S3]. Your app fetches them at runtime instead of you copying credentials onto every server. Credentials never touch your codebase or your laptop. And rotation, the thing I'm doing this week, becomes trivial: update the value in the manager, restart the app. No code change, no redeploy. If I'd had every one of these three keys behind a manager from the start, this week would be a thirty-second job instead of a careful, backup-first cycle.
For an early product this feels like overkill. It isn't. Setting up a secret manager takes an afternoon. Cleaning up a leak takes weeks and costs trust you can't spare.
The repo audit checklist I'm running on myself
If you've ever committed a secret, it's still in your Git history after you delete it. Every commit is permanent unless you explicitly remove it. Here's the checklist.
- Scan the full history, not just current files with trufflehog's filesystem mode. Review the output for API keys, tokens, passwords, and connection strings.
- Check for common secret files:
.envvariants,config.json,secrets.yml,credentials.csv,id_rsa,*.pem,*.key, and database backups (*.sql,*.dump). - Verify your .gitignore covers them (
.env*,*.pem,*.key, secrets configs). - Rotate anything you find. If it was in history, assume it's compromised. The CISA keys stayed valid for 48 hours after the repo came down [S1]. That window is real, which is exactly why I'm doing my rotation with a backup in place instead of yanking everything at once.
- Remove secrets from history with BFG Repo-Cleaner or git-filter-repo, then force-push and tell anyone with a local clone to re-clone.
- Enable GitHub secret scanning. It scans public repos for known patterns automatically; turn it on for private repos too. The CISA contractor disabled it [S1]. Don't.
How any one of these would have stopped CISA
The breach was preventable at five separate points. If the contractor had left GitHub's secret detection on, the platform would have blocked the keys [S1]. If they'd used environment variables instead of committing CSVs, the credentials wouldn't have existed in the repo [S1]. If they'd stored secrets in a manager, the "importantAWStokens" file would have been unnecessary [S1]. A pre-commit hook would have caught it locally [S2]. A routine audit would have flagged the public repo [S3].
Caturegli identified the exposed artifactory credentials as a prime target for lateral movement and backdooring software packages [S1]. None of the fixes above need an enterprise budget or a security team. They need you to treat secrets as the high-value targets they are.
What this means if you hold customer data
Customers trust you with their data before you've earned it. One leaked credential that exposes user information ends that trust for good. SOC 2, GDPR, and HIPAA all require secure credential management [S3], so failing an audit because a key was committed to GitHub is an unforced error.
The good news: the work is front-loaded and cheap. Scanning tools are free. Secret managers have generous free tiers. You set it up once and maintain it as part of normal development.
The CISA repo was public for six months and granted admin access to federal cloud infrastructure [S1]. Your startup can't survive six days of that. I'm spending this week rotating three keys because I'd rather do the boring fix now than write the apology email later. If you've been putting your own rotation off, the CISA leak is your reminder too. See how I build ConnectEngine in the open.
Tobias Koehler
Founder, ConnectEngine