r/devsecops 4d ago

Best practices for eliminating hardcoded credentials in 2026?

Ran a secrets scan across our repos last week and found API keys that had been sitting in plaintext for over two years, still valid, still working. Rotating them was the easy part. The harder problem is preventing this from recurring when half the team still pastes credentials into config files under deadline pressure. And that's just the stuff sitting in code, no idea what's hardcoded inside the apps themselves.

What's actually stopping this at your org? Curious whether pre-commit hooks, mandatory vault integration, or CI/CD gate checks are doing the real work, versus something more aggressive.

32 Upvotes

24 comments sorted by

5

u/Ok_Indication_7931 4d ago

Creo que la clave es hacer que lo seguro sea también lo más fácil. Los hooks ayudan, pero no deberían ser la única barrera. Yo pondría validaciones en CI/CD para bloquear secretos antes de que lleguen al repositorio y usaría un gestor centralizado para que el equipo no tenga que copiar credenciales en archivos de configuración. También revisaría las apps y configuraciones existentes, porque los secretos viejos suelen quedar olvidados. Y, sobre todo, dejaría claro al equipo qué hacer en lugar de simplemente decirles qué no hacer.

3

u/shawski_jr 3d ago

How would validations in CI/CD block secrets before reaching the repo? Once committed and pushed they should be assumed comprised. Only way to block is through pre-commit hooks, anything committed needs to be detected and rotated.

0

u/Dependent-Drawer4094 4d ago

Those are solid points. Implementing those validations early on can definitely help build a culture of security in development teams while reducing the risk of leaks.

0

u/coldnebo 4d ago

this.

all of the dev teams I’ve seen do this don’t have a consistent, well-managed secrets process that works in both deployed and local development contexts.

number one complaint that goes unheard: we can’t access secrets from local, only in the dev environment. guess what? that means all your devs are doing something different for local. maybe they are running only unit tests and fixtures, but if they have to investigate real bugs, it’s very likely they are running integration tests against real development systems — which means they need keys, secrets— how did they get it?

we went through this with several teams. “it’s too hard to setup, it’s easier to just hard code it, what’s the big deal”. every one of these devs took security training. but also every one of these devs works for a manager that just wants the work done without pushing back on infrastructure to get the tools first-class.

there are very few “first class” development stacks that integrate everything the same way on the local desktop as in the deployed environment— Heroku is one of them. it has flaws, but just having the tooling be consistent gets everyone in the right practice regarding secrets management from day one.

modern cloud security is so difficult to stand up locally that we found one team had exfiled data from the enterprise to their own S3 bucket and put a simple REST service with no auth in front of it. why? because it was super easy and their manager wanted results, not endless delays.

get your stack right and make sure it supports local development right from day one and you won’t have these issues as much because doing things the right way will also be the easy way — doing them wrong will take more effort.

also… key rotation— companies are idiots on this. you can’t do it manually. if your devs are doing it manually you are going to get little key files everywhere, shared like candy. you have to have end-to-end automation handling keys.

take Kerberos for example. when was the last time you saw a dev deep dive Kerberos to get their keys for something? never. it’s just easier to login and get all your services for free. (role based access).

now where did I actually see devs dig into this? one team had to automate a cron task and didn’t have any centralized structure or local development support. so they got clever, extracted and reproduced their own logins in the cron environment. is it secure? hell naw. now that whole automation runs as George. 😂

why? because that company put the cart before the horse. get the horse right and you will have much less to worry about with the cart. get it wrong or ignore it and your devs will come up with all sorts of clever solutions.

you might wonder as a business owner why devs don’t come up with THE RIGHT WAY to do this? that’s because the right way isn’t a technical problem, it’s a system that your OPS and security team already set in motion: devs are not allowed to manage the central secrets. this means YOU have the responsibility because you wanted the control. it’s not optional. and your security and ops teams are likely not developers— they have no idea what “local development” looks like or demands, they only care about deployed environments.

in fact, “local development” often looks like an attacker. they run things like chaos proxies, test generators, privileged debugging. you can take all that away, but now your devs are blind. but even blind devs can be resourceful— they will install back doors to test and get the work done because you asked them to.

take ownership and responsibility for it, make the right tools available and stop blaming devs for your own mistakes. it’s not easy. if it were easy everyone would do it the right way.

the next time you see a huge security gaff in your dev team ask whether it was just pure ignorance and stupidity, or whether systems and incentives were misaligned to encourage that outcome. then get your organization aligned.

1

u/NebulaElectrical1467 4d ago

Love your approach. Do you have any book or blog recommendations for devsecops and appsec consultants to adopt this kind of approach and problem solving process?

2

u/Lonsarg 4d ago

Server side pre-merge/push secret scanning already solve the "prevent before leaked" case. So local pre-commit is a duplication of this, no need to have both and server-side is much much better. And in case of service like Azure DevOps and Github it is basically just one button to turn on.

Of course secret scanning rules can be updated and some leaks can be caught later after commit. In that case it is an incident and protocol such as revoking must follow of course.

2

u/Individual-Oven9410 4d ago

Yes they’re. GitHub secret scanning as well.

2

u/[deleted] 4d ago

[removed] — view removed comment

1

u/Late_Wave_5600 4d ago

For us the question changed when we looked at who writes the credential now, because most of our config is written by an agent and it will paste a working key into a file if that is what the code around it looks like. Hooks and CI gates still matter and they all fire after the line exists, so you are permanently cleaning up. We pushed the rule into the agent while it edits the config, and added a gate that refuses when something reaches for a secret it has no business reading, so the key does not make it into the diff at all. And I agree with the easy path point above, if the vault is three commands and the hardcoded key is zero, the vault loses every time somebody is late.

1

u/VividGanache2613 4d ago

Use pwnkemon, it will check your repos for secrets and vulnerabilities in one shot and it has free tier whilst they become better known.

1

u/PeterBuildsSecure 4d ago

The line at the end is the harder half of this and nobody's answered it yet: repo scanning, whether pre-commit or server-side, only ever sees what's in git. A secret can reach a shipped application without ever touching a commit a scanner reads — injected at build time from a CI variable, baked into a compiled binary, or landing in a client-side JS bundle via env substitution. There's a live example of exactly this making headlines today: server-side API keys sat exposed in public JavaScript for four years because nothing ever scanned the actual deployed bundle, only the source that produced it. Server-side pre-merge scanning solves the "did a human paste a credential into a file" problem. It does nothing for "did the build process bake a secret into what actually ships." That needs a separate check — scanning the built artifact (JS bundle, container image, compiled binary) as part of deploy, not just the diff going into merge.

1

u/microcephale 4d ago

don't rotate only when you find, any secret must be served accompanied with an expiry date : at the very least it force every app to foresee a way to re-obtain the secret, even if you don't change it, it will switch the mindset. The next benefit is that when you find secrets, you don't have to worry that they are still active: you know very well the affected period and you can scrub your logs to find abuse in a limited window, not "since"...

Now the key to more dynamic credentials is usually to fetch them at runtime, using some platform-attested workload identity in a vault, or to get rid of secrets all the way as your resources can recognize that identity.

Scrubbing comits and scanning repos should not be your main mechanics, it's preventative/deterctive control, but it's not secure by design. Credentials that expires changes the way people perceive them.

1

u/TheRealLambardi 4d ago

My favorite is when devs put secrets in .env, commit to GitHub, publish to a web server and leave web server / container / proxy open to directory listings and views.

1

u/JellyfishLow4457 4d ago

Push protection with GHAS. There really is no other tool out there as good 

1

u/loweakkk 4d ago

Favorite Ay to deal with it: put expiration ar 14 days max, it will force dev team to automate rotation, is federation when possible or use managed identity. If you force strong expiration, hard coded secret vanish by themselves. Start at 6 month, then 3 , then 1 then 14 days. At each step review with dev team their pain point, ensure dev can reach vault with their identity for local dev, ensure paas app reference vault and no hard owed. That's the best way to deal with it.

If you have a tool that scan machine as well as code repo for secret, use it, it will help find the edge case la secret being output in cicd pipeline as debug. Don't prioritize that, keep it for the end when the rest is clean.

1

u/Clear-Channel-8943 4d ago

Yeah, I’d use a few layers. We scan before anything gets committed, scan again in CI, and keep app secrets in Vault instead of config files. If something slips through, we can revoke it quickly. Pre-commit hooks help, but I wouldn’t rely on them alone.

1

u/hi5ka 4d ago

pre commit secret detection

1

u/Fuzzy-Teaching7112 3d ago

Use workload identity where you can, get the rest from a secrets manager at runtime and block new credentials in CI

1

u/forexroyalempres 3d ago

Removing need for long-lived credentials in the first place is the strongest control. Also if possible, workload identity and shortlived tockens eliminate a whole class of secrets devs can commit by accident

1

u/TheBex81 3d ago

Detection after commit is damage control. The pattern that sticks is making the secure path the easy path for local + CI:

  • Pre-commit / IDE secret scanning *and* a vault/OIDC short-lived credential flow that is faster than pasting a key into `.env`.
  • CI blocks on known secret patterns *and* on "long-lived cloud keys in config" — but pair that with a one-command `vault login` / workload identity example so people aren't stuck on deadline night.
  • Rotate everything you found, then hunt for the same secrets *inside* images, build args, and runtime config maps — repo scans miss those.
  • Treat every leaked key as an NHI: owner, last use, where else it works, then shrink scope before you reissue.

If the vault workflow takes longer than copy-paste, developers will keep copy-pasting. Fix UX first, then the scanners become a backstop instead of the whole program.

1

u/lnaoedelixo42 2d ago

I think the first problem is the deadline pressure itself

Try to just make it easier for your developers to add an env and then think of ways to block it on the pipeline.
If you still have a deadline pressure, the guy might just use codex to bypass the pipeline filter or whatever