Module 12 of 16

Secure CI/CD Pipelines

Harden GitHub Actions, protect secrets, isolate pipelines, and implement secure deployment workflows

3 hours2 labsFree

Start here

Learning objectives

  • Identify CI/CD threat vectors
  • Harden GitHub Actions workflows
  • Implement pipeline isolation and secret scanning
  • Deploy securely with signed artifacts and workload identity
SECURE CI/CD PIPELINECode PushSecret Scangitleaks/trufflehogBuild + TestIsolated runnerSign + SBOMCosign + SyftDeploy (OIDC)No static secretsSecurity Controls at Each StageBranch protectionSigned commitsPre-commit hooksCredential detectionPinned actionsMinimal permissionsImage signingOIDC auth (no secrets)Every stage has controls. Compromise of one stage does not compromise the full pipeline.

CI/CD pipelines have privileged access to production systems. They pull source code, build artifacts, push to registries, and deploy to clusters. A compromised pipeline is a direct path to production compromise.

CI/CD Threat Vectors

  • Poisoned pipeline execution: Malicious PR modifies workflow to exfiltrate secrets
  • Dependency confusion: Attacker publishes a package with the same name as an internal one
  • Leaked secrets: API keys printed in logs, exposed in artifacts, or committed to Git
  • Unpinned actions: Third-party GitHub Actions updated with malicious code
  • Over-permissioned runners: CI runners with cluster-admin access

Hardening GitHub Actions

# Secure GitHub Actions workflow
name: Secure Build
on:
  push:
    branches: [main]

permissions:
  contents: read        # Minimal! Not write
  packages: write       # Only for pushing images
  id-token: write       # For OIDC auth (no static secrets)

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4    # Pin to exact SHA in production
      - name: Secret Scan
        run: gitleaks detect --source . --verbose
      - name: Build
        run: docker build -t myapp .
      - name: Sign Image
        run: cosign sign ghcr.io/myorg/myapp:latest
      - name: Deploy via OIDC (no secrets!)
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123:role/deploy
          aws-region: us-east-1
          # No AWS_ACCESS_KEY_ID! OIDC temporary credentials only

Real world

Where this shows up

  • Hardening GitHub Actions for production deployments
  • OIDC-based cloud authentication (zero static secrets)
  • Secret scanning in pre-commit hooks
  • Secure artifact signing in CI pipelines

Common mistakes

What usually breaks

  • Using permissions: write-all in workflows
  • Storing cloud credentials as repository secrets instead of OIDC
  • Not scanning for leaked secrets before they reach the main branch
  • Using unpinned action versions (uses: actions/checkout@main instead of SHA)

Key terms

Vocabulary used in this module

OIDC

OpenID Connect — used for keyless authentication from CI to cloud

gitleaks

Tool for detecting hardcoded secrets in Git repositories

Branch Protection

GitHub rules requiring reviews, status checks, and signed commits

Pinned Actions

Referencing GitHub Actions by commit SHA instead of mutable tags

Labs

Hands-on labs

30 minIntermediate

Harden a GitHub Actions Workflow

Apply security best practices to a CI/CD pipeline.

  1. Audit an insecure workflow (over-permissioned, unpinned actions)
  2. Add minimal permissions, pin action versions to SHA
  3. Add secret scanning with gitleaks
  4. Configure OIDC for deployment (eliminate static secrets)
View lab on GitHub
35 minAdvanced

Implement Secure Deployment Pipeline

Build a pipeline that signs, scans, and deploys with verification.

  1. Build and sign images with Cosign in CI
  2. Generate SBOM and scan for CVEs
  3. Configure admission controller to reject unsigned images
  4. Deploy using OIDC workload identity (zero static secrets)
View lab on GitHub

Recap

Key takeaways

  • CI/CD pipelines are high-value targets — they have production access
  • Use minimal permissions on every workflow — never write when read is enough
  • Pin all third-party actions to specific commit SHAs
  • Use OIDC for cloud authentication — eliminate all static secrets from CI
  • Sign every artifact in CI, verify every artifact before deploying

Related resources

Keep learning across CodersSecret