Creating your First Secure CI/CD Pipeline with GitHub Actions

GitHub Actions CDCI Pipeline

In the world of DevOps, security is paramount. With the rise of continuous integration and continuous delivery (CI/CD), integrating security checks into the pipeline is a critical step. In this blog post, I'll guide you through setting up a CI/CD pipeline on GitHub with robust security analysis stages using some of the best open-source tools available.

Understanding the Pipeline Stages

Before we dive into the setup, let's understand what each stage represents:

  • Static Application Security Testing (SAST): This stage reviews the source code for potential security vulnerabilities, coding flaws, and more.

  • Dynamic Application Security Testing (DAST): Unlike SAST, DAST tests the running application, simulating external attacks.

  • Software Composition Analysis (SCA): This checks for vulnerabilities within your project's dependencies and libraries.

  • Infrastructure as Code (IaC) Analysis: This ensures your infrastructure setup scripts follow security best practices.

  • Container Security: This stage scans your Docker containers for vulnerabilities and misconfigurations.

Setting Up Your GitHub Actions Workflow

Here's how you can set up a GitHub Actions workflow file that includes these critical security stages:

name: Our First CI/CD Pipeline with Security Stages

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
 SAST:
    name: Static Application Security Testing with Bandit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Bandit
        run: |
          docker run -v $(pwd):/src pyupio/bandit -r /src

  DAST:
    needs: SAST
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Start the application
        run: |
          # Start your application
      - name: Run DAST Tool
        run: |
          docker run -t owasp/zap2docker-stable zap-full-scan.py -t http://localhost -r zap_report.html

  SCA:
    needs: DAST
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run SCA Tool
        run: |
          docker run --rm -v $(pwd):/src owasp/dependency-check dependency-check.sh --project "YourProject" --scan "/src"

  IAC:
    needs: SCA
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run IaC Analysis Tool
        run: |
          docker run --rm -v $(pwd):/project bridgecrew/checkov -d /project

  CONTAINER_SECURITY:
    needs: IAC
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Container Security Tool
        run: |
          docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/project aquasec/trivy image <your_image_name>

Enhancing Security in CI/CD with GitHub Actions

When setting up a CI/CD pipeline, incorporating security checks is essential to ensure that the code and infrastructure you deploy are free from known vulnerabilities. GitHub Actions offers a flexible way to automate these checks by integrating various security tools directly into your workflow. Let's break down the stages of a CI/CD pipeline that includes comprehensive security checks.

Static Application Security Testing (SAST)

The SAST stage is where the static analysis of the source code occurs. This process doesn’t require the application to be running. It’s aimed at detecting potential security vulnerabilities, coding flaws, and quality issues early in the development process.

In our pipeline, we use an open-source tool, such as Bandit, to perform the SAST:

jobs:
 SAST:
    name: Static Application Security Testing with Bandit
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Bandit
        run: |
          docker run -v $(pwd):/src pyupio/bandit -r /src

Dynamic Application Security Testing (DAST)

Following SAST, we have the DAST stage. DAST tools interact with a running instance of the application, attempting to exploit common vulnerabilities such as cross-site scripting or SQL injection. This simulates an external attack on the application to find runtime security issues.

We utilize OWASP ZAP for DAST in our pipeline:

  DAST:
    needs: SAST
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Run DAST Tool
        run: |
          docker run -t owasp/zap2docker-stable zap-full-scan.py -t http://localhost ...

Software Composition Analysis (SCA)

SCA tools are crucial for detecting known vulnerabilities in open-source libraries and dependencies. This step helps developers to update or replace dependencies that could make the application susceptible to attacks.

In the pipeline, OWASP Dependency-Check serves this purpose:

  SCA:
    needs: DAST
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run SCA Tool
        run: |
          docker run --rm -v $(pwd):/src owasp/dependency-check dependency-check.sh --project "YourProject" --scan "/src"

Infrastructure as Code (IaC) Analysis

With the adoption of cloud services, managing infrastructure using code has become prevalent. IaC analysis tools ensure that the scripts defining infrastructure adhere to security best practices.

For IaC analysis, we use Checkov:

  IAC:
    needs: SCA
    runs-on: ubuntu-latest
    steps:
      ...
      - name: Run IaC Analysis Tool
        run: |
          docker run --rm -v $(pwd):/project bridgecrew/checkov -d /project

Container Security

Finally, container security scanning is vital as it checks the Docker container images for known vulnerabilities. This step is crucial because it ensures that the environment where the application runs is secure.

Trivy is used in the pipeline to scan the container images:

  CONTAINER_SECURITY:
    needs: IAC
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      - name: Run Container Security Tool
        run: |
          docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd):/project aquasec/trivy image <your_image_name>

Each of these stages builds upon the previous, ensuring that the code, its dependencies, the infrastructure it runs on, and the containers that encapsulate it are all subject to rigorous security scrutiny. By integrating these tools into your GitHub Actions pipeline, you can automate the process of identifying and addressing security issues, leading to a more robust and secure CI/CD process for a first time security integration in to your stack.

Choosing Your Tools

For each stage, you'll need to choose a tool. Here are some suggestions that I have used;

  • SAST: Use SonarQube or Semgrep.

  • DAST: OWASP ZAP or Arachni are good choices.

  • SCA: Try OWASP Dependency-Check or Snyk.

  • IaC Analysis: Checkov and Terrascan are excellent options.

  • Container Security: Trivy and Clair are top picks.

Configuring the Tools

Each tool comes with its own set of configurations. You'll need to set up the tools with the correct command-line arguments, environment variables, and configuration files specific to your project's needs. Ensure you handle sensitive data such as tokens and API keys securely, preferably using GitHub's secrets feature.

Final Thoughts

Integrating security into your CI/CD pipeline doesn't just reduce the risk of vulnerabilities slipping through the cracks; it embeds a security-first mindset into your development process.

While the above workflow serves as a template, your pipeline should evolve with your project's complexity and needs.

Stay secure and happy coding!

Previous
Previous

Nginx Security Configuration Review

Next
Next

Intercepting Non-Proxy Aware Mobile Applications