DevSecOps: Making Security an Engineering Problem, Not a Gate

DevSecOps: Making Security an Engineering Problem, Not a Gate

The traditional model of security in software development goes like this: developers build a feature over several weeks, the security team reviews it before release, security finds problems, developers are unhappy about the last-minute rework, security is portrayed as “slowing things down,” and everyone resents everyone else.

DevSecOps is the recognition that this model is broken, not because security teams are incompetent, but because the feedback loop is too long. Security issues found in code review or penetration testing are expensive to fix. Security issues found at commit time are cheap. The entire DevSecOps philosophy is about moving security feedback as far left as possible.

Shifting Left in Practice

“Shift left” means finding issues earlier in the development lifecycle. The spectrum:

  • Development: Pre-commit hooks, IDE plugins (cheap to fix)
  • CI/CD: SAST, SCA, secret scanning, IaC scanning (cheap)
  • Pre-production: DAST, container scanning, penetration testing (moderate)
  • Production: Runtime security monitoring (expensive to fix)

Most organizations invest heavily in pre-production and production security while neglecting the development and CI/CD phases. This is backwards.

SAST: Static Application Security Testing

SAST analyzes your source code for security vulnerabilities without executing it. For Java, the options include:

Semgrep (my preference): Rule-based static analysis with a huge library of open-source security rules. Fast enough to run in CI, extensive Java rule sets, customizable.

# GitHub Actions
- name: SAST - Semgrep
  uses: semgrep/semgrep-action@v1
  with:
    config: p/java
    generateSarif: "1"
- name: Upload SARIF to GitHub
  uses: github/codeql-action/upload-sarif@v3
  with:
    sarif_file: semgrep.sarif

SpotBugs with FindSecBugs: Bytecode analysis that catches security issues that source-level tools miss. Runs as a Maven or Gradle plugin.

<!-- Maven -->
<plugin>
    <groupId>com.github.spotbugs</groupId>
    <artifactId>spotbugs-maven-plugin</artifactId>
    <configuration>
        <plugins>
            <plugin>
                <groupId>com.h3xstream.findsecbugs</groupId>
                <artifactId>findsecbugs-plugin</artifactId>
                <version>LATEST</version>
            </plugin>
        </plugins>
    </configuration>
</plugin>

Run SAST on every PR. Gate the merge if critical issues are found. Don’t gate on every warning—tune your rules to reduce noise first, then tighten the gate.

SCA: Software Composition Analysis

Your application is mostly third-party dependencies. Those dependencies have CVEs. SCA tools track which dependencies you’re using and which CVEs affect them.

OWASP Dependency-Check: Free, integrates with Maven/Gradle/npm, outputs HTML and XML reports.

# Gradle
plugins {
    id 'org.owasp.dependencycheck' version '9.0.9'
}

dependencyCheck {
    failBuildOnCVSS = 7  // Fail on HIGH and CRITICAL
    suppressionFile = 'dependency-check-suppressions.xml'
}

Trivy: Does SCA plus container image scanning. Run in CI to catch known CVEs:

# Scan a container image
trivy image --exit-code 1 --severity HIGH,CRITICAL myapp:latest

# Scan filesystem (source/dependencies)
trivy fs --exit-code 1 --severity HIGH,CRITICAL .

Snyk: Commercial, excellent developer experience, integrates with GitHub/GitLab for automatic PR comments when vulnerabilities are found.

The key practice: have a suppression/exception process for false positives and unfixable issues, but audit that list regularly. Suppressions that were “temporary” two years ago are still in the file.

Secret Scanning

Secrets in code are a persistent, underestimated problem. Developers accidentally commit API keys, database passwords, and certificates. These get pushed to GitHub, discovered by automated scanners, and you have an incident.

GitHub Secret Scanning: Built-in, free for public repos, catches common secret patterns (AWS keys, GCP service accounts, Stripe keys, etc.).

Gitleaks: Scan your repo’s entire history for secrets:

# Scan full git history
gitleaks detect --source . --report-format json --report-path gitleaks-report.json

# Pre-commit hook
gitleaks protect --staged
# .gitleaks.toml - customize rules
[allowlist]
description = "Global allowlist"
paths = [
    ".gitleaks.toml",
    "test-fixtures/fake-secret.txt"
]

Install Gitleaks as a pre-commit hook so developers never commit secrets in the first place:

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

Infrastructure as Code Scanning

Your Terraform, Kubernetes manifests, Helm charts, and Dockerfiles all have security implications. Scan them:

Checkov (Bridgecrew/Palo Alto): IaC security scanner supporting Terraform, CloudFormation, Kubernetes, Helm, Dockerfiles, and more.

# Scan Helm charts
checkov -d ./my-chart --framework helm

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

# Scan Terraform
checkov -d ./terraform --framework terraform

Hadolint specifically for Dockerfiles:

hadolint Dockerfile

Common Dockerfile issues Hadolint catches:

  • apt-get install without pinned versions
  • Running as root
  • Not using --no-install-recommends on apt installs
  • Copying .git into the image
  • Missing HEALTHCHECK

Container Image Scanning

Container images accumulate CVEs over time. Even if you started with a clean image, the base OS packages age. Scan images both in CI (on build) and in the registry (continuously):

# Trivy in CI
- name: Scan container image
  run: |
    trivy image \
      --exit-code 1 \
      --ignore-unfixed \
      --severity CRITICAL \
      --format sarif \
      --output trivy-results.sarif \
      $

For registry-wide scanning, Trivy operator can run in your Kubernetes cluster and continuously scan all running images, reporting findings as Kubernetes CRDs you can query with kubectl.

Policy as Code

For Kubernetes, policy enforcement at admission time prevents misconfiguration from reaching the cluster. Options:

Kyverno: Kubernetes-native policy engine. Rules are Kubernetes YAML.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: disallow-latest-tag
spec:
  validationFailureAction: enforce
  rules:
    - name: require-image-tag
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "Using ':latest' image tag is not allowed."
        pattern:
          spec:
            containers:
              - image: "!*:latest"

OPA/Gatekeeper: More flexible, uses Rego policy language. Steeper learning curve, more powerful.

The Security Champion Model

DevSecOps at the organizational level requires embedding security knowledge in development teams, not keeping it centralized in a security silo. Security champions—developers with security interest and training who serve as the first line of security review within their team—bridge the gap.

The tools and pipeline are necessary but not sufficient. If developers don’t understand why Semgrep flagged their code, they’ll add suppressions rather than fix the issue. Security education, embedded in the team, makes the tooling meaningful.

Building the Security Pipeline

Minimal viable security pipeline:

security:
  stage: security
  parallel:
    matrix:
      - SCAN_TYPE: sast
        COMMAND: semgrep --config p/java .
      - SCAN_TYPE: secrets
        COMMAND: gitleaks detect --no-git .
      - SCAN_TYPE: sca
        COMMAND: trivy fs --severity HIGH,CRITICAL .
      - SCAN_TYPE: iac
        COMMAND: checkov -d . --framework kubernetes,helm
  script:
    - $COMMAND

Run all scans in parallel. Gate the pipeline on critical findings. Review and tune the rules regularly. This is the baseline from which you build a mature DevSecOps practice.

Security baked into the pipeline isn’t a tax on development velocity—it’s the thing that makes velocity sustainable without accumulating security debt that will eventually have to be paid.

Share this post: LinkedIn Reddit WhatsApp Mastodon
Jesse Borden

Jesse Borden

Software Engineer with an interest in hands on learning

I have several years of professional Information Technology (IT) experience leading staff and projects within the Department of War (DOW). I have managed Service Desk, Web Application Development, and System Administration teams. My two greatest passions are learning and conti...