Skip to content

title: CloudSlash - Shift-Left Scanning Reference description: Catch the $14K idle cluster before it merges, not three months later when someone asks why the bill doubled. For true shift-left: analyze only the resources ...


Shift-Left Scanning

Catch the $14K idle cluster before it merges, not three months later when someone asks why the bill doubled.


Prerequisites

  • CloudSlash source or binary available in CI
  • Cloud credentials configured as CI secrets (optional: falls back to mock mode without them)
  • CEL policy files committed to your repository (optional)

GitHub Actions

Recommended

Basic Scan

name: CloudSlash Infrastructure Scan
on:
  pull_request:
    branches: [main]
    paths: ['**.tf', '**.tfvars', '**cloudslash*.yaml']

permissions:
  contents: read
  pull-requests: write
  security-events: write

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Install CloudSlash
        run: curl -fsSL https://cloudslash.dev/install.sh | bash

      - name: Run Scan
        run: cs scan --format=sarif --output=results.sarif --fail-on=critical
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: Upload to GitHub Security
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif
          category: cloudslash

Terraform Plan Scanning

For true shift-left: analyze only the resources being changed in the PR:

      - name: Terraform Plan
        run: |
          terraform init
          terraform plan -out=tfplan.out
          terraform show -json tfplan.out > tfplan.json

      - name: Scan Plan Diff
        run: |
          cs scan --plan=tfplan.json --format=sarif --output=results.sarif --fail-on=critical

The plan parser extracts resource_changes[] and builds a targeted graph containing only the resources being created, modified, or destroyed.

PR Findings

Comment with

      - name: Generate PR Report
        run: cs scan --format=github-pr > scan-report.md

      - name: Post PR Comment
        if: always()
        uses: peter-evans/create-or-update-comment@v4
        with:
          issue-number: ${{ github.event.pull_request.number }}
          body-path: scan-report.md

GitLab CI

cloudslash-scan:
  stage: test
  image: golang:1.23
  before_script:
    - curl -fsSL https://cloudslash.dev/install.sh | bash
  script:
    - cs scan --format=json --fail-on=warning --timeout=5m
  variables:
    AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
    AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
  allow_failure: false

Azure DevOps

steps:
  - script: curl -fsSL https://cloudslash.dev/install.sh | bash
    displayName: 'Install CloudSlash'

  - script: |
      cs scan --format=sarif --output=$(Build.ArtifactStagingDirectory)/results.sarif --fail-on=critical
    displayName: 'CloudSlash Scan'
    env:
      AZURE_CLIENT_ID: $(AZURE_CLIENT_ID)
      AZURE_CLIENT_SECRET: $(AZURE_CLIENT_SECRET)
      AZURE_TENANT_ID: $(AZURE_TENANT_ID)

  - task: PublishBuildArtifacts@1
    inputs:
      pathToPublish: '$(Build.ArtifactStagingDirectory)/results.sarif'
      artifactName: 'CodeAnalysisLogs'

No Credentials

No Problem

When cloud credentials are not available, CloudSlash automatically falls back to mock analysis:

WARN: No cloud credentials found: falling back to mock mode for static analysis

This ensures your pipeline never fails due to missing secrets during initial setup. The fallback detects 13 credential failure patterns across AWS, GCP, and Azure.


Exit Codes

Code Meaning
0 All findings below --fail-on threshold
1 Findings exceed threshold: CI gate fails

Policy Enforcement

in CI

Combine scans with CEL policies for compliance gating:

cs scan --rules soc2-compliance.yaml --fail-on=warning --format=github-pr

The scan exits with code 1 if any rule produces a violation at or above the --fail-on threshold.


What's Next