Skip to content

title: CloudSlash - CI/CD Integration Reference description: Gate infrastructure changes at the pull request. Every flag, every policy violation, every cost spike: caught before it merges. The reference implementation ...


CI/CD Integration

Gate infrastructure changes at the pull request. Every flag, every policy violation, every cost spike: caught before it merges.

GitHub Actions

Recommended

The reference implementation uses actions/cache@v4 for Go module caching and github/codeql-action/upload-sarif@v3 for Security tab integration.

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

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

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

      - name: Set up Go
        uses: actions/setup-go@v5
        with:
          go-version-file: go.mod

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: |
            ~/go/pkg/mod
            ~/.cache/go-build
          key: go-${{ runner.os }}-${{ hashFiles('go.sum') }}
          restore-keys: go-${{ runner.os }}-

      - name: Build CloudSlash
        run: go build -o cloudslash ./cmd/cloudslash-cli

      - name: Run Scan
        run: |
          ./cs scan --format=github-pr --fail-on=critical --region=${{ vars.AWS_REGION || 'us-east-1' }} \
            > scan-report.md
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

      - name: SARIF Upload
        if: always()
        run: |
          ./cs scan --format=sarif --output=results.sarif --fail-on=none

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

      - 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

SARIF Category

The category: cloudslash parameter groups all CloudSlash findings under a single Security tab section, preventing collision with other SARIF producers (CodeQL, Semgrep).

Terraform Plan

Diff Scanning

The --plan flag enables true shift-left scanning. Instead of analyzing the full cloud account state, the engine evaluates only the resources being created, modified, or destroyed by the proposed Terraform change.

# Generate a plan file
terraform plan -out=tfplan.out

# Convert to JSON
terraform show -json tfplan.out > tfplan.json

# Scan only the resources being changed
cs scan --plan=tfplan.json --format=sarif --output=results.sarif --fail-on=critical

The plan parser extracts resource_changes[] from the JSON structure and constructs a targeted graph. Resources being destroyed are automatically flagged with a risk score of 60 and the terraform_destroy waste reason.

GitHub Actions

With Plan Scanning

      - 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

Mock Fallback

Credential-Free Environments

The scanner implements automatic credential detection. When cloud provider credentials are absent, the engine logs a warning and degrades to mock static analysis mode. This prevents pipeline failures in environments where secrets are not yet configured.

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

The credential detection evaluates 13 failure patterns across AWS, GCP, and Azure error responses:

  • unable to locate credentials
  • could not find default credentials
  • AccessDenied, AuthenticationFailed
  • no such host, invalid_client

No explicit --mock flag required. The fallback is fully automatic.

GitLab CI

cloudslash-scan:
  stage: test
  image: golang:1.23
  script:
    - go build -o cloudslash ./cmd/cloudslash-cli
    - ./cs scan --format=json --fail-on=warning --timeout=5m --region eu-west-1
  variables:
    AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID
    AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY
  allow_failure: false
  artifacts:
    reports:
      sast: results.sarif

Azure DevOps

steps:
  - task: GoTool@0
    inputs:
      version: '1.23'

  - script: |
      go build -o cloudslash ./cmd/cloudslash-cli
      ./cs scan --format=sarif --output=$(Build.ArtifactStagingDirectory)/results.sarif --region eastus
    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'

CircleCI

jobs:
  scan:
    docker:
      - image: cimg/go:1.23
    steps:
      - checkout
      - run:
          name: Build CloudSlash
          command: go build -o cloudslash ./cmd/cloudslash-cli
      - run:
          name: Infrastructure Scan
          command: ./cs scan --format=json --fail-on=critical --region us-east-1