A production-grade, security-first CI/CD pipeline built with GitHub Actions β integrating SAST, SCA, secret scanning, container scanning, and DAST as automated security gates.
Author: Adarsh Singh | DevSecOps Engineer | SecurityWithAdarsh
- Architecture
- Pipeline Stages
- Security Tools
- Project Structure
- Quick Start
- Kubernetes Deployment
- Security Reports
- Secrets Management
- Contributing
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GitHub Repository β
β β
β Code Push / PR β
β β β
β βΌ β
β ββββββββββββ ββββββββββββ ββββββββββββ ββββββββββββββββββββββ β
β β SAST β β SCA β β Secret β β Unit Tests β β
β β Bandit ββββΆβ Safety ββββΆβ Scan ββββΆβ + Code Coverage β β
β β Semgrep β β pip-auditβ β Gitleaks β β (pytest) β β
β β CodeQL β ββββββββββββ ββββββββββββ ββββββββββ¬ββββββββββββ β
β ββββββββββββ β β
β βΌ β
β ββββββββββββββββ β
β β Docker Build β β
β β + Push GHCR β β
β ββββββββ¬ββββββββ β
β β β
β βΌ β
β ββββββββββββββββ β
β β Container β β
β β Scan (Trivy)β β
β ββββββββ¬ββββββββ β
β β β
β βΌ β
β ββββββββββββββββ β
β β DAST (OWASP β β
β β ZAP) β β
β ββββββββ¬ββββββββ β
β β β
β ββββββββββββββββββββββββββββββ€ β
β β β β
β βΌ βΌ β
β ββββββββββββββ ββββββββββββββ β
β β Staging β β Production β β
β β (develop) β β (main) β β
β ββββββββββββββ ββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| # | Stage | Tools | Trigger | Gate |
|---|---|---|---|---|
| 1 | SAST | Bandit, Semgrep, CodeQL | Push/PR | β Fails on Medium+ severity |
| 2 | SCA | Safety, pip-audit | Push/PR | β Fails on known CVEs |
| 3 | Secret Scan | Gitleaks | Push/PR | β Fails on any secret |
| 4 | Unit Tests | pytest + coverage | After SAST/SCA | β Fails on test failure |
| 5 | Build | Docker Buildx, GHCR | After tests | Pushes signed image |
| 6 | Container Scan | Trivy | After build | β Fails on CRITICAL/HIGH |
| 7 | DAST | OWASP ZAP | After container scan | |
| 8 | Deploy Staging | kubectl + Kustomize | develop branch |
Manual approval |
| 9 | Deploy Prod | kubectl + Kustomize | main branch |
Manual approval |
| Tool | What it Checks | Config |
|---|---|---|
| Bandit | Python security anti-patterns, hardcoded passwords, SQL injection | security/bandit/bandit.ini |
| Semgrep | Custom rules + community rulesets (flask, secrets, python) | security/semgrep/semgrep-rules.yml |
| CodeQL | Deep semantic code analysis by GitHub | .github/workflows/codeql.yml |
| Tool | What it Checks |
|---|---|
| Safety | Known CVEs in Python dependencies (PyPI advisory DB) |
| pip-audit | Vulnerability audit via OSV and PyPI advisories |
| GitHub Dependency Review | PR-level dependency diff with vulnerability flagging |
| Tool | What it Checks |
|---|---|
| Gitleaks | 150+ secret patterns: AWS keys, GCP tokens, JWT, SSH keys, API tokens |
| Tool | What it Checks | Config |
|---|---|---|
| Trivy | OS packages, language deps, misconfigs, embedded secrets | security/trivy/trivy.yaml |
| Tool | What it Tests |
|---|---|
| OWASP ZAP | XSS, SQLi, CSRF, security headers, active crawl |
DevSecOps-CI-CD-Pipeline/
β
βββ .github/
β βββ workflows/
β βββ devsecops-pipeline.yml # Main pipeline (SASTβSCAβBuildβScanβDASTβDeploy)
β βββ codeql.yml # GitHub CodeQL analysis
β βββ dependency-review.yml # PR dependency gate
β βββ secret-scan.yml # Gitleaks secret scanning
β
βββ app/
β βββ __init__.py # Flask app factory
β βββ routes.py # API routes (/health, /api/info)
β βββ templates/
β βββ index.html # Pipeline visualization UI
β
βββ tests/
β βββ test_app.py # Pytest unit tests
β
βββ security/
β βββ bandit/bandit.ini # Bandit SAST config
β βββ semgrep/semgrep-rules.yml # Custom Semgrep rules
β βββ trivy/trivy.yaml # Trivy scanner config
β
βββ k8s/
β βββ base/ # Kustomize base manifests
β β βββ deployment.yaml # Hardened K8s deployment
β β βββ service.yaml
β β βββ network-policy.yaml # Zero-trust NetworkPolicy
β β βββ kustomization.yaml
β βββ overlays/
β βββ dev/ # Staging (1 replica)
β βββ prod/ # Production (3 replicas)
β
βββ scripts/
β βββ run-security-scan.sh # Local security scan runner
β βββ zap-scan.sh # Local OWASP ZAP runner
β
βββ reports/ # Generated security reports (gitignored)
βββ .zap/rules.tsv # ZAP rule overrides
βββ .gitleaks.toml # Gitleaks config
βββ Dockerfile # Multi-stage, hardened
βββ docker-compose.yml # Local dev + DAST profile
βββ main.py # App entrypoint
βββ requirements.txt # Production dependencies
βββ requirements-dev.txt # Dev/security tool dependencies
βββ pytest.ini # Test config
βββ SECURITY.md # Vulnerability disclosure policy
βββ CONTRIBUTING.md
- Python 3.12+
- Docker
- (Optional) kubectl + a Kubernetes cluster
# Clone the repo
git clone https://github.com/SecurityWithAdarsh/DevSecOps-CI-CD-Pipeline.git
cd DevSecOps-CI-CD-Pipeline
# Create virtual environment
python -m venv venv && source venv/bin/activate
# Install dependencies
pip install -r requirements.txt -r requirements-dev.txt
# Run the app
python main.py
# β Visit http://localhost:5000# Build and start
docker compose up --build
# Run DAST against the running app
docker compose --profile dast up zap# Run all security tools (Bandit + Safety + Semgrep + Trivy)
bash scripts/run-security-scan.sh
# Run unit tests with coverage
pytest# Deploy to staging
kubectl apply -k k8s/overlays/dev/
# Deploy to production
kubectl apply -k k8s/overlays/prod/
# Watch rollout
kubectl rollout status deployment/devsecops-app -n productionrunAsNonRoot: trueβ no root containersreadOnlyRootFilesystem: trueβ immutable container FSallowPrivilegeEscalation: falsecapabilities: drop: [ALL]seccompProfile: RuntimeDefaultNetworkPolicyβ restricts ingress/egress traffic
All reports are generated as GitHub Actions artifacts (retained 30 days):
| Report | Tool | Format |
|---|---|---|
bandit-report.json |
Bandit | JSON |
semgrep-report.json |
Semgrep | JSON |
safety-report.json |
Safety | JSON |
pip-audit-report.json |
pip-audit | JSON |
trivy-report.json |
Trivy | JSON |
trivy-results.sarif |
Trivy | SARIF β GitHub Security tab |
zap-report.json |
OWASP ZAP | JSON |
coverage.xml |
pytest-cov | XML |
Never commit secrets. This pipeline uses:
- GitHub Secrets for
GITHUB_TOKEN(auto-provided), kubeconfig, registry credentials - Gitleaks to block secret commits at the PR gate
- Trivy to detect secrets baked into Docker images
Required secrets for full pipeline operation:
| Secret | Used By |
|---|---|
GITHUB_TOKEN |
Auto-provided β GHCR push, release creation |
KUBECONFIG |
kubectl deploy steps (add manually) |
MIT License β see LICENSE
Adarsh Singh β DevSecOps Engineer | Application Security | OT/ICS Security
"Security is not a feature β it's a pipeline gate."