Ideas Engineered for Tomorrow
We Engineer Services & Solutions for Your Business Needs
Home About
Products
Services
Hire
Industries
Consulting
Partners
Articles Careers Contact
Cybersecurity

DevSecOps: Integrating Security Into Your CI/CD Pipeline

Security gates that block deploys don't work — developers route around them. DevSecOps embeds security into the pipeline so fast feedback replaces slow gates. Here's how to set it up with tools you already use.

🔒 Cybersecurity January 30, 2026 14 min read

In This Guide

The median time to fix a critical vulnerability is 60 days (Veracode, 2024). Not because the fix is hard — usually it's a dependency bump or a one-line code change. It's 60 days because the vulnerability was found by a quarterly pen test, filed as a ticket, prioritized against feature work, assigned to someone who'd forgotten the context, and eventually deployed. DevSecOps exists to compress that 60-day feedback loop to 60 seconds.

We've implemented DevSecOps pipelines at Pillai Infotech for projects ranging from single-service APIs to multi-repo microservice architectures. This guide covers the tools, configurations, and — critically — the cultural changes that make it work.

1. Why "Shift Left" Isn't Enough — You Need "Shift Everywhere"

"Shift left" means finding security issues earlier in the development cycle. Good idea. But the slogan implies security is a phase that moves — it's not. Security needs to exist at every stage simultaneously.

Stage Security Activity Tools Feedback Time
IDE / Pre-commit Secrets detection, basic SAST gitleaks, Semgrep IDE extension Instant (before commit)
Pull Request Full SAST, SCA, license check Semgrep, Snyk, Trivy 2-5 minutes
Build Container scan, IaC scan, SBOM Trivy, Checkov, Syft 3-8 minutes
Staging DAST, API fuzzing OWASP ZAP, Nuclei 10-30 minutes
Production Runtime protection, WAF, monitoring Falco, Datadog ASM, Cloudflare WAF Real-time
Ongoing New CVE alerts, pen testing GitHub Dependabot, Snyk Monitor Continuous

2. The DevSecOps Pipeline — Security at Every Stage

Developer Workstation CI Pipeline Production ┌───────────────────┐ ┌────────────────────────┐ ┌──────────────────┐ │ IDE Linting │ │ ┌──────────────────┐ │ │ WAF / CDN │ │ Pre-commit hooks │──▶│ │ SAST (Semgrep) │ │──▶│ Runtime RASP │ │ • gitleaks │ │ │ SCA (Snyk/Trivy) │ │ │ Log monitoring │ │ • Semgrep │ │ │ Secrets scan │ │ │ Anomaly detection│ └───────────────────┘ │ │ License check │ │ └──────────────────┘ │ └──────┬───────────┘ │ │ │ Pass? │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Build & Package │ │ │ │ Container scan │ │ │ │ IaC scan │ │ │ │ SBOM generation │ │ │ └──────┬───────────┘ │ │ │ Pass? │ │ ▼ │ │ ┌──────────────────┐ │ │ │ Deploy → Staging │ │ │ │ DAST (ZAP) │ │ │ │ API fuzz testing │ │ │ └──────────────────┘ │ └────────────────────────┘

The key principle: fast checks run first, slow checks run later. Secrets detection in pre-commit takes milliseconds. DAST against a staging environment takes minutes. If you put the slow checks first, developers will disable them.

3. SAST — Finding Bugs in Source Code

Static Application Security Testing analyzes source code without running it. The modern tool of choice is Semgrep — it's fast, has great rules, and the open-source version covers most use cases.

Tool Languages Speed False Positive Rate Cost
Semgrep 30+ (JS, Python, Go, Java, PHP...) Fast (seconds) Low Free OSS / paid Pro
CodeQL C/C++, Java, JS, Python, Go, Ruby Slow (minutes) Very low Free on GitHub
SonarQube 29 languages Medium Medium-high Free Community / paid
Bandit (Python) Python only Fast Low-medium Free
# Semgrep in CI — GitHub Actions
- name: Run Semgrep SAST
  uses: returntocorp/semgrep-action@v1
  with:
    config: >-
      p/security-audit
      p/owasp-top-ten
      p/nodejs
      p/php
    generateSarif: true

# Or run directly for more control:
- name: Semgrep scan
  run: |
    pip install semgrep
    semgrep scan \
      --config p/security-audit \
      --config p/owasp-top-ten \
      --error \                    # Fail CI on findings
      --severity ERROR \           # Only block on critical
      --sarif -o semgrep.sarif \   # Upload to GitHub Security tab
      .

Custom Semgrep Rules

The real power of Semgrep is writing rules specific to your codebase. Here's one we use:

# .semgrep/custom-rules.yml — Catch raw SQL in PHP
rules:
  - id: php-raw-sql-query
    patterns:
      - pattern: $DB->query("..." . $VAR . "...")
    message: >
      Direct variable interpolation in SQL query detected.
      Use prepared statements: $db->execute("... WHERE id = ?", [$var])
    languages: [php]
    severity: ERROR
    metadata:
      cwe: CWE-89
      owasp: A03:2021

  - id: no-auth-middleware
    patterns:
      - pattern: |
          $app->$METHOD($PATH, function($req, $res) { ... });
      - pattern-not: |
          $app->$METHOD($PATH, authenticate, ...);
    message: Route handler without authentication middleware
    languages: [javascript]
    severity: WARNING

4. SCA — Your Dependencies Are Your Attack Surface

The average Node.js project pulls in 1,200+ transitive dependencies. You wrote 5,000 lines of code, but you're shipping 500,000 lines of other people's code. Software Composition Analysis (SCA) tracks those dependencies for known vulnerabilities.

# Dependency scanning commands by ecosystem
# Node.js — built-in audit
npm audit --audit-level=high
# Fix automatically where possible:
npm audit fix

# Python
pip-audit --require-hashes --strict
# Or:
safety check --full-report

# Go
govulncheck ./...

# PHP (Composer)
composer audit

# Universal — Trivy scans any project type
trivy fs --severity HIGH,CRITICAL --exit-code 1 .

# Generate SBOM (Software Bill of Materials)
syft . -o spdx-json > sbom.spdx.json

Dependency Policy That Works

Not every vulnerability needs immediate action. Set a policy:

Severity CI Behavior SLA Example
Critical (CVSS 9+) Block merge Fix within 24 hours Remote code execution in Express
High (CVSS 7-8.9) Block merge Fix within 7 days SQL injection in ORM library
Medium (CVSS 4-6.9) Warn, don't block Fix within 30 days ReDoS in validation library
Low (CVSS 0-3.9) Log only Fix in next dependency update cycle Info disclosure in debug mode
What We've Learned at Pillai Infotech

We started with "block on all vulnerabilities" and reverted within a week — developers couldn't merge because of low-severity findings in transitive dependencies they didn't control. The policy above took three iterations to get right. The key insight: block on things developers can actually fix quickly (direct dependencies, critical severity), warn on everything else.

5. Secrets Detection — Catching Leaked Credentials

GitHub scans public repos and finds over 1 million leaked secrets per year. Private repos leak too — they just take longer to discover. The fix is catching secrets before they enter version control.

# Pre-commit hook with gitleaks
# Install gitleaks
brew install gitleaks  # macOS
# Or: go install github.com/gitleaks/gitleaks/v8@latest

# .pre-commit-config.yaml
repos:
  - repo: https://github.com/gitleaks/gitleaks
    rev: v8.18.0
    hooks:
      - id: gitleaks

# Run manually against entire repo history
gitleaks detect --source . --verbose

# Scan only staged changes (fast, for pre-commit)
gitleaks protect --staged --verbose
# Custom gitleaks config — .gitleaks.toml
[extend]
useDefault = true  # Include all default patterns

# Add custom patterns for your APIs
[[rules]]
id = "pillai-api-key"
description = "Pillai Infotech API Key"
regex = '''nc_bot_[a-zA-Z0-9]{10,}'''
secretGroup = 0
entropy = 3.5

[[rules]]
id = "openrouter-key"
description = "OpenRouter API Key"
regex = '''sk-or-v1-[a-f0-9]{64}'''

# Allowlist — files that legitimately contain example keys
[allowlist]
paths = [
  '''\.env\.example''',
  '''docs/api-examples\.md''',
]

If a secret is already committed: Rotating the credential is more important than removing it from git history. Even if you rewrite history with git filter-branch or BFG Repo Cleaner, the secret was likely already in caches, CI logs, or someone's local clone. Rotate first, clean history second. See our cybersecurity best practices guide for secrets management tools.

6. Container and IaC Scanning

Your Dockerfile and Terraform files are code. They can contain vulnerabilities, misconfigurations, and secrets just like application code.

Container Image Scanning with Trivy

# Trivy — scan container images + IaC + dependencies
# Scan a Docker image for OS and library vulnerabilities
trivy image --severity HIGH,CRITICAL myapp:latest

# Scan Dockerfile for misconfigurations
trivy config --severity HIGH,CRITICAL Dockerfile

# Scan Terraform files
trivy config --severity HIGH,CRITICAL ./terraform/

# Common Dockerfile issues Trivy catches:
# - Running as root (no USER instruction)
# - Using :latest tag (unpinned base image)
# - Secrets in ENV or ARG instructions
# - Package manager cache not cleaned
# - Unnecessary packages installed

Secure Dockerfile Pattern

# Multi-stage build with security best practices
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production   # Deterministic install
COPY . .
RUN npm run build

# Stage 2: Production — minimal image
FROM node:20-alpine AS production

# ✅ Don't run as root
RUN addgroup -g 1001 appgroup && \
    adduser -u 1001 -G appgroup -s /bin/sh -D appuser

WORKDIR /app

# ✅ Only copy what's needed
COPY --from=builder --chown=appuser:appgroup /app/dist ./dist
COPY --from=builder --chown=appuser:appgroup /app/node_modules ./node_modules
COPY --from=builder --chown=appuser:appgroup /app/package.json ./

# ✅ Read-only filesystem where possible
USER appuser

# ✅ Health check for orchestrator
HEALTHCHECK --interval=30s --timeout=3s \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1

EXPOSE 3000
CMD ["node", "dist/server.js"]

IaC Scanning with Checkov

# Checkov — catches cloud misconfigurations before deploy
# Scan Terraform
checkov -d ./terraform/ --framework terraform

# Common findings:
# ✗ S3 bucket without encryption
# ✗ Security group with 0.0.0.0/0 ingress on port 22
# ✗ RDS without encryption at rest
# ✗ CloudTrail not enabled
# ✗ IAM policy with * resource

# Scan Kubernetes manifests
checkov -d ./k8s/ --framework kubernetes

# Common findings:
# ✗ Container running as root
# ✗ No resource limits set
# ✗ No readOnlyRootFilesystem
# ✗ hostNetwork: true

7. DAST — Testing the Running Application

DAST finds vulnerabilities that SAST can't — it tests the running application the way an attacker would. OWASP ZAP is the standard open-source DAST tool.

# OWASP ZAP — automated scan in CI
# Baseline scan — fast, finds low-hanging fruit (5-10 min)
docker run --rm -v $(pwd):/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-baseline.py \
    -t https://staging.pillaiinfotech.com \
    -r zap-report.html \
    -l WARN

# Full scan — thorough, runs active attacks (30-60 min)
docker run --rm -v $(pwd):/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-full-scan.py \
    -t https://staging.pillaiinfotech.com \
    -r zap-full-report.html

# API scan — import OpenAPI spec, test every endpoint
docker run --rm -v $(pwd):/zap/wrk \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-api-scan.py \
    -t https://staging.pillaiinfotech.com/openapi.json \
    -f openapi \
    -r zap-api-report.html

When to DAST: Run the baseline scan on every PR deploy to staging. Run the full scan weekly or before releases. API scans should run whenever the OpenAPI spec changes. Never run DAST against production — it generates real attack traffic. Use a staging environment that mirrors production. For dedicated penetration testing, hire professionals.

8. Complete GitHub Actions Security Pipeline

Here's a production-ready security pipeline that ties everything together. We use a variation of this across our projects at Pillai Infotech:

# .github/workflows/security.yml
name: Security Pipeline
on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

jobs:
  secrets-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0  # Full history for comprehensive scan
      - name: Gitleaks
        uses: gitleaks/gitleaks-action@v2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Semgrep
        uses: returntocorp/semgrep-action@v1
        with:
          config: p/security-audit p/owasp-top-ten
          generateSarif: true
      - name: Upload SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: semgrep.sarif

  dependency-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Trivy vulnerability scan
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: fs
          severity: HIGH,CRITICAL
          exit-code: 1
          format: sarif
          output: trivy-results.sarif
      - name: Upload Trivy SARIF
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: trivy-results.sarif

  container-scan:
    runs-on: ubuntu-latest
    needs: [sast, dependency-scan]  # Only build if code is clean
    steps:
      - uses: actions/checkout@v4
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      - name: Trivy image scan
        uses: aquasecurity/trivy-action@master
        with:
          image-ref: myapp:${{ github.sha }}
          severity: HIGH,CRITICAL
          exit-code: 1

  iac-scan:
    runs-on: ubuntu-latest
    if: contains(github.event.pull_request.changed_files, 'terraform')
    steps:
      - uses: actions/checkout@v4
      - name: Checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: ./terraform
          framework: terraform
          soft_fail: false

Notice that secrets-scan, sast, and dependency-scan run in parallel — no need to wait. The container-scan only runs after the code checks pass (no point building an image if the code has vulnerabilities). Total pipeline time: 3-5 minutes for most projects.

9. Making It Work — Culture, Not Just Tools

We've seen teams with world-class tooling and terrible security outcomes. The tools only work if the culture supports them.

Anti-Pattern What Happens Better Approach
Block on every finding Developers add # nosemgrep everywhere Block on critical/high only, track rest as tech debt
Security team owns all findings 3-month backlog, developers uninvolved Developer who wrote the code fixes it, security team advises
Security review as gate 2-week review queue, bypassed for "urgent" releases Automated checks + security champions in each team
Only scan main branch Vulnerabilities found after deploy Scan on every PR — fix before merge
No triage process 500 open findings, no one looks at them Weekly triage: classify, prioritize, assign, SLA

Security champions are the most effective cultural change we've seen. Pick one developer per team who:

What We've Learned at Pillai Infotech

The metric that matters isn't "number of vulnerabilities found" — it's "mean time to remediate." We track MTTR by severity. Our target: critical findings fixed within 24 hours, high within a week. When MTTR starts creeping up, it's usually a culture problem (developers ignoring findings) not a tooling problem. The fix is always the same: make findings visible in the PR, not in a separate dashboard nobody checks.

10. Frequently Asked Questions

How much does DevSecOps slow down CI/CD?

With parallel execution, 2-5 minutes for SAST + SCA + secrets scanning. That's less than most test suites. DAST adds 10-30 minutes but runs on staging after merge, not blocking PRs. If your security pipeline takes longer than your test suite, something is misconfigured.

Should we use Snyk, GitHub Advanced Security, or open-source tools?

Start with open-source (Semgrep + Trivy + gitleaks). They cover 80% of use cases. Move to paid tools (Snyk, GitHub Advanced Security) when you need: fix suggestions with auto-PRs, reachability analysis (is the vulnerable code actually called?), compliance reporting, or SLA-backed vulnerability databases. Most teams under 50 developers do fine with open-source.

How do we handle false positives?

Suppress with inline comments (// nosemgrep: rule-id) and require a justification. Track suppressions — if one rule generates more suppressions than real findings, tune or disable it. Review suppressions quarterly. A tool with 50% false positive rate will be ignored within a month.

What if we're using a monorepo?

Scope scans to changed paths. Most CI tools support path filters — only run Node.js SCA when package.json changes, only run Terraform scanning when *.tf files change. Trivy and Semgrep both support --include and --exclude patterns. Full repo scans run on a nightly schedule, not on every PR.

Where should we start if we have no security scanning?

Day 1: Add gitleaks pre-commit hook (prevents the most embarrassing class of bugs). Day 2: Add npm audit / trivy fs to CI (finds known vulnerabilities in dependencies). Week 2: Add Semgrep with default rulesets. That's 80% of the value in under a week. Add DAST and container scanning as you mature. See our CI/CD pipeline guide for the full pipeline setup.

🔒

Pillai Infotech LLP

We integrate security into every pipeline we build — from CI/CD setup to cloud security hardening. Let's secure your pipeline.

Related Articles

Cybersecurity Best Practices for Software Development Teams → CI/CD Pipeline Best Practices: From Code to Production → Cloud Security: Protecting Your AWS, Azure, and GCP Infrastructure →

Pillai Infotech Engineering Team

We build production software across AI, cloud, web, and mobile — sharing real-world insights from projects delivered for startups and enterprises across India and globally.

Need Help Setting Up DevSecOps?

From security pipeline design to tool selection and developer training, we help teams embed security without slowing down delivery.

Get a Security Assessment Security Consulting