Detect Security Issues Fast: A Practical DevSecOps Guide

The idea behind DevSecOps is that Security should move at the speed of development and not as an after thought.

Introduction

The idea behind DevSecOps is that Security should move at the speed of development and not as an after thought. This can be achieved by using a set of automation practices that integrate security into delivery without creating friction with the development team. By adopting this mindset and workflow you provide security training to your team, and remove part of the mental fatigue.

The goal of this article is to provide a high level overview of a CI/CD secure workflow that teams can implement today.

So why does it matter to the business?

First of all, it protects from production incidents. No need to worry that your production is down, or that you expose your clients' data, it reduces risk early, and it saves you time, money and reputation.

As a side effect, it also improves the confidence of the development team.

Depending on your business niche, you will also meet different compliance frameworks, and these automation flows will help you stay compliant and produce the artefacts needed to be certified.

If you'd ask me, you get a pretty great deal.

The pipeline

There is application code, and infrastructure code. If you do not use Git, you need to start using Git, and if you do not keep them separated, you need to start keeping them separated.

The pipeline is simple: you have a CI (Continuous Integration) stage and a CD (Continuous Deployment) stage for both of them.

In the CI phase the goal is to catch issues early (before you deploy them). In the CD phase the goal is to ship without problems.

OWASP DevSecOps pipeline view
Pipeline view, source: OWASP DevSecOps Guideline

High level flow

The flow is the following:

For App Code

CI:
App Code -> Secret scanning -> Software composition analysis -> Static Code Security Analysis -> Container scanning

CD:
Deploy staging -> DAST -> Deploy to prod

For Infra Code

CI:
IaC -> secret scanning -> infrastructure-as-code scanning

CD:
deploy staging -> Infra scanning -> Deploy prod

Below we'll touch briefly on each of these phases and mention practical tooling and how each item ties back to faster detection and business outcomes.

Secrets Scanning

This applies to both App Code and Infrastructure as Code (IaC).

You need to scan your repositories for secrets, you do not want to leak them to the world! Tools such as gitleaks, git-secrets, or GitHub Advanced Security help detect leaked credentials early in the workflow.

Example workflow: .github/workflows/secret-scan.yml
name: Secret Scan on Commit

on:
  push:
    branches:
      - '**'  # This will trigger on any branch
  pull_request:
    branches:
      - '**'  # This will trigger on PRs from any branch

jobs:
  secret-scan:
    runs-on: ubuntu-latest

    steps:
      # Checkout the code
      - name: Checkout code
        uses: actions/checkout@v3

      # Download the GitLeaks binary (pinned SHA version)
      - name: Install GitLeaks
        run: |
          curl -sSL https://github.com/zricethezav/gitleaks/releases/download/v8.9.1/gitleaks-linux-amd64 -o /usr/local/bin/gitleaks
          chmod +x /usr/local/bin/gitleaks

      # Run GitLeaks to scan for secrets in the Python code
      - name: Run GitLeaks scan
        run: |
          gitleaks detect --source=. --exit-code=1 --verbose

Software Composition Analysis (SCA)

This applies to App Code.

The goal is to catch vulnerable software libraries within your application dependencies before they are deployed. Tools such as Dependabot, Snyk, or OWASP Dependency-Check can automate this process.

Let’s go with Dependabot as it has native GitHub support. Create the file:

.github/dependabot.yml

And add the following YAML configuration (example for Python). It will scan weekly.

Example configuration: .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "pip"
    directory: "/"  # Path to requirements.txt
    schedule:
      interval: "weekly"

SAST - Static Application Security Testing

This applies to App Code.

The goal is to find insecure code patterns within code written in-house (or introduced via supply chain). Tools such as Bandit, Semgrep, or SonarQube are common options. For Python, we'll use Bandit by PyCQA.

.github/workflows/sast.yml
Example workflow: .github/workflows/sast.yml
name: Bandit

on:
  pull_request:
    branches:
      - staging  # runs when PR targets 'staging' branch

jobs:
  analyze:
    runs-on: ubuntu-latest
    permissions:
      # required for all workflows
      security-events: write
      # only required for workflows in private repositories
      actions: read
      contents: read
    steps:
      - name: Perform Bandit Analysis
        uses: PyCQA/bandit-action@v1

Container Scanning

This applies to App Code.

The last check in the CI flow is container scanning. Some Docker images may contain vulnerabilities in system libraries. This matters because your application or its dependencies may call into these libraries, if they are compromised, your entire service can be exploited.

For example, if there’s a critical vulnerability in your image’s OpenSSL package and your Python web server relies on it for secure connections, an attacker could exploit that flaw to bypass encryption and expose data. Serious stuff.

Common tools for container scanning include Grype, Trivy, and Clair.

.github/workflows/container-scan.yml
Example workflow: .github/workflows/container-scan.yml
name: Container Scan - Grype

on:
  pull_request:
    branches: ['**']

jobs:
  grype-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install Grype
        run: |
          curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin

      - name: Build Docker image
        run: docker build -t my-app:latest .

      - name: Scan image with Grype
        run: grype my-app:latest --fail-on high

Infrastructure as Code Scanning (IaC Scanning)

Still part of the CI phase, the goal is to detect misconfigurations in Terraform, CloudFormation, and other infrastructure-as-code frameworks. You don’t want to give admin rights to everyone or let anyone deploy anything to production unchecked.

For this example, we’ll use tfsec, a popular open-source static analysis tool for Terraform.

.github/workflows/iac-scanning.yml
Example workflow: .github/workflows/iac-scanning.yml
name: IaC Scan - tfsec

on:
  pull_request:
    branches:
      - '**'

jobs:
  tfsec-scan:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Install tfsec
        run: |
          curl -sSL https://raw.githubusercontent.com/aquasecurity/tfsec/master/scripts/install_linux.sh | bash

      - name: Run tfsec scan
        run: tfsec .

The CD Phase

This phase focuses on validating that your deployed environments are secure before promoting changes to production. The goal is to run Dynamic Application Security Testing (DAST) on the staging environment for application code, and perform infrastructure scanning for IaC deployments.

Only when all checks are green should deployment to production proceed. As a bonus, you can also apply compliance baselines automatically during this stage.

Compliance & Continuous Auditing

For frameworks such as PCI DSS, ISO 27001, and SOC 2, there are policy-as-code tools that can automate continuous compliance verification. These tools allow you to codify compliance requirements, turning audits into continuous, automated checks rather than painful manual efforts.

This approach aligns technical automation with governance, risk, and compliance goals, which is a key benefit for mature DevSecOps teams.

Conclusion

To conclude, you add the DevSecOps flow once, and then your team operates it as a feedback loop, always improving and adapting to business needs. This continuous flow connects development, security, and operations, increasing the overall maturity of the organization.

Teams should start with small, easy steps and gradually expand. Integrating even a few CI scans in your GitHub workflows provides immediate benefits by catching issues early and establishing a security-aware engineering culture.