Software Engineering·July 21, 2026·4 min read

CI/CD Security and Supply Chain

How to protect your deployment pipeline and the software it produces — keeping secrets safe, scanning dependencies, and understanding where attacks actually happen.

cicdsecuritydevsecopssupplychaindeployment

Your CI/CD pipeline is the system that automatically builds and deploys your code every time you push a change. It's powerful — and because it holds your deployment credentials and can push directly to production, it's also one of the most valuable things an attacker could compromise. If Cartara flagged this in your diff, you likely have a pipeline configuration that touches secrets, runs third-party code, or deploys to a live environment — and there are safer patterns worth knowing.

Two Separate Problems

"CI/CD security" is actually two distinct concerns that are easy to conflate:

The pipeline itself. Your CI system has credentials — keys to your cloud accounts, your database, your production environment. A compromised pipeline is a direct path to your live app.

The software supply chain. Most of the code in your app isn't code you wrote — it's open-source dependencies. Attackers increasingly tamper with those packages, or inject malicious code into build processes, rather than attacking your running application directly.

The core idea is called "shift left": catch security problems early in the pipeline (when they're cheap to fix), not after they've reached production.

Security Checks That Run Automatically

These are gates you add to your pipeline, the same way you add automated tests. They run on every push and block deploys if they find problems:

Dependency scanning (SCA) checks your third-party packages against a database of known vulnerabilities. Tools like Dependabot (built into GitHub, free) and Renovate do this automatically and open pull requests when vulnerable packages are found. Turn this on first — it's the highest-value, lowest-effort security improvement available.

Secret scanning catches API keys and credentials that were accidentally committed to your repo. GitHub has this built in. Services like GitGuardian go further. A leaked key in a commit history is a serious incident waiting to happen.

Static analysis (SAST) scans your source code for patterns associated with security bugs — without running it.

Container image scanning checks your Docker images for known vulnerabilities in base OS packages. Trivy and Snyk are common tools here.

The Supply Chain Problem

In 2020, attackers compromised SolarWinds by injecting malicious code into its build process — the software then went out to thousands of customers with a legitimate signature, as if nothing was wrong. This is a supply chain attack: rather than hacking the live system, you compromise how the software is assembled.

The defenses are practical:

Lock your dependency versions. Use lockfiles (package-lock.json, yarn.lock, Pipfile.lock) and don't ignore them. They pin exact versions and checksums so a package can't silently be swapped for a malicious one.

Pin third-party pipeline actions. If you use GitHub Actions, the actions you pull in (like actions/checkout) are themselves part of your supply chain. Pin them to a specific commit SHA rather than a floating tag like @v3.

SBOM (Software Bill of Materials). A manifest listing every component in your built artifact. When a new vulnerability is announced, an SBOM lets you answer "are we affected?" in minutes.

Artifact signing. Cryptographically sign what you build so anyone deploying it can verify it wasn't tampered with. Sigstore / cosign is the open-source standard.

The SLSA Framework

SLSA (pronounced "salsa") is an industry checklist for build integrity. Each level adds stronger guarantees about how your software was produced:

LevelWhat It Means
L0No guarantees — local builds only
L1Build system automatically records how the artifact was built
L2Builds run on a hosted CI service (GitHub Actions, etc.), which signs the build record
L3Strong protections against tampered build records, even if credentials are compromised

If you already build on GitHub Actions or a similar hosted CI service, you're most of the way to L2 without any extra work.

Keeping the Pipeline Itself Safe

Least privilege. Each job in your pipeline should only have the permissions it needs. A job that runs tests has no business with production deploy credentials. Scope tightly.

Store secrets in the platform's encrypted store. Never hardcode a secret in a workflow file. Inject secrets at runtime from GitHub Secrets, your cloud's secret manager, or a tool like Doppler.

Be careful with pull requests from forks. If your repo is public, anyone can open a PR. Don't run untrusted PR code with access to your production secrets. Most platforms let you require approval before running workflows on outside contributions — enable that.

Review pipeline config like code. Your .github/workflows/ files live in version control. They should go through the same review process as your application code, because they have just as much access.

What You'll See in Your Code

A GitHub Actions workflow that scans dependencies and checks for secrets on every push:

name: Security Checks

on: [push, pull_request]

jobs:
  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@a81bbbf8298c0fa03ea29cdc473d45769f953675  # pinned to commit, not tag
      
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@master
        with:
          scan-type: 'fs'
          scan-ref: '.'
          severity: 'CRITICAL,HIGH'

      - name: Check for secrets
        uses: gitleaks/gitleaks-action@v2

Scoping secrets so only the deploy job can access production credentials:

jobs:
  test:
    runs-on: ubuntu-latest
    # No secrets here — tests don't need production access
    steps:
      - run: npm test

  deploy:
    needs: test
    runs-on: ubuntu-latest
    environment: production  # Only this job gets production secrets
    steps:
      - run: npm run deploy
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}

Related concepts

CI/CD Basics
CI/CD automates the process of testing and shipping code. This guide explains continuous integration, continuous deployment, how pipelines work, and how to set one up.
Deployment Strategies
A deployment strategy controls how a new version of your app reaches users — all at once, gradually, or behind a feature flag. This guide explains the main approaches and when to use each.
Security Best Practices for Vibe Coders
The most common security mistakes when building with AI tools — and how to avoid them. Covers API keys, environment variables, database security, authentication, and frontend vs. backend.

Turn shipping into understanding

Cartara measures what your team actually learns from every AI coding session.

Join the waitlist