DevSecOps is the practice of integrating security into every stage of the software development lifecycle — not as a gate at the end, but as a continuous process built into the same workflow developers use for testing and deployment. The core principle is "shift left": find and fix security issues as early as possible, when they are cheapest to remediate, rather than discovering them in production.
A vulnerability found during code review costs minutes to fix. The same vulnerability found in production after a breach costs months and potentially millions of dollars.
The Security Testing Toolchain
DevSecOps toolchains typically combine several complementary scanning approaches:
SAST — Static Application Security Testing
SAST tools analyze source code without executing it, looking for patterns that indicate vulnerabilities: SQL strings concatenated with user input, hardcoded credentials, missing authorization checks, dangerous function calls.
Common SAST tools: Semgrep, SonarQube, Bandit (Python), ESLint security plugins (JavaScript), Brakeman (Ruby).
# Example Semgrep rule — finds SQL concatenation in Python
rules:
- id: sql-injection
pattern: cursor.execute("..." + $USER_INPUT)
message: Potential SQL injection
severity: ERROR
Strengths: Fast, runs on code before deployment, no running application needed, finds issues early.
Limitations: High false positive rate, misses runtime configuration issues, cannot see vulnerability from the outside as an attacker would.
SCA — Software Composition Analysis
SCA tools audit your dependencies (npm packages, Python packages, Maven jars) against known vulnerability databases like CVE and GitHub Advisory.
Tools: Dependabot (GitHub), Snyk, OWASP Dependency-Check, npm audit, pip-audit.
# Run in CI
pip-audit --requirement requirements.txt --format json > pip-audit.json
npm audit --json > npm-audit.json
Set up automated pull requests for dependency updates and fail the build for critical or high severity CVEs in direct dependencies.
Secret Scanning
Catches API keys, passwords, and tokens accidentally committed to source control before they reach the remote repository.
# Pre-commit hook with gitleaks
gitleaks protect --staged
# In CI
gitleaks detect --source . --report-format json
Tools: gitleaks, truffleHog, GitHub Secret Scanning (built-in for GitHub repositories). A pre-commit hook is the most effective placement — it blocks the commit before the secret is ever in history.
DAST — Dynamic Application Security Testing
DAST runs against a live, deployed application, probing it from the outside as an attacker would. This catches vulnerabilities that only manifest at runtime: misconfigured security headers, TLS issues, server error disclosures, reflected XSS.
DAST in CI/CD targets a staging environment, not production. A typical workflow:
- Deploy the application to a staging environment
- Run a DAST scan against the staging URL
- Parse the results and fail the pipeline if new critical or high findings are introduced
- Deploy to production only if the scan passes
Shieldome's REST API is designed for exactly this integration — run a programmatic scan, poll for results, and gate deployment on severity thresholds.
CI/CD Integration Example (GitHub Actions)
name: Security Scan
on: [push, pull_request]
jobs:
sast:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: |
pip install semgrep
semgrep --config=auto --error .
sca:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Python dependency audit
run: |
pip install pip-audit
pip-audit -r requirements.txt
secrets:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: Scan for secrets
run: |
curl -sSfL https://raw.githubusercontent.com/gitleaks/gitleaks/main/scripts/install.sh | sh
./gitleaks detect --source . --exit-code 1
dast:
runs-on: ubuntu-latest
needs: [sast, sca] # Only run if static checks pass
steps:
- name: Start staging server
run: docker compose -f docker-compose.staging.yml up -d
- name: Run DAST scan
run: |
curl -X POST https://app.shieldome.com/api/scans -H "Authorization: Bearer $SHIELDOME_API_KEY" -d '{"target": "https://staging.yourapp.com"}'
Severity Thresholds and Breaking Builds
Not every finding should fail a build — that leads to alert fatigue and developers disabling the checks. A practical threshold policy:
- Critical/High: Always fail the build. These require immediate attention.
- Medium: Fail the build unless an existing exemption is documented and approved.
- Low/Info: Report but do not fail. Review in the next sprint.
Use a baseline file to suppress known accepted risks, so only newly introduced issues fail the build. This keeps the signal-to-noise ratio high and prevents teams from ignoring the scanner.
The Developer Experience Matters
Security tooling that slows developers down gets disabled. Design for speed:
- Run lightweight checks (secret scanning, SAST) on every commit — these are fast
- Run heavier checks (full DAST scan) only on pull requests to main, not on every feature branch commit
- Give developers access to the same tools locally so they can check before pushing
- Report findings with clear remediation guidance, not just CVE numbers
- Provide a documented process for handling false positives and accepted risks
The goal is a security program that developers see as a helpful tool, not a deployment gate that generates work for someone else. When security is embedded in the workflow and findings are actionable, it gets fixed. When it is a separate process that generates reports at the end of the quarter, it gets deferred.