“Shift left” has become a cliché in security circles. What it means in practice is simple: find and fix security issues earlier in the development lifecycle, when they’re cheap to fix, rather than later, when they’re expensive. A bug found in design costs a conversation. The same bug found in production costs a breach.
DevSecOps is the practice of integrating security throughout the software development lifecycle (SDLC) — not as a gate at the end, but as a continuous, automated discipline woven into how teams build and ship software. Our DevSecOps consulting service helps engineering teams implement exactly the toolchain and culture described in this guide. Key components include source code security review and periodic web application penetration testing.
This guide is practical, not theoretical. It covers the specific controls to implement, the tools to use, and how to do it without making developers hate the security team.
Why Traditional Security Models Break in DevOps
Traditional security worked like this: developers build a feature, security reviews it before release, security finds issues, developers fix them, cycle repeats. This was already slow in the Waterfall era. In modern DevOps environments with multiple releases per day, it’s completely incompatible.
The symptoms of a broken security model:
- Security reviews become bottlenecks that delay releases
- Developers find security requirements vague and adversarial
- Issues found late in the cycle are expensive to fix (changing a framework choice costs weeks; changing it in design costs an afternoon)
- Security is seen as “not my job” — the dev team ships features, the security team checks them
- Security defects accumulate faster than they’re resolved
DevSecOps addresses this by:
- Automating security checks in the pipeline so they don’t require human gates
- Making developers own security — not just security teams
- Providing fast, specific, actionable feedback so developers can fix issues without security expertise
- Shifting expensive manual security testing to the places where it adds the most value
The DevSecOps Toolchain: Layer by Layer
Layer 1: Secure Design (Pre-Code)
Threat Modelling
Before writing code for a significant feature or system, do a 30–60 minute threat modelling session:
- What are we building? Draw a simple data flow diagram.
- What can go wrong? Apply STRIDE (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege).
- What do we do about it? Document mitigations.
- Did we succeed? Define security acceptance criteria.
Use OWASP Threat Dragon (free, open source) or whiteboard + photo. The goal is not a perfect diagram — it’s a structured conversation that surfaces security requirements before a line of code is written.
Security Stories
Write security requirements as user stories that can be verified:
- “The login endpoint must rate-limit to 5 attempts per minute per IP and return 429 after threshold”
- “Session tokens must not be logged in application logs”
- “User-uploaded files must be scanned for malware before storage”
These go in the same backlog as feature stories. They have acceptance criteria. They get tested.
Layer 2: IDE and Pre-Commit
IDE Security Plugins
Give developers real-time feedback while they’re writing code:
| Plugin | Language Support | What It Finds |
|---|---|---|
| Snyk | JS, Python, Java, Go, Ruby | Vulnerable dependencies, code issues |
| SonarLint | 30+ languages | Code quality and security bugs |
| Semgrep | 30+ languages | Custom and community security rules |
| GitGuardian | Any | Secrets (API keys, credentials) in code |
| Checkov (for IaC) | Terraform, CloudFormation | Infrastructure misconfigurations |
The goal is to catch issues before they’re committed — before they’re in CI/CD, before they’re in a PR review, before they’re in production.
Pre-Commit Hooks
Use pre-commit framework to run security checks before every commit:
# .pre-commit-config.yaml
repos:
- repo: https://github.com/gitleaks/gitleaks
rev: v8.18.0
hooks:
- id: gitleaks # Secrets scanning
- repo: https://github.com/pycqa/bandit
rev: 1.7.5
hooks:
- id: bandit # Python SAST
args: ["-ll"] # Only high and medium
- repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.83.0
hooks:
- id: terraform_tfsec # Terraform security
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
hooks:
- id: detect-private-key # Private keys
- id: check-merge-conflict
Install: pip install pre-commit && pre-commit install
Layer 3: CI/CD Pipeline Security
This is the core of DevSecOps — automated security testing on every PR and every push to main.
SAST (Static Application Security Testing)
Analyses source code without running it. Finds hardcoded credentials, injection sinks, dangerous functions, logic errors. For deeper analysis of your most critical components, pair SAST with a source code security review conducted by a human expert.
# GitHub Actions — SAST with Semgrep
- name: Semgrep SAST
uses: semgrep/semgrep-action@v1
with:
config: >-
p/owasp-top-ten
p/python
p/javascript
p/secrets
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
Tool options:
- Semgrep (open source / commercial) — excellent for custom rules, fast, low false positives
- CodeQL (GitHub native, free for public repos) — very deep analysis, good for Java/JS/Python/Go
- SonarQube — comprehensive, well-integrated in enterprise environments
- Bandit (Python-specific) — fast, good Python security scanner
- ESLint Security Plugin (Node.js) — catches common JS security issues
SCA (Software Composition Analysis)
Checks your dependencies for known CVEs:
# GitHub Actions — Snyk dependency scanning
- name: Snyk dependency scan
uses: snyk/actions/python@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
command: test
args: --severity-threshold=high --fail-on=all
Tool options:
- Dependabot (GitHub native, free) — automatic PRs for vulnerable dependencies
- Snyk — comprehensive SCA with remediation advice
- OWASP Dependency-Check — open source, mature
- Socket — open source security, detects supply chain attacks
Secrets Scanning
Prevent credential leaks from making it to version control:
# GitHub Actions — Gitleaks secrets scanning
- name: Gitleaks secrets scan
uses: gitleaks/gitleaks-action@v2
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITLEAKS_LICENSE: ${{ secrets.GITLEAKS_LICENSE }}
Also enable GitHub Advanced Security secret scanning — it scans your entire repo history, not just new commits.
IaC Security Scanning
Scan Terraform, CloudFormation, Kubernetes manifests for misconfigurations:
# GitHub Actions — Checkov IaC scanning
- name: Run Checkov
uses: bridgecrewio/checkov-action@master
with:
directory: terraform/
framework: terraform
output_format: sarif
output_file_path: checkov-results.sarif
soft_fail: false # Fail build on critical findings
Container Image Scanning
Scan Docker images for OS and application vulnerabilities before pushing:
# GitHub Actions — Trivy container scanning
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan image with Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: CRITICAL,HIGH
exit-code: 1 # Fail build on critical/high
format: sarif
output: trivy-results.sarif
DAST (Dynamic Application Security Testing)
Test the running application for vulnerabilities — runs against a deployed staging environment:
# GitHub Actions — OWASP ZAP API scan
- name: Deploy to staging
run: ./deploy-staging.sh
- name: ZAP API Scan
uses: zaproxy/action-api-scan@v0.4.0
with:
target: 'https://staging.api.yourapp.com/openapi.json'
format: openapi
fail_action: true
cmd_options: '-a -j -l WARN'
Layer 4: Pre-Deployment Gates
Before code reaches production, apply final security gates:
Security Approval for High-Risk Changes
Define what requires a security team review (not all changes — that’s the bottleneck):
- New authentication or authorisation logic
- Changes to cryptographic implementations
- New external integrations or data sources
- Infrastructure changes to production networks
- Any change touching PII storage or processing
Everything else ships without security gate. Automate the categorisation where possible.
Compliance Checks
If you’re PCI DSS or HIPAA regulated, run automated compliance checks against your infrastructure configuration before deployment to production. Checkov and Cloud Custodian can enforce “no deploy if config violates policy.”
Layer 5: Runtime Protection
Security doesn’t stop at deployment:
RASP (Runtime Application Self-Protection)
RASP agents instrument your application at runtime, detecting and blocking attacks in real-time from within the application. Can catch attacks that WAF and SAST miss (application logic exploitation).
Options: Sqreen (acquired by Datadog), Contrast Security, Imperva RASP
WAF
Cloudflare WAF, AWS WAF, or application-specific WAF rules. First line of defence for known attack patterns.
Cloud Security Posture Management (CSPM)
Continuous assessment of your cloud configuration against security benchmarks (CIS, PCI, etc.). Catches drift from the baseline established in IaC.
Container Runtime Security
If running Kubernetes: Falco, Sysdig, or commercial alternatives (Prisma Cloud CWPP) monitor container behaviour at runtime and alert on anomalous activity (unexpected process execution, privilege escalation, unexpected network connections).
Common Failure Modes (And How to Avoid Them)
“Too Many False Positives — Developers Ignore Everything”
The worst outcome: security tools crying wolf so often that developers disable or ignore them. Fix this by:
- Start with low false positive tools (Semgrep with curated rulesets, not everything turned on)
- Tune rules before enforcing them — run in monitor mode for 2 weeks
- Address false positives immediately when reported — don’t let them accumulate
- Create a clear suppression process so developers can dismiss false positives with justification
”Security Adds 30 Minutes to Every Build”
Long security scans kill developer experience. Fix this by:
- Run fast checks (SAST, secrets, SCA) on every PR — these should take < 2 minutes
- Run slow checks (DAST, container scanning) only on merges to main or deployment branches
- Parallelise security jobs in CI/CD — don’t run them serially
- Cache SAST results and only re-scan changed files
”We Have 500 Open Security Findings and No One Owns Them”
Tool sprawl without triage creates finding debt that nobody believes they can pay down. Fix this by:
- Establishing a triage SLA: Critical = fix within 48 hours, High = fix within 1 sprint, Medium = backlog
- Assigning ownership: the team that owns the code owns the finding
- Blocking releases on Critical findings only initially — work up to High as the team matures
- Tracking metrics: open finding count by team, resolution rate, mean time to fix
Measuring DevSecOps Maturity
Track these metrics to demonstrate program progress:
| Metric | What It Measures |
|---|---|
| MTTF (Mean Time to Fix) | How quickly security findings are remediated |
| Vulnerability introduction rate | New findings per sprint/release |
| Pipeline pass rate | % of builds that pass security gates without manual intervention |
| Security finding backlog | Open findings by severity — should trend down |
| Pentest finding reduction | Year-over-year reduction in findings from external pentests |
| Secrets leaked (to remediated) | How many credentials accidentally committed, how quickly revoked |
A mature DevSecOps programme shows: declining finding backlog, low MTTF, high pipeline pass rates, and shrinking pentest findings year-over-year as the pipeline catches more issues earlier. Complement your pipeline controls with annual source code security reviews to catch the business logic flaws that automated tools miss.
Starting Point: 30-Day Plan
If you’re starting from nothing:
Week 1 — Visibility
- Enable Dependabot on all repos (free, immediate dependency vulnerability detection)
- Enable GitHub secret scanning on all repos
- Install Semgrep IDE plugin for the team
Week 2 — Automate
- Add Gitleaks to CI/CD for secrets scanning
- Add Snyk (or Dependabot Alerts with auto-PRs) for dependency scanning
- Add Checkov for any IaC (Terraform/CloudFormation)
Week 3 — Measure
- Review findings from Week 2 — triage and assign
- Define triage SLAs
- Create a security findings dashboard (GitHub Security tab is a good start)
Week 4 — Harden
- Add SAST (Semgrep or CodeQL) to CI/CD
- Set up pre-commit hooks for the team
- Schedule first threat modelling session for next sprint’s big feature
By Day 30 you’ll have a functioning DevSecOps baseline. The next 90 days are about tuning, expanding coverage, and building the culture.
CyberneticsPlus helps engineering teams build and mature DevSecOps programmes through our DevSecOps consulting service — from pipeline security tooling to developer training and threat modelling facilitation. We also provide source code security reviews to validate security at the code level. Contact us to assess your current development security posture.