DevSecOps Fundamentals
- DevSecOps Fundamentals
Security as everyone’s job, at every stage
DevSecOps integrates security practices into every phase of the DevOps pipeline — planning, coding, building, testing, releasing, deploying, operating, and monitoring. Rather than treating security as a gate at the end of development, DevSecOps embeds it continuously throughout the software delivery lifecycle.
ℹ️ DevSecOps is the connective tissue for much of this course: it’s where threat modeling, application-security testing, and vulnerability management actually run. The shift is as much cultural as technical — security becomes a shared responsibility, automated into the pipeline rather than owned by a separate team at the end.
What is DevSecOps?
DevSecOps (Development, Security, Operations) extends the DevOps philosophy of collaboration and automation to include security as a shared responsibility across every team and every stage of the pipeline. The core shift is cultural: security is not the sole responsibility of a security team — developers write secure code, operations enforces secure configuration, and automated tooling prevents regressions.
DevSecOps vs DevOps
| Aspect | DevOps | DevSecOps |
|---|---|---|
| Primary goals | Speed, reliability, collaboration | Speed, reliability, collaboration, and security |
| Security timing | End-of-pipeline scan or separate audit | Embedded at every stage |
| Security ownership | Security team | Shared across Dev, Sec, Ops |
| Vulnerability discovery | Late (pre-release or post-release) | Early (commit, build, PR review) |
| Compliance | Manual audit cycles | Continuous compliance validation |
| Tools added | CI/CD, monitoring, IaC | + SAST, DAST, SCA, secrets scanning, policy-as-code |
The OWASP DevSecOps Guideline and the NIST Secure Software Development Framework (SSDF, SP 800-218) both formalize these principles.
The Shift-Left principle
“Shift left” means moving security activities earlier in the development lifecycle:
Traditional: Plan → Code → Build → Test → Release → [Security Audit]
DevSecOps: Plan → Code → Build → Test → Release → Deploy → Monitor
↓ ↓ ↓ ↓ ↓ ↓ ↓
Threat SAST SCA DAST Image Policy Runtime
model lint deps scan scan check alerts
Finding a vulnerability during design costs orders of magnitude less than fixing it post-production. IBM’s Systems Science Institute estimated the relative costs as: design (1×), coding (10×), testing (15×), production (100×).
Security Principles
CIA Triad
The CIA Triad is the foundational model for information security. Every security control exists to protect one or more of these properties:
| Property | Definition | Example controls |
|---|---|---|
| Confidentiality | Information is accessible only to authorized parties | Encryption, access control, MFA |
| Integrity | Information is accurate and has not been tampered with | Checksums, digital signatures, audit logs |
| Availability | Systems and data are accessible when needed | Redundancy, DDoS mitigation, backups |
A ransomware attack violates all three: it denies availability, may exfiltrate data (confidentiality), and often corrupts backups (integrity).
import hashlib
def verify_file_integrity(filepath: str, expected_sha256: str) -> bool:
"""Verify a file's SHA-256 hash to ensure integrity."""
sha256 = hashlib.sha256()
with open(filepath, 'rb') as f:
for chunk in iter(lambda: f.read(65536), b''):
sha256.update(chunk)
actual = sha256.hexdigest()
if actual != expected_sha256:
raise ValueError(f"Integrity check FAILED: expected {expected_sha256}, got {actual}")
return True
Defense in Depth
Defense in depth (also called layered security) uses multiple independent security controls so that the failure of any single layer does not compromise the entire system.
Internet
│
▼
[WAF / DDoS protection] ← Layer 1: Edge
│
▼
[Network firewall / ACLs] ← Layer 2: Network
│
▼
[Load balancer / TLS termination] ← Layer 3: Transport
│
▼
[Application firewall rules] ← Layer 4: Application
│
▼
[Authentication / Authorization] ← Layer 5: Identity
│
▼
[Input validation / SAST output] ← Layer 6: Code
│
▼
[Encrypted database / secrets] ← Layer 7: Data
No single control is assumed to be perfect. An attacker who bypasses the WAF still faces network ACLs. An attacker who gains network access still needs valid credentials. An attacker with valid credentials still cannot read encrypted data without the key.
Zero Trust
Zero Trust is a security model that eliminates implicit trust based on network location. The traditional “castle and moat” model trusted everything inside the perimeter — Zero Trust does not.
Zero Trust principles (NIST SP 800-207):
- All resources are accessed via authenticated, authorized requests — regardless of network location
- Access is granted on a per-session basis with least privilege
- All traffic is inspected and logged
- The network is assumed to be hostile (even internal traffic)
# Example: enforce mTLS (mutual TLS) between services with Istio
# Both client and server present certificates; the network is untrusted
kubectl apply -f - <<'EOF'
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICT # reject all non-mTLS traffic, even within the cluster
EOF
Least Privilege
Every user, process, and service should have only the minimum permissions needed to perform its function, and only for as long as needed.
# Bad: application running as root
docker run --user root myapp
# Good: application running as unprivileged user (UID 1000)
docker run --user 1000:1000 myapp
# Bad: service account with cluster-admin
kubectl create clusterrolebinding myapp-admin \
--clusterrole=cluster-admin --serviceaccount=default:myapp
# Good: service account with only what the app needs
kubectl create role myapp-role \
--verb=get,list --resource=configmaps --namespace=myapp
kubectl create rolebinding myapp-binding \
--role=myapp-role --serviceaccount=myapp:myapp
# Python: request only the IAM permissions needed
import boto3
# Bad: use a profile with AdministratorAccess
s3 = boto3.client('s3')
# Good: use an IAM role scoped to the specific bucket and operation
# (configured in AWS via least-privilege policy, attached to instance/ECS task role)
# The policy grants: s3:GetObject on arn:aws:s3:::my-bucket/*
s3 = boto3.client('s3', region_name='us-east-1')
obj = s3.get_object(Bucket='my-bucket', Key='report.pdf')
DevSecOps Lifecycle Integration
Security in Each Pipeline Stage
Plan:
- Threat modeling during design (see Threat Modeling)
- Security user stories and acceptance criteria
- Compliance requirement identification
Code:
- IDE security plugins (Semgrep, Snyk, SonarLint)
- Pre-commit hooks for secrets detection
- Peer code review with security checklist
Build:
- SAST (Static Application Security Testing) — scan source code
- SCA (Software Composition Analysis) — scan dependencies for known CVEs
- Secrets detection — reject builds containing credentials
Test:
- DAST (Dynamic Application Security Testing) — test running application
- Container image scanning
- Infrastructure-as-code security scanning (Checkov, tfsec)
Release:
- Artifact signing (Sigstore/cosign)
- SBOM generation
- Policy gate: fail build on critical CVEs
Deploy:
- Kubernetes admission controllers (OPA/Gatekeeper)
- Signed image verification
- Network policy enforcement
Operate:
- Runtime security monitoring (Falco)
- Log aggregation and SIEM alerting
- Vulnerability scanning of production assets
Monitor:
- Continuous compliance scanning (CSPM)
- Alerting on anomalous behavior
- Incident response playbooks
A minimal DevSecOps GitHub Actions pipeline
# .github/workflows/devsecops.yml
name: DevSecOps Pipeline
on: [push, pull_request]
jobs:
sast:
name: Static Analysis
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# Python SAST with Bandit
- name: Run Bandit
run: |
pip install bandit
bandit -r src/ -f json -o bandit-report.json -ll
continue-on-error: false
# Semgrep multi-language SAST
# The old returntocorp/semgrep-action is retired — run the CLI directly.
- name: Run Semgrep
run: |
pip install semgrep
semgrep scan --config p/owasp-top-ten --error
secrets:
name: Secrets Detection
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # full history for gitleaks
- name: Run gitleaks
uses: gitleaks/gitleaks-action@v2
sca:
name: Dependency Scan
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Trivy filesystem scan
# Pin to a full commit SHA, not a tag: trivy-action tags were
# force-pushed during a March 2026 supply-chain compromise, so a
# moving ref like @master (or even a tag) is not trustworthy.
uses: aquasecurity/trivy-action@<commit-sha> # SHA for a known-good release
with:
scan-type: fs
scan-ref: .
severity: CRITICAL,HIGH
exit-code: 1
container:
name: Container Scan
runs-on: ubuntu-latest
needs: [sast, secrets, sca]
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:$ .
- name: Scan image with Trivy
uses: aquasecurity/trivy-action@<commit-sha> # pin to a SHA (see note above)
with:
image-ref: myapp:$
severity: CRITICAL,HIGH
exit-code: 1
Scripting for DevSecOps
Python for security automation
Python is the primary language for DevSecOps automation. Key security libraries:
| Library | Purpose | Install |
|---|---|---|
bandit |
Python SAST scanner | pip install bandit |
safety |
Check Python deps for CVEs | pip install safety |
semgrep |
Multi-language SAST | pip install semgrep |
cryptography |
Crypto primitives | pip install cryptography |
paramiko |
SSH client/server | pip install paramiko |
requests |
HTTP client (with TLS) | pip install requests |
boto3 |
AWS SDK | pip install boto3 |
hvac |
Vault/OpenBao API client | pip install hvac |
python-nmap |
Nmap Python wrapper | pip install python-nmap |
# Scan Python code with Bandit
pip install bandit
bandit -r myapp/ -ll # report medium+ severity issues
bandit -r myapp/ -f json -o report.json # machine-readable output
# Check dependencies for known CVEs
# `safety check` was retired (unsupported past June 2024); use `safety scan`,
# which auto-discovers requirements/Poetry/Pipenv files in the project.
pip install safety
safety scan # scan the project directory
safety scan --output json # JSON output for CI
# Safety 3.x requires auth: run `safety auth` once, or set SAFETY_API_KEY in CI.
Bash for security scripting
# Harden a new Linux host: disable root login and empty passwords
sed -i 's/^PermitRootLogin.*/PermitRootLogin no/' /etc/ssh/sshd_config
sed -i 's/^PermitEmptyPasswords.*/PermitEmptyPasswords no/' /etc/ssh/sshd_config
systemctl reload sshd
# Find world-writable files (potential privilege escalation vectors)
find / -xdev -type f -perm -0002 -ls 2>/dev/null
# Find SUID/SGID binaries (review for unexpected entries)
find / -xdev \( -perm -4000 -o -perm -2000 \) -type f -ls 2>/dev/null
# Check for failed SSH login attempts
journalctl -u sshd --since "1 hour ago" | grep "Failed password" | \
awk '{print $11}' | sort | uniq -c | sort -rn | head -20
# Verify file checksums against a known-good manifest
sha256sum --check /etc/checksums.sha256
Key takeaways
- DevSecOps is shift-left plus shared ownership: security activities move earlier and become everyone’s job, automated into the pipeline instead of a final audit. Fixing a design flaw is ~100× cheaper than fixing it in production.
- Four principles anchor everything: the CIA triad (what you protect), defense in depth (layered, independent controls), zero trust (no implicit trust by network location, NIST 800-207), and least privilege (minimum permissions, briefest time).
- Each pipeline stage gets a control: threat modeling at plan, SAST/SCA/secrets at build, DAST/image/IaC scanning at test, signing + SBOM at release, admission control at deploy, and runtime monitoring (Falco/SIEM) at operate.
- Gates make it real: configure scanners to fail the build on high-severity findings, so insecure code can’t merge — a control that only warns is eventually ignored.
- Python and Bash are the automation glue —
bandit/safety/semgrepfor scanning, plus hardening scripts (disable root SSH, hunt SUID/world-writable files, verify checksums).
References
- OWASP DevSecOps Guideline. https://owasp.org/www-project-devsecops-guideline/
- NIST SP 800-218 — Secure Software Development Framework (SSDF). https://csrc.nist.gov/publications/detail/sp/800/218/final
- NIST SP 800-207 — Zero Trust Architecture. https://csrc.nist.gov/publications/detail/sp/800/207/final
- CIS Controls v8. https://www.cisecurity.org/controls/v8
- OWASP Top 10. https://owasp.org/www-project-top-ten/
Related course pages: Threat Modeling · Vulnerability Management · Containerization
🛠️ Maintenance note: third-party GitHub Actions move and get re-tagged — re-verify the
uses:references each term, and replace the<commit-sha>placeholders ontrivy-actionwith a current known-good commit SHA (its tags were force-pushed in a March 2026 supply-chain compromise, so prefer SHA pins). Also re-check the IBM cost-of-defect figures and the SSDF revision each term.