Why DevSecOps
Traditional pipelines treat security as a gate at the end. DevSecOps flips that: every commit is scanned, every dependency is checked, every image is verified before it reaches production. The goal is not to add friction — it is to catch the boring 90% of issues automatically so humans can focus on the interesting 10%.
Pipeline Stages
- Source — signed commits, branch protection, required reviews.
- Static analysis — CodeQL / Semgrep for SAST.
- Dependencies — Trivy or Dependabot for SCA + license checks.
- Build — reproducible container images, pinned base images.
- Image scan — Trivy scan on the built image, fail on HIGH/CRITICAL.
- SBOM — generate + attach a Software Bill of Materials.
- Deploy — OIDC to cloud, no long-lived keys, immutable tags.
- Runtime — monitoring, alerting, and periodic re-scans.
A Minimal Secure Workflow
The workflow below runs on every push. It installs dependencies, runs a filesystem scan with Trivy, builds a Docker image, scans the image, and uploads the SARIF report to GitHub's Security tab.
name: ci-secure
on:
push:
branches: [main]
pull_request:
permissions:
contents: read
security-events: write
id-token: write # for OIDC to AWS/GCP
jobs:
build-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Trivy filesystem scan
uses: aquasecurity/trivy-action@0.24.0
with:
scan-type: fs
scan-ref: .
severity: HIGH,CRITICAL
exit-code: '1'
ignore-unfixed: true
format: sarif
output: trivy-fs.sarif
- name: Upload SARIF
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-fs.sarif
- name: Build image
run: docker build -t app:${{ github.sha }} .
- name: Trivy image scan
uses: aquasecurity/trivy-action@0.24.0
with:
image-ref: app:${{ github.sha }}
severity: HIGH,CRITICAL
exit-code: '1'
ignore-unfixed: trueSecrets Management
- Never commit
.env— use GitHub Encrypted Secrets or a cloud secret store. - Prefer OIDC over long-lived cloud keys (AWS
configure-aws-credentials, GCP Workload Identity). - Rotate anything that ever appeared in a log. Assume it is compromised.
- Run gitleaks in CI to catch accidental secret commits.
Container Hardening
- Use minimal base images (
distroless,alpine, orchainguard). - Pin by digest, not by tag:
FROM node@sha256:.... - Run as a non-root
USER. Drop Linux capabilities. - Set
readOnlyRootFilesystem: truein Kubernetes.
SBOM & Supply Chain
Generate an SBOM with trivy sbom or syft, attach it to the release, and sign artifacts with cosign. This gives you a queryable inventory the day a new CVE drops — instead of grepping repositories at 2am.
Failing Loudly
A scan that warns is a scan that gets ignored. Set exit-code: 1 on HIGH/CRITICAL and let the pipeline fail. Then triage — either fix, upgrade, or explicitly waive with a tracked .trivyignore entry and an expiry date.
Beyond the Pipeline
- Re-scan running images on a schedule — CVEs are published continuously.
- Ship logs and metrics (Prometheus + Grafana, or a hosted stack).
- Practice restoring from backups. An untested backup is a hope.
Wrap-up
A secure pipeline is not a single tool — it is a chain of small, enforced defaults. Start with Trivy + branch protection + OIDC, add SBOMs and image signing next, and layer on runtime monitoring once the basics are boring. The best security work is invisible.
Written by Piyush Prasad — Cloud & DevOps Engineer. Back to portfolio.