DevSecOps & Secure SDLC — Deep Dive Training
DevSecOps & Secure SDLC — Deep Dive Training
CIPHER Training Module | Domain: Application Security, CI/CD Security, Supply Chain Integrity Last updated: 2026-03-14
Table of Contents
- Secure SDLC Framework
- SAST Tools — Static Application Security Testing
- DAST Tools — Dynamic Application Security Testing
- SCA Tools — Software Composition Analysis
- Tool Comparison Matrix
- CI/CD Pipeline Security Controls
- Secret Scanning Patterns
- Infrastructure as Code Security
- Supply Chain Security — SLSA, in-toto, Sigstore
- Secure Code Review Methodology
- Threat Modeling in SDLC
- OpenSSF Scorecard — Project Security Posture
- Implementation Playbook
1. Secure SDLC Framework
Phases and Security Activities
The OWASP DevSecOps Guideline defines security integration at every SDLC phase. The principle is shift-left: detect security issues by design as early as possible.
┌─────────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐
│ PRE-COMMIT │→ │ COMMIT │→ │ BUILD │→ │ TEST │→ │ DEPLOY │→ │ OPERATE │
│ │ │ │ │ │ │ │ │ │ │ │
│ Threat Model│ │ SAST │ │ SCA │ │ DAST │ │ IaC Scan │ │ RASP │
│ IDE Linting │ │ Secrets │ │ SBOM │ │ IAST │ │ Signing │ │ WAF │
│ Pre-commit │ │ Lint │ │ Container│ │ Pen Test │ │ Provenance│ │ Monitor │
│ Hooks │ │ License │ │ Scan │ │ Fuzzing │ │ Verify │ │ Vuln Mgmt│
└─────────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
Pre-Commit Phase
- Threat modeling using STRIDE/DREAD (OWASP Threat Dragon, Microsoft TMT)
- IDE security plugins — Semgrep LSP, Snyk IDE extensions, SonarLint
- Pre-commit hooks — Gitleaks for secret detection, linters for security anti-patterns
- Security requirements — Abuse cases alongside use cases, security user stories
Commit Phase
- SAST scanning on every PR (Semgrep, CodeQL, SonarQube)
- Secret scanning in diffs (Gitleaks pre-commit, TruffleHog in CI)
- License compliance checks on new dependencies
- Signed commits — GPG/SSH signatures, verified author identity
Build Phase
- SCA scanning — dependency vulnerability detection (Snyk, Trivy, OWASP Dependency-Check)
- SBOM generation — CycloneDX or SPDX format via Trivy, Syft
- Container image scanning — base image CVEs, misconfigurations (Trivy, Grype)
- Build provenance — SLSA attestation generation
Test Phase
- DAST scanning — runtime vulnerability detection (OWASP ZAP, Nuclei)
- IAST — instrumented runtime analysis (Contrast Security)
- API security testing — OpenAPI/Swagger spec scanning
- Fuzz testing — AFL, libFuzzer, OSS-Fuzz integration
Deploy Phase
- IaC scanning — Terraform/K8s/CloudFormation (Checkov, Trivy, tfsec)
- Artifact signing — Sigstore cosign, in-toto attestations
- Provenance verification — SLSA verification before deployment
- Admission control — OPA Gatekeeper, Kyverno policy enforcement
Operate Phase
- RASP — Runtime Application Self-Protection
- WAF — Web Application Firewall (ModSecurity, AWS WAF)
- Vulnerability management — continuous CVE monitoring of deployed dependencies
- Security monitoring — SIEM integration, anomaly detection, audit logging
2. SAST Tools — Static Application Security Testing
Semgrep
What it is: Lightweight, open-source static analysis tool using pattern-matching syntax that resembles real code. No need for compilation or build artifacts.
Key capabilities:
- 30+ language support: Python, JavaScript, Java, Go, Ruby, C/C++, C#, PHP, Rust, TypeScript, Kotlin, Scala, Swift, Terraform, Dockerfile, YAML
- Semantic pattern matching: Understands code structure, not just text —
$X == $Xfinds equality-with-self bugs - Taint tracking: Data-flow analysis tracing untrusted input to dangerous sinks
- Autofix: Automatic remediation suggestions in rule definitions
- 2,000+ community rules at semgrep.dev/explore; 20,000+ Pro rules
Installation and usage:
# Install
pip3 install semgrep
brew install semgrep
docker run semgrep/semgrep
# Scan with community rules
semgrep scan --config auto .
# Scan with specific rule
semgrep -e '$X == $X' --lang=py path/to/src
# CI mode — only reports new findings on PRs
semgrep ci
# Scan with a specific ruleset
semgrep --config p/owasp-top-ten .
semgrep --config p/python .
Rule anatomy (YAML):
rules:
- id: hardcoded-password
patterns:
- pattern: password = "..."
message: Hardcoded password detected
languages: [python]
severity: ERROR
metadata:
cwe: [CWE-798]
owasp: [A07:2021]
fix: password = os.environ.get("PASSWORD")
CI/CD integration: Native support for GitHub Actions, GitLab CI, CircleCI. PR-level scanning reports only newly introduced issues. Runs locally — code never uploaded in OSS mode.
Community vs Pro:
| Feature | Community (OSS) | Pro (AppSec Platform) |
|---|---|---|
| Analysis scope | Single file/function | Cross-file, cross-function |
| False positive rate | Higher | ~25% reduction |
| True positive rate | Baseline | ~250% increase |
| Rules | 2,000+ community | 20,000+ proprietary |
| Triage | Manual | AI-powered (Semgrep Assistant) |
Other SAST Tools
| Tool | Languages | Differentiator |
|---|---|---|
| CodeQL | 10+ (C/C++, C#, Go, Java, JS, Python, Ruby, Swift) | GitHub-native, query language for vulnerability research |
| SonarQube | 30+ | Quality + security, technical debt tracking |
| Bandit | Python only | Python-specific, fast, lightweight |
| Brakeman | Ruby/Rails only | Rails-specific, no config needed |
| gosec | Go only | Go-specific security rules |
3. DAST Tools — Dynamic Application Security Testing
OWASP ZAP (Zed Attack Proxy)
What it is: World's most widely used open-source web application security scanner. Maintained by Checkmarx under the OWASP umbrella. Licensed Apache 2.0.
Scanning modes:
- Passive scan: Observes HTTP traffic without modifying requests — identifies information disclosure, missing security headers, cookie flags
- Active scan: Sends crafted payloads to find injection flaws, XSS, SSRF, path traversal — destructive, use only in test environments
- Ajax Spider: Crawls JavaScript-heavy SPAs using a headless browser
- API scan: Import OpenAPI/Swagger/GraphQL specs for targeted API testing
Key features:
- Intercepting proxy for manual testing
- Automated scanning with configurable policies
- Authentication handling (form-based, token-based, OAuth)
- Script engine (JavaScript, Python, Zsh) for custom scan rules
- Community scripts: active scan, passive scan, authentication, fuzzer, payload generator
- SARIF/JSON/HTML/XML report generation
CI/CD integration:
# Docker baseline scan (passive only)
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-baseline.py \
-t https://target.example.com -r report.html
# Docker full scan (passive + active)
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-full-scan.py \
-t https://target.example.com -r report.html
# API scan with OpenAPI spec
docker run -t ghcr.io/zaproxy/zaproxy:stable zap-api-scan.py \
-t https://target.example.com/openapi.json -f openapi -r report.html
# Automation framework (YAML-driven)
docker run -t ghcr.io/zaproxy/zaproxy:stable zap.sh \
-cmd -autorun /zap/wrk/automation.yaml
ZAP Automation Framework (recommended for CI/CD):
env:
contexts:
- name: "target-app"
urls: ["https://target.example.com"]
authentication:
method: "form"
parameters:
loginUrl: "https://target.example.com/login"
loginRequestData: "user={%username%}&pass={%password%}"
jobs:
- type: spider
parameters:
maxDuration: 5
- type: passiveScan-wait
- type: activeScan
- type: report
parameters:
template: "sarif-json"
reportFile: "zap-report.sarif"
DAST Tool Comparison
| Tool | Type | Strengths | CI/CD Ready |
|---|---|---|---|
| OWASP ZAP | Proxy-based | Free, extensible, API scanning | Yes (Docker) |
| Nuclei | Template-based | Fast, 8000+ templates, network+web | Yes (binary) |
| Burp Suite | Proxy-based | Gold standard for manual testing | Enterprise only |
| OWASP Amass | Recon | Subdomain enumeration, not a scanner | Yes |
| Nikto | CGI scanner | Legacy web server checks | Yes |
4. SCA Tools — Software Composition Analysis
Trivy (Aqua Security)
What it is: All-in-one security scanner — vulnerabilities, misconfigurations, secrets, licenses, and SBOM generation. Apache 2.0 licensed, written in Go.
Scan targets:
- Container images (Docker, OCI)
- Filesystems and repositories
- Kubernetes clusters and workloads
- Virtual machine images
- SBOM files (CycloneDX, SPDX)
Scanner types:
| Scanner | Detects |
|---|---|
| Vulnerability | CVEs in OS packages and language dependencies |
| Misconfiguration | IaC issues in Terraform, K8s, Dockerfile, CloudFormation |
| Secret | API keys, passwords, tokens in code and images |
| License | Software license identification and compliance |
| SBOM | Bill of materials generation (CycloneDX, SPDX) |
Usage:
# Install
brew install trivy
apt-get install trivy
# Scan container image
trivy image python:3.12-alpine
trivy image --severity HIGH,CRITICAL myapp:latest
# Scan filesystem
trivy fs --scanners vuln,secret,misconfig .
# Scan git repository
trivy repo https://github.com/org/project
# Scan Kubernetes cluster
trivy k8s --report summary cluster
# Generate SBOM
trivy image --format cyclonedx -o sbom.json myapp:latest
# Scan IaC
trivy config ./terraform/
# CI mode — exit code 1 on findings
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest
Snyk CLI
What it is: Commercial SCA tool with generous free tier. Scans open source dependencies, application code, containers, and IaC from a single CLI.
Core commands:
# Scan dependencies
snyk test
# Scan source code (SAST)
snyk code test
# Scan container image
snyk container test myapp:latest
# Scan IaC files
snyk iac test ./terraform/
# Monitor (continuous alerting)
snyk monitor
Key differentiator: Unified scanning across deps, code, containers, and IaC. Curated vulnerability database with remediation advice. Fix PRs auto-generated.
OWASP Dependency-Check
What it is: Free SCA tool focusing on known vulnerability identification in project dependencies using NVD data.
# CLI scan
dependency-check --project "MyApp" --scan ./lib --format HTML
# Maven plugin
mvn org.owasp:dependency-check-maven:check
Dependency Management Best Practices
From the OWASP Vulnerable Dependency Management Cheat Sheet:
Remediation decision tree:
| Scenario | Action |
|---|---|
| Patch available | Update dependency, run tests, deploy |
| Fix delayed | Wrap vulnerable function, add input validation, deploy WAF rule |
| No fix expected | Evaluate alternatives, self-patch based on CVE details, add defensive tests |
| Undisclosed vuln | Report via responsible disclosure, apply Case 2 or 3 mitigation |
Critical rules:
- Pin versions using lock files (
package-lock.json,Pipfile.lock,poetry.lock,go.sum) - Verify package integrity with cryptographic hashes
- Never directly patch transitive dependencies — update the first-level dep instead
- Implement SCA from project inception, not mid-cycle
- CVSS scores guide prioritization but business context determines actual risk
- Use scoped packages (npm
@scope/package) to prevent namespace confusion - Configure single private registry feed to prevent dependency confusion attacks
- Risk acceptance requires CISO sign-off with documented technical analysis
5. Tool Comparison Matrix
SAST Comparison
| Criterion | Semgrep | CodeQL | SonarQube |
|---|---|---|---|
| Languages | 30+ | 10+ | 30+ |
| Rule authoring | Code-like YAML | QL (query language) | Java-based |
| Learning curve | Low | High | Medium |
| CI integration | Native | GitHub-native | Plugin-based |
| Cross-file analysis | Pro only | Yes | Yes |
| Taint tracking | Yes | Yes | Yes |
| Self-hosted | Yes | Yes | Yes |
| Price | Free OSS / Paid Pro | Free for public repos | Free Community / Paid |
| Speed | Very fast | Slow (needs CodeQL DB) | Medium |
| False positives | Medium (Low in Pro) | Low | Medium |
DAST Comparison
| Criterion | OWASP ZAP | Nuclei | Burp Suite Pro |
|---|---|---|---|
| Cost | Free | Free | ~$449/yr |
| API scanning | OpenAPI/GraphQL | Template-based | Yes |
| Authentication | Form/Token/OAuth | Header injection | Full support |
| CI/CD | Docker, Automation FW | Binary, GitHub Action | Enterprise only |
| Extensibility | Scripts (JS/Python) | YAML templates | BApp Store + Java |
| Manual testing | Proxy + GUI | CLI only | Best-in-class GUI |
| Speed | Moderate | Very fast | Moderate |
SCA Comparison
| Criterion | Trivy | Snyk | Dep-Check | Grype |
|---|---|---|---|---|
| Cost | Free | Freemium | Free | Free |
| Vuln DB | NVD + multiple | Snyk Intel DB | NVD | Grype DB |
| Container scan | Yes | Yes | No | Yes |
| IaC scan | Yes | Yes | No | No |
| Secret scan | Yes | No | No | No |
| SBOM | Generate + scan | Limited | No | Consume |
| License scan | Yes | Yes | No | No |
| Fix suggestions | No | Yes (auto PRs) | No | No |
| Speed | Fast | Medium | Slow | Fast |
Secret Scanner Comparison
| Criterion | Gitleaks | TruffleHog | Trivy (secrets) |
|---|---|---|---|
| Detection | Regex + entropy | Regex + entropy + verification | Regex |
| Live verification | No | Yes (800+ detectors) | No |
| Pre-commit hook | Native | Via wrapper | No |
| Git history scan | Yes | Yes | No |
| Cloud sources | No | S3, GCS, Docker, CI systems | Container images |
| Custom rules | TOML config | Yes | Limited |
| CI integration | GitHub Action | Multiple | GitHub Action |
IaC Scanner Comparison
| Criterion | Checkov | Trivy (misconfig) | tfsec (deprecated) |
|---|---|---|---|
| Terraform | Yes | Yes | Yes |
| CloudFormation | Yes | Yes | No |
| Kubernetes | Yes | Yes | No |
| Dockerfile | Yes | Yes | No |
| Helm | Yes | Yes | No |
| CI/CD configs | Yes (GHA, GitLab) | No | No |
| Custom policies | Python + YAML | Rego | Rego |
| Built-in checks | 1000+ | Growing | 100+ |
| Status | Active | Active | Deprecated → Trivy |
6. CI/CD Pipeline Security Controls
OWASP Top 10 CI/CD Security Risks
Based on the OWASP CI/CD Security Cheat Sheet:
| # | Risk | Description | Mitigation |
|---|---|---|---|
| 1 | Insufficient Flow Control | No approval gates, bypassed reviews | Require PR review + approval before merge; enforce branch protection |
| 2 | Inadequate IAM | Over-privileged identities, shared accounts | Centralized IdP, MFA, least privilege, regular access audits |
| 3 | Dependency Chain Abuse | Dependency confusion, typosquatting, package takeover | Pin versions by digest, verify hashes, use private registries, scoped packages |
| 4 | Poisoned Pipeline Execution (PPE) | Injecting malicious code into pipeline definitions | Version-control pipeline configs, restrict who can modify CI YAML |
| 5 | Insufficient PBAC | Over-privileged pipeline permissions | Scope pipeline secrets to specific services/ops, isolate by sensitivity |
| 6 | Inadequate Credential Hygiene | Hardcoded secrets, secrets in logs | Vault-based secrets, rotate frequently, mask in output, use ephemeral creds |
| 7 | Insecure System Configuration | Misconfigured CI/CD platform | Harden runners, enforce TLS 1.2+, restrict network access, audit configs |
| 8 | Ungoverned Third-Party Services | Unvetted plugins and integrations | Vet plugins for reputation/security, maintain plugin inventory, review periodically |
| 9 | Improper Artifact Integrity | Unsigned/unverified build outputs | Sign artifacts with Sigstore, verify provenance, implement SLSA |
| 10 | Insufficient Logging | No visibility into pipeline activity | SIEM integration, structured logging, alert on anomalies, never log secrets |
Pipeline Security Architecture
┌─────────────────────────────────────────────────┐
│ SECURITY GATES │
│ │
┌──────┐ ┌──────┴──────┐ ┌───────────┐ ┌──────────┐ ┌────────┐│
│ Code │→ │ Pre-Commit │→ │ Build │→ │ Test │→ │ Deploy ││
│ │ │ │ │ │ │ │ │ ││
│ │ │ • Gitleaks │ │ • SAST │ │ • DAST │ │ • Sign ││
│ │ │ • Lint │ │ • SCA │ │ • IAST │ │ • SLSA ││
│ │ │ • Format │ │ • License │ │ • Fuzz │ │ • IaC ││
│ │ │ • Semgrep │ │ • SBOM │ │ • Pentest│ │ • OPA ││
└──────┘ └─────────────┘ └───────────┘ └──────────┘ └────────┘│
│ │
│ BREAK BUILD on: Critical/High vulns │
│ WARN on: Medium vulns, new dependencies │
│ BLOCK DEPLOY on: Failed IaC scan, no signing │
└─────────────────────────────────────────────────┘
Source Code Management Hardening
- Branch protection: Require PR reviews before merge; block force push to main
- Signed commits: Require GPG/SSH commit signatures; verify authorship
- CODEOWNERS: Require security team approval for sensitive paths (auth/, crypto/, CI configs)
- Restrict visibility: Prevent accidental public repo exposure
- Disable auto-merge: Require human approval before merge completes
- Limit external contributors: Separate fork-based CI from trusted CI
Pipeline Execution Hardening
# GitHub Actions — hardened workflow example
name: Secure CI
on:
pull_request:
branches: [main]
permissions:
contents: read # Least privilege — explicitly declare
security-events: write
jobs:
security-scan:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for secret scanning
# Secret scanning
- name: Gitleaks
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# SAST
- name: Semgrep
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/python
# SCA + Container scan
- name: Trivy
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scanners: 'vuln,secret,misconfig'
severity: 'HIGH,CRITICAL'
exit-code: '1'
# IaC scan
- name: Checkov
uses: bridgecrewio/checkov-action@v12
with:
directory: ./terraform
soft_fail: false
Secrets Management in CI/CD
Rules:
- Never hardcode credentials in repos, config files, or compiled artifacts
- Use dedicated vault solutions (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault)
- Use ephemeral/short-lived credentials wherever possible (OIDC federation for cloud providers)
- Mask secrets in CI output — secrets must never appear in logs
- Scope secrets to specific jobs/environments — no global secrets
- Rotate secrets on schedule and immediately on suspected compromise
- Monitor secret access patterns for anomalies
GitHub Actions OIDC federation (eliminates long-lived cloud credentials):
permissions:
id-token: write
contents: read
steps:
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-arn: arn:aws:iam::123456789:role/github-actions
aws-region: us-east-1
IAM for CI/CD
- Use centralized identity providers — no local CI/CD accounts
- Prohibit shared accounts and self-provisioned identities
- Enforce MFA for all human access to CI/CD platforms
- Maintain identity inventory: owner, provider, last usage, granted vs. actual permissions
- Run pipeline jobs with non-root, least-privilege service accounts
- Regularly audit and deprovision unused identities
7. Secret Scanning Patterns
TruffleHog
What it is: Credential discovery platform that finds, classifies, and verifies leaked secrets. Supports 800+ secret types with live validation.
Detection methods:
- Regex pattern matching — known credential formats (AWS keys, GitHub tokens, etc.)
- Entropy analysis — high-entropy strings that may be secrets
- Live verification — attempts authentication to confirm secret is active
The verification step is critical: it distinguishes between active dangers and revoked/test credentials.
Usage:
# Install
brew install trufflehog
docker run trufflesecurity/trufflehog:latest
# Scan git repository
trufflehog git https://github.com/org/repo
# Scan GitHub org
trufflehog github --org=myorg
# Scan filesystem
trufflehog filesystem /path/to/code
# Scan S3 bucket
trufflehog s3 --bucket=my-bucket
# Scan Docker image
trufflehog docker --image=myapp:latest
# CI mode — fail on verified secrets (exit code 183)
trufflehog git https://github.com/org/repo --since-commit=HEAD~1 --fail
Supported sources: Git repos, GitHub orgs, GitLab, S3, GCS, Docker images, filesystems, Jenkins, Elasticsearch, Postman collections.
Gitleaks
What it is: Regex-based secret scanner for git repos, files, and stdin. Focused on speed and simplicity.
Usage:
# Install
brew install gitleaks
# Scan git history
gitleaks git -v
# Scan directory
gitleaks dir -v
# Scan stdin
echo "AKIAIOSFODNN7EXAMPLE" | gitleaks stdin
# Generate baseline (ignore existing findings)
gitleaks git --baseline-path gitleaks-report.json --report-path new-findings.json
# Output formats
gitleaks git -f json -r report.json
gitleaks git -f sarif -r report.sarif
Pre-commit hook setup:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.21.0
hooks:
- id: gitleaks
Custom rules (.gitleaks.toml):
[extend]
# Extend default rules
useDefault = true
[[rules]]
id = "custom-api-key"
description = "Custom API key pattern"
regex = '''(?i)my_service_api_key\s*=\s*['"]([a-zA-Z0-9]{32,})['"]'''
entropy = 3.5
secretGroup = 1
[rules.allowlist]
paths = ['''test/''', '''\.example$''']
[[allowlist.paths]]
# Global path ignores
paths = ['''vendor/''', '''node_modules/''']
Secret Scanning Strategy
Layer defense in depth:
| Layer | Tool | When | What |
|---|---|---|---|
| Developer workstation | Gitleaks pre-commit | Before commit | Prevents secrets from entering history |
| Pull request | TruffleHog in CI | On PR | Catches what pre-commit missed, verifies liveness |
| Scheduled scan | TruffleHog full scan | Nightly/weekly | Scans entire history, cloud sources |
| Container images | Trivy | Build time | Secrets baked into images |
| Runtime | AWS Macie / GCP DLP | Continuous | Secrets in cloud storage, logs |
Common secret patterns to detect:
# AWS
AKIA[0-9A-Z]{16} # AWS Access Key ID
[0-9a-zA-Z/+]{40} # AWS Secret Access Key
# GitHub
gh[pousr]_[A-Za-z0-9_]{36,} # GitHub tokens (PAT, OAuth, etc.)
# Generic
(?i)(password|passwd|pwd)\s*[:=]\s*.+ # Password assignments
(?i)(api[_-]?key|apikey)\s*[:=]\s*.+ # API key assignments
(?i)(secret|token)\s*[:=]\s*['"][^'"]+ # Secret/token assignments
# Private keys
-----BEGIN (RSA |EC |DSA )?PRIVATE KEY----- # PEM private keys
# Database connection strings
(?i)(postgres|mysql|mongodb)://[^:]+:[^@]+@ # DB URIs with credentials
Remediation when secrets are found:
- Immediately rotate the exposed credential — do not wait for the PR to merge
- Revoke the old credential in the service provider
- Remove from git history using
git-filter-repo(notgit filter-branch) - Scan again to confirm removal
- Investigate access logs for the exposed credential period
- Add the pattern to your
.gitleaks.tomlallowlist only if it is a false positive
8. Infrastructure as Code Security
Checkov (Prisma Cloud)
What it is: Static analysis tool for IaC with 1000+ built-in policies covering AWS, Azure, and GCP. Supports graph-based scanning for context-aware analysis.
Supported frameworks:
- IaC: Terraform, Terraform Plan, CloudFormation, AWS SAM, Kubernetes, Helm, Kustomize, Dockerfile, Serverless, Bicep, OpenAPI, ARM, OpenTofu
- CI/CD configs: GitHub Actions, GitLab CI, Azure Pipelines, Argo Workflows, BitBucket Pipelines, CircleCI
Usage:
# Install
pip3 install checkov
brew install checkov
# Scan Terraform directory
checkov -d ./terraform/
# Scan specific file
checkov -f main.tf
# Run specific checks
checkov -d . --check CKV_AWS_20,CKV_AWS_57
# Scan Kubernetes manifests
checkov -d ./k8s/
# Scan Dockerfile
checkov -f Dockerfile
# Scan container image
checkov --image myapp:latest --dockerfile-path ./Dockerfile
# Output SARIF for CI integration
checkov -d . -o sarif > results.sarif
# Scan with severity threshold
checkov -d . --check-severity HIGH
Inline suppression:
# Terraform
resource "aws_s3_bucket" "data" {
bucket = "my-bucket"
#checkov:skip=CKV_AWS_18:Access logging not needed for this bucket
}
# Kubernetes
metadata:
annotations:
checkov.io/skip1: "CKV_K8S_20=Service mesh handles this"
Custom policy (Python):
from checkov.common.models.enums import CheckResult, CheckCategories
from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
class S3BucketEncryption(BaseResourceCheck):
def __init__(self):
name = "Ensure S3 bucket has server-side encryption"
id = "CKV_CUSTOM_1"
supported_resources = ['aws_s3_bucket']
categories = [CheckCategories.ENCRYPTION]
super().__init__(name=name, id=id,
categories=categories,
supported_resources=supported_resources)
def scan_resource_conf(self, conf):
if 'server_side_encryption_configuration' in conf:
return CheckResult.PASSED
return CheckResult.FAILED
check = S3BucketEncryption()
Trivy IaC Scanning
# Scan Terraform
trivy config ./terraform/
# Scan Kubernetes manifests
trivy config ./k8s/
# Scan with specific severity
trivy config --severity HIGH,CRITICAL ./terraform/
# Output as JSON
trivy config -f json -o results.json ./terraform/
tfsec (Deprecated — Migrate to Trivy)
tfsec has been absorbed into Trivy's misconfiguration scanner. Key features now available in Trivy:
- HCL expression evaluation
- Terraform function support (
concat(), etc.) - Module scanning (local and remote)
.tfvarsfile evaluation- Multi-cloud provider checks (AWS, Azure, GCP, K8s, etc.)
Migration: Replace tfsec . with trivy config . in CI pipelines.
Critical IaC Security Rules
AWS — Top violations:
| Check ID | Rule | Severity |
|---|---|---|
| CKV_AWS_18 | S3 bucket access logging enabled | Medium |
| CKV_AWS_19 | S3 bucket encryption enabled | High |
| CKV_AWS_20 | S3 bucket not publicly accessible | Critical |
| CKV_AWS_23 | Security group no unrestricted ingress | High |
| CKV_AWS_24 | Security group no unrestricted SSH | Critical |
| CKV_AWS_41 | RDS encryption enabled | High |
| CKV_AWS_145 | RDS instance not publicly accessible | Critical |
Kubernetes — Top violations:
| Check ID | Rule | Severity |
|---|---|---|
| CKV_K8S_1 | Do not allow privileged containers | Critical |
| CKV_K8S_8 | Limit container CPU | Medium |
| CKV_K8S_9 | Limit container memory | Medium |
| CKV_K8S_20 | Do not run as root | High |
| CKV_K8S_22 | Use read-only filesystem | Medium |
| CKV_K8S_28 | No host network | High |
| CKV_K8S_37 | No capability additions | High |
Dockerfile — Top violations:
| Check ID | Rule | Severity |
|---|---|---|
| CKV_DOCKER_1 | Do not use USER root |
High |
| CKV_DOCKER_2 | Healthcheck instruction present | Low |
| CKV_DOCKER_3 | Do not use ADD (use COPY) |
Medium |
| CKV_DOCKER_7 | Pin base image by digest | High |
| CKV_DOCKER_8 | Do not use latest tag |
Medium |
9. Supply Chain Security — SLSA, in-toto, Sigstore
SLSA Framework (Supply-chain Levels for Software Artifacts)
SLSA (pronounced "salsa") is a specification defining increasing levels of supply chain integrity guarantees. Current version: 1.0 (retired; v1.2 current).
Build Track Levels
| Level | Name | Requirements | Guarantees |
|---|---|---|---|
| L0 | No guarantees | None | Baseline — no protections |
| L1 | Provenance exists | Documented build process; provenance describing how artifact was built (platform, process, inputs); provenance distributed to consumers | Prevents unintentional mistakes; enables debugging and inventory |
| L2 | Hosted build platform | L1 + builds run on hosted platform that generates and signs provenance; consumers validate authenticity | Prevents post-build tampering; deters unsophisticated adversaries |
| L3 | Hardened builds | L2 + strong isolation between builds; signing material inaccessible to user-defined steps | Prevents tampering during builds (insider threats, compromised creds); intended as standard for most releases |
SLSA Threat Model
Source threats (future SLSA scope):
- Unauthorized code changes via version control
- Compromise of source repository infrastructure
- Building from modified/unofficial sources
Build threats (core SLSA focus):
- (E) Compromise build process — tamper with output or forge provenance
- (F) Upload modified package — distribute artifacts built outside trusted CI
- (G) Compromise package registry — exploit distribution infrastructure
- (H) Use compromised package — typosquatting, post-registry tampering
Dependency threats:
- Compromised build/runtime dependencies
- Mitigation: pin dependencies by digest, apply SLSA recursively
Level-specific mitigations:
| Threat | L1 | L2 | L3 |
|---|---|---|---|
| Tamper with artifact post-build | Hash verification | Yes | Yes |
| Forge provenance | — | Cryptographic signatures | Yes |
| Forge provenance values | — | Control plane generation | Hardened isolation |
| Compromise other builds | — | — | Mandatory isolation |
| Steal signing secrets | — | — | Control plane access only |
| Poison build cache | — | — | Per-build isolation |
Implementing SLSA
GitHub Actions SLSA provenance generator:
# .github/workflows/slsa-provenance.yml
name: SLSA Provenance
on:
release:
types: [created]
jobs:
build:
outputs:
digest: ${{ steps.hash.outputs.digest }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make build
- name: Generate digest
id: hash
run: echo "digest=$(sha256sum artifact.tar.gz | cut -d' ' -f1)" >> $GITHUB_OUTPUT
- uses: actions/upload-artifact@v4
with:
name: artifact
path: artifact.tar.gz
provenance:
needs: build
permissions:
actions: read
id-token: write
contents: write
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.0.0
with:
base64-subjects: ${{ needs.build.outputs.digest }}
in-toto (Supply Chain Integrity Framework)
What it is: Python framework that protects software supply chain integrity by verifying that each task is performed by authorized personnel and products remain unmodified.
Core concepts:
- Layout: Signed document defining the supply chain — expiration, steps, authorized functionaries, artifact rules, inspection commands
- Link metadata: Signed record of each step execution — commands run, materials consumed, products created
- Functionaries: Authorized individuals/systems that execute steps and sign their work
How it works:
1. Project owner creates signed LAYOUT
├── Defines steps: code → build → test → package
├── Assigns functionaries to each step
└── Specifies artifact rules (CREATE, MODIFY, MATCH, etc.)
2. Functionaries execute steps
├── in-toto-run: wraps command, captures materials + products
└── Generates signed LINK metadata
3. Verifier runs in-toto-verify
├── Validates layout signature and expiration
├── Confirms each step by correct functionary
├── Verifies artifact rules compliance
└── Runs inspection commands
Artifact rules: CREATE, DELETE, MODIFY, ALLOW, DISALLOW, REQUIRE, MATCH — ensures only authorized artifacts are created, modified, or deleted.
Usage:
pip install in-toto
# Record a build step
in-toto-run --step-name build --products build/output.bin -- make build
# Record with explicit key
in-toto-run --step-name build --key developer.pem -- make build
# Verify the supply chain
in-toto-verify --layout root.layout --layout-key owner.pub
Sigstore (Keyless Signing)
What it is: Ecosystem for signing, verifying, and protecting software. Eliminates the need for long-lived signing keys.
Components:
- Cosign: Container image and blob signing/verification
- Fulcio: Certificate authority issuing short-lived certificates tied to OIDC identity
- Rekor: Immutable transparency log recording signing events
Usage:
# Install cosign
brew install cosign
# Sign a container image (keyless — uses OIDC)
cosign sign myregistry.io/myapp:latest
# Verify a container image
cosign verify myregistry.io/myapp:latest \
--certificate-identity=user@example.com \
--certificate-oidc-issuer=https://accounts.google.com
# Sign a blob
cosign sign-blob --output-signature sig.txt artifact.tar.gz
# Verify a blob
cosign verify-blob --signature sig.txt artifact.tar.gz \
--certificate-identity=user@example.com \
--certificate-oidc-issuer=https://accounts.google.com
# Attach SBOM to image
cosign attach sbom --sbom sbom.json myregistry.io/myapp:latest
# Verify SLSA provenance
cosign verify-attestation myregistry.io/myapp:latest \
--type slsaprovenance \
--certificate-identity-regexp='.*' \
--certificate-oidc-issuer-regexp='.*'
Supply Chain Security Integration
┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐
│ Source │ │ Build │ │ Publish │ │ Deploy │
│ │ │ │ │ │ │ │
│ Signed │───→│ SLSA L3 │───→│ Cosign │───→│ Verify │
│ Commits │ │ Provenance │ │ Sign Image │ │ Provenance │
│ │ │ in-toto │ │ Attach SBOM│ │ + Signature│
│ Branch │ │ Links │ │ Rekor Log │ │ OPA Policy │
│ Protection │ │ Isolated │ │ │ │ Admission │
└────────────┘ └────────────┘ └────────────┘ └────────────┘
10. Secure Code Review Methodology
Review Checklist by Vulnerability Class
Injection (CWE-89, CWE-78, CWE-79)
- All user input parameterized in database queries (no string concatenation)
- OS command execution uses safe APIs with argument arrays (not shell=True)
- HTML output context-encoded (HTML entities, JS string escaping, URL encoding)
- Template engines use auto-escaping; manual
|safe/mark_safeaudited - LDAP, XPath, XML queries use parameterized interfaces
Authentication & Session (CWE-287, CWE-384)
- Password hashing uses bcrypt/scrypt/argon2 with appropriate cost factor
- No plaintext password storage or reversible encryption
- Session tokens cryptographically random, regenerated on login
- Failed login handling: constant-time comparison, no user enumeration
- MFA implementation reviewed for bypass vectors
- Token expiration and revocation implemented
Authorization (CWE-862, CWE-863)
- Every endpoint enforces authorization (not just authentication)
- IDOR checks: user can only access their own resources
- Role/permission checks at service layer, not just UI
- Horizontal privilege escalation tested (user A accessing user B data)
- Vertical privilege escalation tested (user elevating to admin)
- Default deny: new endpoints require explicit authorization
Cryptography (CWE-327, CWE-330)
- No custom crypto implementations — use vetted libraries
- TLS 1.2+ enforced; weak ciphers disabled
- Keys/IVs generated from CSPRNG (not
random.random()) - Encryption at rest for sensitive data (AES-256-GCM recommended)
- No ECB mode; prefer authenticated encryption (GCM, ChaCha20-Poly1305)
- Key rotation mechanism exists and is tested
Data Exposure (CWE-200, CWE-532)
- Sensitive data not logged (passwords, tokens, PII, PHI)
- Error messages do not leak stack traces, SQL queries, or internal paths
- API responses do not include unnecessary fields (over-fetching)
- Debug/verbose modes disabled in production
- Sensitive data masked in application logs
Deserialization (CWE-502)
- No deserialization of untrusted data (pickle, Java ObjectInputStream, PHP unserialize)
- If unavoidable: type allowlisting, integrity verification, isolated environment
- JSON preferred over binary serialization formats
SSRF (CWE-918)
- User-supplied URLs validated against allowlist of domains/IPs
- Internal/private IP ranges blocked (127.0.0.0/8, 10.0.0.0/8, 169.254.169.254, etc.)
- DNS rebinding mitigated (resolve then validate, not validate then resolve)
- Redirect following disabled or limited
File Operations (CWE-22, CWE-434)
- File paths canonicalized and validated against base directory
- File upload: content-type validated server-side, filename sanitized, stored outside webroot
- No user-controlled file paths in
open(),include(),require() - Uploaded files scanned for malware
Secure Code Review Process
1. UNDERSTAND — Read design doc / threat model; identify trust boundaries
2. MAP — Identify entry points (APIs, message queues, file uploads)
3. TRACE — Follow data from source (user input) to sink (database, OS, output)
4. CHECK — Apply vulnerability checklist at each trust boundary crossing
5. VERIFY — Confirm mitigations are correctly implemented, not just present
6. DOCUMENT — File findings with severity, location, proof, remediation
What to prioritize:
- Authentication and authorization changes
- Crypto implementation changes
- Input handling at trust boundaries
- New dependencies (check for known vulns)
- Changes to CI/CD configuration
- Infrastructure as code changes
- Anything touching secrets or credentials
Semgrep Rules for Code Review
# Run targeted rulesets during review
semgrep --config p/owasp-top-ten . # OWASP Top 10
semgrep --config p/python . # Python security
semgrep --config p/javascript . # JavaScript security
semgrep --config p/secrets . # Hardcoded secrets
semgrep --config p/insecure-transport . # HTTP/plaintext usage
semgrep --config p/command-injection . # Command injection
semgrep --config p/sql-injection . # SQL injection
11. Threat Modeling in SDLC
OWASP Threat Dragon
What it is: Free, open-source, cross-platform threat modeling application. Supports data flow diagrams with associated threats and mitigations.
Features:
- Visual data flow diagram editor
- Threat suggestion engine
- Mitigation and countermeasure documentation
- Repository integration (GitHub, GitLab, Bitbucket)
- Desktop (Windows, macOS, Linux) and web versions
- Aligned with the Threat Modeling Manifesto
Installation:
# Docker
docker run -p 3000:3000 owasp/threat-dragon:latest
# Desktop — download from GitHub releases
# Web — available at threatdragon.com
Threat Modeling Methodology
When to threat model:
- At design phase (before writing code)
- When architecture changes significantly
- When new trust boundaries are introduced
- Before major releases
- When integrating new third-party services
STRIDE per element:
| Threat | Applies to | Question |
|---|---|---|
| Spoofing | External entities, processes | Can an attacker impersonate a user or service? |
| Tampering | Data stores, data flows | Can data be modified in transit or at rest? |
| Repudiation | External entities, processes | Can actions be denied without proof? |
| Information Disclosure | Data stores, data flows | Can sensitive data leak? |
| Denial of Service | Processes, data stores | Can availability be impacted? |
| Elevation of Privilege | Processes | Can an attacker gain higher permissions? |
Output: Data flow diagram with trust boundaries, STRIDE table per component, DREAD scores per threat, mitigations with owners and status.
12. OpenSSF Scorecard — Project Security Posture
What it is: Automated tool that evaluates open-source project security across 17+ dimensions, scoring 0-10 per check.
Security checks performed:
| Check | What it evaluates |
|---|---|
| Branch-Protection | Code review requirements, protection policies |
| Binary-Artifacts | Unverified binaries in repo |
| Code-Review | Mandatory review procedures |
| CI-Tests | Automated testing infrastructure |
| Dependency-Update-Tool | Dependabot/Renovate configured |
| SAST | Static analysis in CI |
| Fuzzing | OSS-Fuzz participation |
| Signed-Releases | Release signature verification |
| Token-Permissions | GitHub workflow token access scoping |
| Vulnerabilities | Known CVEs in dependencies |
| CII-Best-Practices | Best practices badge |
| Maintained | Recent commit activity |
| Security-Policy | SECURITY.md presence |
| Contributors | Organizational diversity |
| License | License file present |
| Pinned-Dependencies | Dependencies pinned by hash |
| Dangerous-Workflow | Unsafe patterns in CI (pull_request_target) |
Usage:
# Install
brew install scorecard
docker pull ghcr.io/ossf/scorecard:latest
# Scan a repository
scorecard --repo=github.com/org/project
# Environment variable for auth
export GITHUB_AUTH_TOKEN=ghp_xxxx
scorecard --repo=github.com/org/project
# GitHub Action integration
# Uses: ossf/scorecard-action@v2
CI integration (GitHub Actions):
name: Scorecard
on:
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6 AM
push:
branches: [main]
permissions:
security-events: write
id-token: write
jobs:
analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ossf/scorecard-action@v2
with:
results_file: results.sarif
publish_results: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
Use scorecard to:
- Evaluate dependencies before adoption
- Monitor your own project's security posture
- Enforce minimum scores via CI gates
- Generate security badges for README
13. Implementation Playbook
Phase 1 — Foundation (Week 1-2)
Goal: Basic secret scanning and dependency checks.
| Action | Tool | Effort |
|---|---|---|
| Pre-commit secret scanning | Gitleaks | 1 hour |
| CI secret scanning | TruffleHog | 2 hours |
| Dependency scanning in CI | Trivy fs | 2 hours |
| Branch protection rules | GitHub/GitLab | 1 hour |
| Signed commits policy | GPG/SSH | 2 hours |
Phase 2 — SAST & IaC (Week 3-4)
Goal: Static analysis and infrastructure security.
| Action | Tool | Effort |
|---|---|---|
| SAST in CI | Semgrep | 2 hours |
| IaC scanning | Checkov or Trivy config | 2 hours |
| Container image scanning | Trivy image | 2 hours |
| SBOM generation | Trivy / Syft | 1 hour |
| Security gate (break build on Critical) | CI config | 2 hours |
Phase 3 — DAST & Supply Chain (Week 5-8)
Goal: Runtime testing and artifact integrity.
| Action | Tool | Effort |
|---|---|---|
| DAST baseline scan | OWASP ZAP | 4 hours |
| API security testing | ZAP API scan | 4 hours |
| Artifact signing | Cosign (Sigstore) | 4 hours |
| SLSA L1 provenance | slsa-github-generator | 4 hours |
| OpenSSF Scorecard monitoring | Scorecard Action | 1 hour |
Phase 4 — Maturity (Week 9-12)
Goal: Advanced controls, threat modeling, hardened pipelines.
| Action | Tool | Effort |
|---|---|---|
| Threat modeling for critical services | Threat Dragon | 8 hours |
| SLSA L3 hardened builds | Isolated runners | 8 hours |
| In-toto supply chain verification | in-toto | 8 hours |
| Custom Semgrep rules for org patterns | Semgrep | 4 hours |
| Pipeline security audit | Manual + Scorecard | 4 hours |
| DAST with authentication | ZAP Automation FW | 8 hours |
| Admission control (K8s) | OPA Gatekeeper / Kyverno | 8 hours |
Metrics to Track
| Metric | Target | Source |
|---|---|---|
| Mean time to remediate Critical CVE | < 48 hours | SCA tool |
| SAST findings per 1000 LOC | Trending down | Semgrep dashboard |
| Secret leak incidents | Zero | TruffleHog / Gitleaks |
| SLSA level achieved | L3 | Provenance verification |
| OpenSSF Scorecard score | > 7.0 | Scorecard |
| IaC violations in production | Zero Critical | Checkov |
| DAST findings per release | Trending down | ZAP reports |
| Dependencies with known Critical CVEs | Zero | Trivy / Snyk |
References
- OWASP DevSecOps Guideline
- OWASP CI/CD Security Cheat Sheet
- OWASP Vulnerable Dependency Management Cheat Sheet
- SLSA Specification v1.0
- Semgrep — SAST
- OWASP ZAP — DAST
- Trivy — Multi-scanner
- TruffleHog — Secret scanning
- Gitleaks — Secret scanning
- Checkov — IaC security
- in-toto — Supply chain integrity
- Sigstore / Cosign — Keyless signing
- OpenSSF Scorecard — Project security scoring
- Snyk CLI — SCA and code scanning
- OWASP Threat Dragon — Threat modeling