Shift left without the platform bill
“Shift left” has been a slogan long enough that it’s mostly stopped meaning anything. Said plainly, it’s one idea: find the problem where it’s cheap to fix — in the editor or the pre-commit hook — instead of where it’s expensive — in a pentest report three weeks before launch. None of the tooling that does this needs a platform purchase or a security team of any size. It needs to be free enough and fast enough that a developer runs it without being told to.
Secrets belong in a vault, not a repo
The discipline is simple even when the tooling varies: nothing that grants access — API keys, database credentials, signing keys — gets committed, ever, including in history. A few ways to make that the easy path rather than the disciplined one:
- HashiCorp Vault, run as a single container (
vault server -devin Docker) for local work, and properly unsealed and backed by real storage for anything shared. Apps read secrets at start-up or runtime; nothing sensitive sits in a.envfile that outlives the session. - sops + age for anything that needs to live in git anyway (encrypted config, not raw secrets) — small, auditable, no server to run.
- gitleaks or trufflehog as a pre-commit hook and a CI gate, so a credential that does slip into a diff is caught before the push, not after someone else clones the repo.
The common thread: the safe way and the fast way are the same command. A vault nobody can reach from their laptop in ten seconds gets bypassed by Friday.
SAST that runs before the PR, not instead of one
Static analysis earns its keep in the editor and the pre-commit hook, where a finding costs a few seconds, not in a weekly report nobody opens:
- Semgrep (the open-source engine and community rulesets) as an IDE plugin and a pre-commit hook, plus its own CI step for the rules that are too slow to run on every keystroke. It’s fast enough to feel like a linter, which is exactly why people tolerate it.
- Bandit, gosec, or the language-appropriate equivalent for anything Semgrep’s generic rules miss.
- Trivy for the container image itself — base image CVEs, exposed secrets baked into a layer, misconfigured Dockerfiles — run as part of the same build that produces the image, not as a separate audit weeks later.
DAST against something that actually runs
Static analysis reasons about code; dynamic analysis pokes at the running thing, which catches a different class of problem — the ones that only exist once request handling, auth and configuration are all wired together.
- OWASP ZAP, baseline or full scan, run in Docker against a
docker-composestack that stands the app up the same way CI does. Because it’s the same container image and the same compose file a developer already has, reproducing a finding locally is adocker compose upaway, not a ticket to the security team. - Run it in CI against a staging build on every merge to main, not as a pre-release ritual. A DAST scan that only runs once a quarter mostly tells you about problems that have been live for a quarter.
Docker is what makes any of this shift left
The reason to standardise on containers here isn’t fashion, it’s reproducibility: the SAST rules, the DAST target, and the dependency scan all run in the same environment locally as they do in CI. That’s what actually moves the check left — not the tool’s marketing, but the fact that a developer can run the exact CI job on their own machine before they push, see the same result, and fix it before anyone else sees a red pipeline.
The IDE is the cheapest gate you have
Every one of these tools has an editor integration, and that’s where most of the value is. A Semgrep or gitleaks finding underlined while you’re still writing the line costs nothing. The same finding surfaced by a CI job twenty minutes later costs a context switch. The same finding surfaced by a pentester three weeks before launch costs a delayed release and an uncomfortable conversation. It’s the same defect at every stage — only the price changes.
None of this needs a budget. It needs the free versions wired into the loop people already work in, and then — same principle as anywhere else — actually used. A vault nobody unlocks, a scanner nobody runs locally, and a DAST job that only fires before a release are controls in name only. The tooling here is cheap. Making it the path of least resistance is the actual work.
- devsecops
- docker
- opensource
- sast
- dast