Skip to main content
Back to blog
DevSecOps CI/CD Security

How to Build a Modern DevSecOps Pipeline

· 6 min read

Introduction

Security can no longer be an afterthought in the development lifecycle. According to IBM’s 2024 report, the average cost of a data breach reaches $4.88 million, and vulnerabilities detected late in the process cost 6 to 10 times more to fix than during development.

At Nommade, we integrate security from the very first line of code through a comprehensive DevSecOps approach. In this article, we share our proven methodology for building a CI/CD pipeline that embeds security at every stage, without sacrificing delivery velocity.


DevSecOps Pipeline Architecture

Before diving into the details, here’s the high-level view of the pipeline we implement for our clients:

┌─────────┐    ┌─────────┐    ┌─────────┐    ┌──────────┐    ┌─────────┐    ┌─────────┐
│  CODE   │───▶│  BUILD  │───▶│  TEST   │───▶│ SECURITY │───▶│ DEPLOY  │───▶│ MONITOR │
│         │    │         │    │         │    │          │    │         │    │         │
│ • SAST  │    │ • SCA   │    │ • Unit  │    │ • DAST   │    │ • K8s   │    │ • Prom  │
│ • Lint  │    │ • Image │    │ • Integ │    │ • Pentest│    │ • Helm  │    │ • Alert │
│ • Secret│    │ • SBOM  │    │ • E2E   │    │ • Scan   │    │ • GitOps│    │ • SIEM  │
└─────────┘    └─────────┘    └─────────┘    └──────────┘    └─────────┘    └─────────┘

Each stage acts as a guardrail: if a check fails, the pipeline stops and the team is notified immediately. This is the “shift-left” principle — moving problem detection as early as possible in the lifecycle.


The 6 Pillars of the Pipeline

1. Static Application Security Testing (SAST)

Static analysis detects vulnerabilities directly in the source code, before execution. It’s the first line of defense.

What we detect:

  • SQL injections, XSS, CSRF
  • Hardcoded secrets (API keys, passwords)
  • Poor cryptographic practices
  • OWASP Top 10 violations
# .gitlab-ci.yml — SAST Stage
sast:
  stage: test
  image: sonarsource/sonar-scanner-cli
  script:
    - sonar-scanner
      -Dsonar.projectKey=$CI_PROJECT_NAME
      -Dsonar.sources=./src
      -Dsonar.qualitygate.wait=true
  allow_failure: false
  rules:
    - if: $CI_MERGE_REQUEST_ID

Additionally, we integrate secret scanning to prevent accidental leaks:

secret-detection:
  stage: test
  image: trufflesecurity/trufflehog:latest
  script:
    - trufflehog git file://. --since-commit HEAD~1 --fail

Recommended tools by context:

ToolStrengthsBest for
SonarQubeMulti-language, quality gatesEnterprise teams
SemgrepCustom rules, very fastStartups / fast CI
CodeQLDeep semantic analysisOpen-source projects
TruffleHogSecret detectionEvery project

2. Software Composition Analysis (SCA)

Third-party dependencies are often the most underestimated attack vector. The Log4Shell incident (2021) was a stark reminder of how critical dependency monitoring is.

Our approach combines multiple verification levels:

dependency-check:
  stage: test
  script:
    # npm package audit
    - npm audit --audit-level=high
    # Multi-format scan with Trivy
    - trivy fs --severity HIGH,CRITICAL --exit-code 1 .
    # SBOM generation (Software Bill of Materials)
    - syft . -o cyclonedx-json > sbom.json
  artifacts:
    reports:
      dependency_scanning: gl-dependency-scanning-report.json
    paths:
      - sbom.json

The SBOM (Software Bill of Materials) has become a standard required by many regulations. It documents all software components used and facilitates traceability in case of an incident.

3. Container Image Scanning

Before deploying a Docker image, it’s essential to scan its layers for known vulnerabilities (CVEs). An image based on an unpatched OS can expose your entire infrastructure.

container-scan:
  stage: security
  image: aquasec/trivy
  script:
    - trivy image
      --exit-code 1
      --severity HIGH,CRITICAL
      --ignore-unfixed
      $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

Docker image best practices:

  • Use minimal base images (Alpine, Distroless)
  • Apply the principle of least privilege (non-root USER)
  • Pin base image versions
  • Regularly update base images

4. Dynamic Application Security Testing (DAST)

Dynamic tests simulate real attacks on the application deployed in a staging environment. Unlike SAST which analyzes source code, DAST tests the application while it’s running.

dast:
  stage: security
  image: ghcr.io/zaproxy/zaproxy:stable
  script:
    - zap-baseline.py
      -t $STAGING_URL
      -r zap-report.html
      -l WARN
      -I
  artifacts:
    paths:
      - zap-report.html
  needs:
    - deploy-staging

DAST detects vulnerabilities that SAST cannot see: server configuration errors, missing security headers, CORS issues, etc.

5. Infrastructure as Code Security

Terraform, Ansible, and other IaC tools must also be audited. A public S3 bucket or an overly permissive security group can compromise your entire infrastructure.

iac-scan:
  stage: security
  script:
    # Terraform scan
    - checkov -d ./terraform --framework terraform --compact
    # Best practices verification
    - tfsec ./terraform --minimum-severity HIGH
    # Ansible validation
    - ansible-lint playbooks/

Critical rules to verify:

  • No plaintext credentials in IaC files
  • Encryption enabled on all volumes and databases
  • Network access restricted (no 0.0.0.0/0 on sensitive ports)
  • Logging and monitoring enabled on all services

6. Monitoring and Incident Response

The pipeline doesn’t stop at deployment. Continuous monitoring is essential to detect abnormal behavior in production.

# Prometheus alerting rules
groups:
  - name: security-alerts
    rules:
      - alert: HighErrorRate
        expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.1
        for: 5m
        labels:
          severity: critical
        annotations:
          summary: "High error rate detected"

      - alert: UnusualTrafficSpike
        expr: rate(http_requests_total[5m]) > 10 * avg_over_time(rate(http_requests_total[5m])[1h:5m])
        for: 2m
        labels:
          severity: warning

Success Metrics

Here are the indicators we track to measure DevSecOps pipeline effectiveness:

MetricBeforeAfterImprovement
Vulnerability detection timeWeeksMinutes~99%
Average fix costHigh (post-prod)Low (pre-merge)-85%
Security coverageManual, partialAutomated, 100%+100%
Deployment timeHoursMinutes-70%
False positivesHighCalibrated-60%

Conclusion

Integrating security into the CI/CD pipeline is not a drag on velocity — it’s an investment that significantly reduces the cost of fixing vulnerabilities and protects your company’s reputation.

Key takeaways:

  1. Shift-left: detect problems as early as possible
  2. Automate: eliminate error-prone manual checks
  3. Block: a pipeline that doesn’t block critical vulnerabilities is useless
  4. Measure: track metrics to continuously improve
  5. Train: educate developers on security best practices

At Nommade, we’ve been helping our clients through this transformation for over 5 years. Whether you’re starting your DevSecOps journey or looking to strengthen an existing pipeline, we can help.

Contact us to discuss your project →