---
# === IDENTITY ===
id: software/security/secure-cicd-pipeline/2026
canonical_question: "How do I secure a CI/CD pipeline?"
aliases:
  - "CI/CD pipeline security best practices"
  - "secure continuous integration continuous delivery"
  - "harden CI/CD pipeline"
  - "DevSecOps pipeline security"
  - "GitHub Actions security hardening"
  - "GitLab CI security configuration"
  - "OWASP CI/CD top 10 risks"
  - "supply chain security CI/CD"
entity_type: software_reference
domain: software > security > Secure CI/CD Pipeline
region: global
jurisdiction: global
temporal_scope: 2024-2026

# === VERIFICATION ===
last_verified: 2026-02-27
confidence: 0.93
version: 1.0
first_published: 2026-02-27

# === TEMPORAL VALIDITY ===
temporal_validity:
  status: stable
  last_breaking_change: "SLSA v1.0 specification finalized (2023); GitHub Actions OIDC GA (2022); Sigstore Cosign v2 keyless signing default (2023)"
  next_review: 2026-08-26
  change_sensitivity: medium

# === CONSTRAINTS ===
constraints:
  - "NEVER store long-lived credentials (API keys, passwords) directly in pipeline configuration files or environment variables -- use a secrets manager (Vault, AWS Secrets Manager, OIDC federation)"
  - "NEVER run CI/CD build steps with root/admin privileges -- use least-privilege service accounts with scoped permissions"
  - "NEVER use mutable tags (latest, v1) to pin third-party actions or images -- pin to full-length commit SHA or verified digest"
  - "NEVER skip artifact integrity verification before deployment -- sign artifacts at build time and verify signatures before deploy"
  - "Self-hosted runners MUST NOT be used for public repositories without ephemeral/JIT configuration -- any fork can execute arbitrary code on the runner"

# === SKIP CONDITIONS ===
skip_this_unit_if:
  - condition: "Need to prevent XSS or web application vulnerabilities, not pipeline security"
    use_instead: "software/security/xss-prevention/2026"
  - condition: "Need container runtime security, not build pipeline security"
    use_instead: "software/security/container-runtime-security/2026"
  - condition: "Need Kubernetes cluster hardening, not CI/CD pipeline hardening"
    use_instead: "software/security/kubernetes-security/2026"

# === AGENT HINTS ===
inputs_needed:
  - key: "ci_platform"
    question: "Which CI/CD platform are you using?"
    type: choice
    options: ["GitHub Actions", "GitLab CI", "Jenkins", "CircleCI", "Azure DevOps", "Other"]
  - key: "cloud_provider"
    question: "Which cloud provider do you deploy to?"
    type: choice
    options: ["AWS", "GCP", "Azure", "Multi-cloud", "On-premises", "None"]
  - key: "maturity_level"
    question: "What is your current CI/CD security maturity?"
    type: choice
    options: ["No security controls", "Basic secrets management", "Some scanning in place", "Comprehensive DevSecOps"]

# === DISTRIBUTION ===
canonical_source: "https://knowledgelib.io/software/security/secure-cicd-pipeline/2026"
suggested_citation: "Source: knowledgelib.io -- AI Knowledge Library (verified 2026-02-27)"

# === RELATED UNITS ===
related_kos:
  depends_on: []
  related_to:
    - id: "software/security/xss-prevention/2026"
      label: "XSS Prevention Guide"
    - id: "software/security/container-runtime-security/2026"
      label: "Container Runtime Security"
  solves: []
  alternative_to: []
  often_confused_with:
    - id: "software/security/kubernetes-security/2026"
      label: "Kubernetes Security Hardening"
    - id: "software/security/container-runtime-security/2026"
      label: "Container Runtime Security"

# === SOURCES (7 authoritative sources) ===
sources:
  - id: src1
    title: "Top 10 CI/CD Security Risks"
    author: OWASP Foundation
    url: https://owasp.org/www-project-top-10-ci-cd-security-risks/
    type: community_resource
    published: 2024-01-15
    reliability: authoritative
  - id: src2
    title: "CI/CD Security Cheat Sheet"
    author: OWASP Foundation
    url: https://cheatsheetseries.owasp.org/cheatsheets/CI_CD_Security_Cheat_Sheet.html
    type: community_resource
    published: 2024-06-15
    reliability: authoritative
  - id: src3
    title: "Secure Use Reference - GitHub Actions"
    author: GitHub
    url: https://docs.github.com/en/actions/reference/security/secure-use
    type: official_docs
    published: 2025-12-01
    reliability: high
  - id: src4
    title: "Pipeline Security - GitLab CI/CD"
    author: GitLab
    url: https://docs.gitlab.com/ci/pipeline_security/
    type: official_docs
    published: 2025-10-01
    reliability: high
  - id: src5
    title: "SLSA - Supply-chain Levels for Software Artifacts"
    author: OpenSSF / SLSA
    url: https://slsa.dev/
    type: community_resource
    published: 2024-04-01
    reliability: high
  - id: src6
    title: "Defending CI/CD Environments"
    author: NSA / CISA
    url: https://media.defense.gov/2023/Jun/28/2003249466/-1/-1/0/CSI_DEFENDING_CI_CD_ENVIRONMENTS.PDF
    type: industry_report
    published: 2023-06-28
    reliability: authoritative
  - id: src7
    title: "Software Supply Chain Best Practices v2"
    author: CNCF TAG Security
    url: https://tag-security.cncf.io/community/working-groups/supply-chain-security/supply-chain-security-paper-v2/
    type: industry_report
    published: 2025-08-06
    reliability: high
---

# Secure CI/CD Pipeline: Hardening Guide

## TL;DR

- **Bottom line**: A secure CI/CD pipeline requires layered controls across six domains -- secrets management, access control (RBAC), artifact integrity (signing + SLSA provenance), security scanning (SAST/DAST/SCA), environment isolation, and audit logging.
- **Key tool/command**: `cosign sign --yes $IMAGE` for keyless artifact signing with Sigstore; OIDC federation for eliminating long-lived secrets.
- **Watch out for**: Storing secrets directly in pipeline config files or environment variables -- use OIDC federation or a dedicated secrets manager instead.
- **Works with**: GitHub Actions, GitLab CI, Jenkins, CircleCI, Azure DevOps, and any CI/CD platform supporting OIDC and webhook integrations.

## Constraints
<!-- Agents: read this section before recommending any action from this unit.
     These are hard constraints that must not be violated. -->

- NEVER store long-lived credentials (API keys, passwords) directly in pipeline configuration files or environment variables -- use a secrets manager (Vault, AWS Secrets Manager, OIDC federation)
- NEVER run CI/CD build steps with root/admin privileges -- use least-privilege service accounts with scoped permissions
- NEVER use mutable tags (latest, v1) to pin third-party actions or images -- pin to full-length commit SHA or verified digest
- NEVER skip artifact integrity verification before deployment -- sign artifacts at build time and verify signatures before deploy
- Self-hosted runners MUST NOT be used for public repositories without ephemeral/JIT configuration -- any fork can execute arbitrary code on the runner

## Quick Reference

**OWASP Top 10 CI/CD Security Risks:**

| # | Risk | Threat | Impact | Key Control |
|---|---|---|---|---|
| 1 | Insufficient Flow Control | No required reviews, direct push to production | Unreviewed malicious code deployed | Branch protection + mandatory PR reviews |
| 2 | Inadequate Identity & Access Management | Shared accounts, over-privileged tokens | Lateral movement, privilege escalation | RBAC + MFA + centralized IdP |
| 3 | Dependency Chain Abuse | Typosquatting, dependency confusion, hijacked packages | Malicious code in builds | Pin versions + lock files + SCA scanning |
| 4 | Poisoned Pipeline Execution (PPE) | Attacker modifies pipeline config via PR | Arbitrary code execution in CI | Restrict pipeline config changes + CODEOWNERS |
| 5 | Insufficient PBAC | Pipeline has admin-level cloud access | Full cloud account compromise | Scoped OIDC roles per pipeline/environment |
| 6 | Insufficient Credential Hygiene | Hardcoded secrets, stale API keys | Credential theft, unauthorized access | Secrets manager + rotation + OIDC |
| 7 | Insecure System Configuration | Default configs, unpatched runners | Runner compromise, crypto mining | Harden runners + ephemeral instances |
| 8 | Ungoverned 3rd Party Services | Unvetted integrations with broad access | Data exfiltration via OAuth apps | Audit integrations + minimal scopes |
| 9 | Improper Artifact Integrity | Unsigned images, unverified provenance | Tampered artifacts deployed to production | Cosign signing + SLSA provenance |
| 10 | Insufficient Logging & Visibility | No audit trail for pipeline changes | Cannot detect or investigate breaches | Centralized logging + SIEM alerts |

**Security Control Checklist:**

| # | Control Domain | Control | Tool/Approach | Priority |
|---|---|---|---|---|
| 1 | Secrets | Use OIDC federation instead of static secrets | GitHub OIDC, GitLab OIDC, AWS STS | Critical |
| 2 | Secrets | Rotate remaining secrets automatically | HashiCorp Vault, AWS Secrets Manager | Critical |
| 3 | Secrets | Scan for leaked secrets in commits | git-secrets, GitGuardian, Gitleaks | Critical |
| 4 | Access | Enforce RBAC with least-privilege | Platform-native RBAC + IdP | Critical |
| 5 | Access | Require MFA for all CI/CD accounts | SSO + TOTP/WebAuthn | Critical |
| 6 | Access | Protect branches + require PR reviews | Branch protection rules | High |
| 7 | Scanning | SAST in every PR | Semgrep, SonarQube, CodeQL | High |
| 8 | Scanning | Dependency/SCA scanning | Dependabot, Snyk, Trivy, Renovate | High |
| 9 | Scanning | Container image scanning | Trivy, Grype, Snyk Container | High |
| 10 | Scanning | DAST against staging | OWASP ZAP, Nuclei | Medium |
| 11 | Artifacts | Sign images with Cosign (keyless) | Sigstore Cosign + Fulcio + Rekor | High |
| 12 | Artifacts | Generate SLSA provenance | slsa-github-generator, in-toto | High |
| 13 | Artifacts | Verify signatures before deploy | Cosign verify, Kyverno, OPA | High |
| 14 | Isolation | Use ephemeral runners | GitHub-hosted, GitLab SaaS runners | High |
| 15 | Isolation | Network-segment build environments | VPC isolation, firewall rules | Medium |
| 16 | Logging | Centralize pipeline audit logs | SIEM (Splunk, Elastic, Datadog) | High |
| 17 | Logging | Alert on anomalous pipeline activity | SIEM rules + PagerDuty | Medium |

## Decision Tree

```
START: What is your most critical CI/CD security gap?
├── Secrets stored in plaintext or pipeline env vars?
│   ├── YES → Implement OIDC federation (Step 1) + secrets manager (Step 2)
│   └── NO ↓
├── No security scanning in the pipeline?
│   ├── YES → Add SAST + SCA + container scanning (Step 4)
│   └── NO ↓
├── Third-party actions/plugins not pinned or audited?
│   ├── YES → Pin actions to SHA + audit integrations (Step 3)
│   └── NO ↓
├── No artifact signing or provenance?
│   ├── YES → Implement Cosign signing + SLSA provenance (Step 5)
│   └── NO ↓
├── Using self-hosted runners for public repos?
│   ├── YES → Switch to ephemeral/JIT runners immediately (Step 6)
│   └── NO ↓
├── No audit logging or monitoring?
│   ├── YES → Deploy centralized logging + SIEM integration (Step 7)
│   └── NO ↓
└── DEFAULT → Review OWASP CI/CD Top 10 risks checklist above and address remaining gaps
```

## Step-by-Step Guide

### 1. Eliminate long-lived secrets with OIDC federation

OIDC (OpenID Connect) lets your CI/CD platform authenticate directly with cloud providers using short-lived tokens instead of storing static API keys. This eliminates the most common CI/CD credential theft vector. [src3]

**GitHub Actions with AWS OIDC:**

```yaml
# .github/workflows/deploy.yml
name: Deploy
on:
  push:
    branches: [main]

permissions:
  id-token: write   # Required for OIDC
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502  # v4.0.2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsDeployRole
          aws-region: us-east-1
          # No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY needed!
```

**AWS IAM Trust Policy for GitHub OIDC:**

```json
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
    },
    "Action": "sts:AssumeRoleWithWebIdentity",
    "Condition": {
      "StringEquals": {
        "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
      },
      "StringLike": {
        "token.actions.githubusercontent.com:sub": "repo:your-org/your-repo:ref:refs/heads/main"
      }
    }
  }]
}
```

**Verify**: `aws sts get-caller-identity` in the workflow should return the assumed role ARN, not a static IAM user.

### 2. Configure secrets management for remaining credentials

Some secrets cannot use OIDC (database passwords, third-party API keys). Store these in a dedicated secrets manager, never in pipeline config. [src2]

```yaml
# GitHub Actions: use encrypted secrets
steps:
  - name: Deploy
    env:
      DB_PASSWORD: ${{ secrets.PRODUCTION_DB_PASSWORD }}
    run: |
      # Secret is masked in logs automatically
      ./deploy.sh --db-password "$DB_PASSWORD"
```

```yaml
# GitLab CI: use CI/CD variables with protection
deploy:
  stage: deploy
  variables:
    DB_PASSWORD: $PRODUCTION_DB_PASSWORD  # Set in Settings > CI/CD > Variables
  rules:
    - if: $CI_COMMIT_BRANCH == "main"  # Protected variable only available on protected branches
  script:
    - ./deploy.sh --db-password "$DB_PASSWORD"
```

**Verify**: `grep -rn 'password\|secret\|api_key\|token' .github/ .gitlab-ci.yml` should return zero hardcoded values.

### 3. Pin third-party actions and dependencies

Mutable tags (v1, latest) can be silently replaced with malicious code. Pin all actions to their full commit SHA. [src3]

```yaml
# BAD: mutable tag can be hijacked
- uses: actions/checkout@v4

# GOOD: pinned to specific commit SHA (immutable)
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
```

Enable Dependabot to keep pinned actions updated:

```yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
```

**Verify**: `grep -rn 'uses:.*@v[0-9]' .github/workflows/` should return zero results (all pinned to SHA).

### 4. Integrate security scanning into every pipeline

Add SAST, SCA, and container scanning as required checks that block deployment on critical findings. [src2]

```yaml
# GitHub Actions: multi-layer security scanning
name: Security
on: [pull_request]

permissions:
  contents: read
  security-events: write

jobs:
  sast:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
      - uses: github/codeql-action/init@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d  # v3.28.0
        with:
          languages: javascript
      - uses: github/codeql-action/analyze@b56ba49b26e50535fa1e7f7db0f4f7b4bf65d80d  # v3.28.0

  dependency-scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
      - name: Run Trivy vulnerability scanner
        uses: aquasecurity/trivy-action@18f2510ee396bbf400402947e795f2d45e7f9929  # v0.28.0
        with:
          scan-type: 'fs'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'  # Fail the build on findings

  container-scan:
    runs-on: ubuntu-latest
    needs: [sast]
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
      - name: Build image
        run: docker build -t myapp:${{ github.sha }} .
      - name: Scan container image
        uses: aquasecurity/trivy-action@18f2510ee396bbf400402947e795f2d45e7f9929  # v0.28.0
        with:
          image-ref: 'myapp:${{ github.sha }}'
          severity: 'CRITICAL,HIGH'
          exit-code: '1'
```

**Verify**: Open a PR with a known vulnerable dependency (e.g., `lodash@4.17.20`) -- the security check should block merge.

### 5. Sign artifacts and generate SLSA provenance

Use Sigstore Cosign for keyless signing tied to your CI/CD identity, and generate SLSA provenance attestations. [src5]

```yaml
# GitHub Actions: sign container image with Cosign (keyless)
name: Build and Sign
on:
  push:
    branches: [main]

permissions:
  id-token: write    # For Cosign OIDC
  packages: write    # For GHCR push
  contents: read

jobs:
  build-sign:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2

      - uses: sigstore/cosign-installer@dc72c7d5c4d10cd6bcb8cf6e3fd625a9e5e537da  # v3.7.0

      - name: Login to GHCR
        uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567  # v3.3.0
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}

      - name: Build and push
        run: |
          docker build -t ghcr.io/${{ github.repository }}:${{ github.sha }} .
          docker push ghcr.io/${{ github.repository }}:${{ github.sha }}

      - name: Sign image (keyless)
        run: |
          cosign sign --yes ghcr.io/${{ github.repository }}@$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/${{ github.repository }}:${{ github.sha }} | cut -d@ -f2)
```

**Verify**: `cosign verify --certificate-oidc-issuer https://token.actions.githubusercontent.com ghcr.io/your-org/your-repo@sha256:...` should show a valid signature.

### 6. Harden runner infrastructure

Use ephemeral runners that are destroyed after each job. For self-hosted runners, use JIT (just-in-time) registration. [src6]

```yaml
# GitHub Actions: prefer GitHub-hosted runners (ephemeral by default)
jobs:
  build:
    runs-on: ubuntu-latest  # Ephemeral VM, fresh for every job

# GitLab CI: use SaaS runners or configure autoscaling
build:
  tags:
    - saas-linux-medium-amd64  # GitLab SaaS runner (ephemeral)
  script:
    - make build
```

For self-hosted GitHub runners, use JIT tokens:

```bash
# Generate a JIT runner token (expires after one job)
curl -X POST \
  -H "Authorization: token $GITHUB_TOKEN" \
  -H "Accept: application/vnd.github+json" \
  https://api.github.com/repos/OWNER/REPO/actions/runners/generate-jitconfig \
  -d '{"name":"ephemeral-runner","runner_group_id":1,"labels":["self-hosted"]}'
```

**Verify**: Check runner job history -- each job should show a different runner instance ID.

### 7. Implement audit logging and monitoring

Centralize pipeline logs and set alerts for anomalous activity (unexpected config changes, secret access, after-hours deployments). [src6]

```yaml
# GitHub Actions: enable audit log streaming (org-level)
# Settings > Audit log > Log streaming > Configure SIEM endpoint

# GitLab: stream audit events to external destination
# Admin Area > Monitoring > Audit Events > Streams > Add streaming destination
```

Key events to monitor:

```
- Pipeline configuration file changes (.github/workflows/*, .gitlab-ci.yml)
- New secrets created or accessed
- Branch protection rule changes
- Runner registration/deregistration
- Failed deployment attempts
- Pipeline runs from forked repositories
- OAuth app installations/permission changes
```

**Verify**: Modify a workflow file and check your SIEM -- the change should appear as an audit event within minutes.

## Code Examples

### GitHub Actions: Complete Hardened Workflow

> Full script: [github-actions-complete-hardened-workflow.yml](scripts/github-actions-complete-hardened-workflow.yml) (30 lines)

```yaml
# .github/workflows/secure-deploy.yml
name: Secure Deploy Pipeline
on:
  push:
    branches: [main]
# ... (see full script)
```

### GitLab CI: Hardened Pipeline Configuration

> Full script: [gitlab-ci-hardened-pipeline-configuration.yml](scripts/gitlab-ci-hardened-pipeline-configuration.yml) (43 lines)

```yaml
# .gitlab-ci.yml
stages:
  - test
  - scan
  - build
# ... (see full script)
```

## Anti-Patterns

### Wrong: Storing secrets in pipeline config

```yaml
# BAD -- secrets visible in version control and logs
env:
  AWS_ACCESS_KEY_ID: AKIAIOSFODNN7EXAMPLE
  AWS_SECRET_ACCESS_KEY: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
```

### Correct: Use OIDC federation or encrypted secrets

```yaml
# GOOD -- no long-lived credentials, OIDC provides short-lived tokens
permissions:
  id-token: write
steps:
  - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
    with:
      role-to-assume: arn:aws:iam::123456789012:role/DeployRole
      aws-region: us-east-1
```

### Wrong: Using mutable action tags

```yaml
# BAD -- tag can be moved to point at malicious code
- uses: actions/checkout@v4
- uses: some-org/some-action@main
```

### Correct: Pin actions to full commit SHA

```yaml
# GOOD -- SHA is immutable, cannot be silently replaced
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683  # v4.2.2
```

### Wrong: Over-privileged pipeline permissions

```yaml
# BAD -- grants all permissions to every job
permissions: write-all

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test  # Test job does NOT need write-all
```

### Correct: Least-privilege permissions per job

```yaml
# GOOD -- minimal global permissions, escalate per job as needed
permissions:
  contents: read

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - run: npm test

  deploy:
    permissions:
      id-token: write  # Only this job needs OIDC
    steps:
      - uses: aws-actions/configure-aws-credentials@e3dd6a429d7300a6a4c196c26e071d42e0343502
```

### Wrong: Running npm install without protections

```bash
# BAD -- post-install scripts from dependencies execute arbitrary code
npm install
```

### Correct: Use --ignore-scripts and audit

```bash
# GOOD -- prevent malicious post-install scripts, audit for vulnerabilities
npm ci --ignore-scripts
npm audit --audit-level=high
```

## Common Pitfalls

- **Poisoned Pipeline Execution (PPE)**: Attacker submits PR that modifies `.github/workflows/` or `.gitlab-ci.yml` to exfiltrate secrets. Fix: Use `pull_request` trigger (not `pull_request_target`) and restrict workflow file changes with CODEOWNERS. [src1]
- **Dependency confusion attacks**: Internal package name matches public registry package, and CI installs the public (malicious) version. Fix: Use scoped packages (`@your-org/package`), configure `.npmrc` with single registry, and use lock files. [src2]
- **Secret sprawl across environments**: Same production secret shared across dev/staging/prod pipelines. Fix: Use environment-specific secrets and protect variables to specific branches. [src4]
- **Docker build cache poisoning**: Attacker pushes a malicious layer to a shared Docker cache. Fix: Use `--no-cache` for production builds or sign and verify base images. [src6]
- **Insufficient fork protection**: Public repo allows fork PRs to run workflows with access to repo secrets. Fix: Require approval for fork PR workflows and never expose secrets to `pull_request` events from forks. [src3]
- **Stale secrets never rotated**: API keys created years ago still active, increasing breach window. Fix: Enforce automatic rotation (90 days max) via Vault or cloud provider secret rotation. [src2]
- **Skipping signature verification at deploy time**: Artifacts are signed at build but nobody checks the signature before deployment. Fix: Add a mandatory `cosign verify` step in the deploy job that fails if verification fails. [src5]
- **Running security scans without failing the build**: Security tools report findings but pipeline continues to deploy. Fix: Set `exit-code: 1` or equivalent to make critical/high findings block deployment. [src2]

## Diagnostic Commands

> Full script: [diagnostic-commands.sh](scripts/diagnostic-commands.sh) (26 lines)

```bash
# Scan for hardcoded secrets in your repository
gitleaks detect --source . --verbose
# Check GitHub Actions workflows for security issues
# Install: pip install actionlint (or download binary)
actionlint .github/workflows/*.yml
# ... (see full script)
```

## Version History & Compatibility

| Framework/Tool | Version | Status | Key Feature |
|---|---|---|---|
| SLSA | v1.0 | Current | Build provenance levels (L1-L4) |
| Sigstore Cosign | v2.x | Current | Keyless signing default, OIDC identity |
| GitHub Actions OIDC | GA | Current | AWS, GCP, Azure federation |
| GitLab OIDC | GA (15.7+) | Current | JWT-based cloud auth |
| in-toto | CNCF Graduated (2025) | Current | Supply chain attestation framework |
| Trivy | v0.50+ | Current | All-in-one scanner (image, fs, IaC, SBOM) |
| OWASP ZAP | v2.15+ | Current | DAST with CI/CD integration |
| CodeQL | v2.x | Current | GitHub-native SAST |
| Dependabot | v2 | Current | Dependency + actions update automation |

## When to Use / When Not to Use

| Use When | Don't Use When | Use Instead |
|---|---|---|
| Any organization running automated build/deploy pipelines | Manual deployments with no CI/CD automation | Manual deployment security checklist |
| Deploying to production or any environment with customer data | Local development-only builds with no deployment | Development environment security guide |
| Using third-party actions, plugins, or dependencies in pipelines | Fully air-gapped build environment with no external dependencies | Internal build system hardening guide |
| Regulatory compliance requires audit trails (SOC 2, ISO 27001, FedRAMP) | Personal hobby project with no sensitive data | Basic CI/CD setup guide |
| Multiple teams share CI/CD infrastructure | Single developer with sole access to everything | Simplified personal pipeline security |

## Important Caveats

- OIDC federation eliminates static secrets for cloud providers but does not protect against compromised pipeline definitions -- you still need branch protection and CODEOWNERS
- Cosign keyless signing ties identity to CI/CD platform OIDC tokens -- if the platform is compromised, signatures are also compromised; consider offline key signing for critical releases
- Security scanning (SAST/DAST/SCA) finds known vulnerability patterns but cannot detect novel zero-day exploits or business logic flaws -- manual security review is still necessary for high-risk changes
- SLSA provenance proves where and how an artifact was built, but does not guarantee the source code is free of vulnerabilities -- it proves integrity, not quality
- Self-hosted runners provide more control but require you to manage patching, isolation, and credential security -- GitHub/GitLab SaaS runners handle this automatically
- Pipeline security controls add latency to builds -- prioritize critical scans in PR checks and run comprehensive scans asynchronously to balance speed and security

## Related Units
<!-- Generated from related_kos frontmatter -->

- [XSS Prevention Guide](/software/security/xss-prevention/2026)
- [Container Runtime Security](/software/security/container-runtime-security/2026)
- [Kubernetes Security Hardening](/software/security/kubernetes-security/2026)
