DevSecOps as a Pipeline
The secure delivery pipeline behind LetsBloom: every commit, image, and landing zone runs a gauntlet of security gates from pre-commit to runtime, so nothing reaches production dirty.
Everything LetsBloom shipped, the platform's own infrastructure and every landing zone in its marketplace, went through a delivery pipeline where security was not a review at the end but a series of automated gates all the way through. I built that pipeline. The rule was simple: a change proves it is safe at every stage, or it does not move.
Security is the pipeline, not a review at the end
The clearest way to understand a DevSecOps pipeline is to watch a single commit travel through it. Every artifact, source, Terraform, dependencies, the container image, and finally the running workload, is checked by a gate that owns one class of risk. The gates are ordered so the cheapest and earliest one that can catch a problem is the one that does.
Try it. Inject a problem into the commit and run the pipeline. Watch where it gets stopped, and notice that only a clean change makes it all the way to production.
Inject a problem into the commit, then run it down the pipeline. The earliest gate that can catch it, does. Nothing gets to production dirty.
No issues injected. Press Run to watch a clean commit sail through, or add a problem above first.
The gates, stage by stage
Each gate targets a specific class of risk, ordered cheapest-and-earliest first so failures are cheap:
- Commit: secret scanning (Gitleaks) rejects hardcoded credentials before they ever leave a laptop.
- Build: unit tests, then SAST (Semgrep) on the source, IaC scanning (Checkov and tfsec) on the Terraform, and dependency scanning (Trivy) on the libraries.
- Package: the container image is scanned (Trivy and Anchore) for OS and library CVEs, then signed with an SBOM attached (cosign and Syft) so its provenance is provable.
- Deploy: DAST (OWASP ZAP) attacks a running instance, and Kyverno admission control rejects any non-compliant Kubernetes resource before it can start.
- Runtime: Falco watches syscalls and container behaviour in the live cluster and alerts on anomalies that only appear once something is running.
# Every stage is a gate. A failure stops the merge or the deploy.
jobs:
scan-source:
steps:
- run: gitleaks detect # hardcoded secrets
- run: semgrep ci # SAST
- run: checkov -d . && tfsec . # IaC misconfiguration
- run: trivy fs --exit-code 1 . # vulnerable dependencies
build-image:
needs: scan-source
steps:
- run: docker build -t app:$SHA .
- run: trivy image --exit-code 1 app:$SHA # image CVEs
- run: syft app:$SHA -o spdx-json > sbom.json
- run: cosign sign --key $KEY app:$SHA # provenance
deploy:
needs: build-image
steps:
- run: zap-baseline.py -t https://staging # DAST
- run: kubectl apply -k k8s/ # Kyverno gates admission
# Falco watches the workload from here on, inside the cluster.The supply chain is in the threat model
A lot of the pipeline exists because the risk is not just your code, it is everything your code pulls in. Software composition analysis flags vulnerable and badly-licensed dependencies; image scanning catches CVEs baked into a base layer; and signing the image with an SBOM means you can prove, later, exactly what shipped and that nobody swapped it in between. For a bank's platform, that provenance is not optional.
Fail fast, and tune the gates
Two principles keep a pipeline like this from becoming a wall developers route around. First, fail fast: order the gates cheapest and earliest, so a hardcoded secret dies at the commit and never wastes a build. Second, tune the thresholds: a new gate starts by warning rather than blocking, so the team can burn down the existing backlog before it becomes a hard stop. Security that blocks everything on day one gets switched off by week two.
Why this mattered for a bank's platform
On a platform selling secure infrastructure to a bank, the pipeline is part of the product. It is the mechanism that lets you say, credibly, that everything you ship, and everything customers deploy from your marketplace, met the bar. Automating that bar is what makes the claim true every time, rather than most of the time.