diff --git a/.checkov.yaml b/.checkov.yaml new file mode 100644 index 000000000..b1fee5353 --- /dev/null +++ b/.checkov.yaml @@ -0,0 +1,14 @@ +framework: terraform +download_external_modules: true +evaluate_variables: true +var_files: + - "*.tfvars" + +skip_path: + - "**/.terraform/*" + - "**/examples/**" + - "**/test/**" + +soft_fail: true # monitor mode +quiet: true + diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml new file mode 100644 index 000000000..83952e35b --- /dev/null +++ b/.github/workflows/checkov.yml @@ -0,0 +1,82 @@ +name: Terraform Security (Checkov) + +on: + pull_request: + branches: [ main, master ] + paths: + - '**/*.tf' + - '**/*.tfvars' + - '**/terraform.lock.hcl' + - '.checkov.yaml' + push: + branches: [ main, master ] + paths: + - '**/*.tf' + - '**/*.tfvars' + - '**/terraform.lock.hcl' + - '.checkov.yaml' + +permissions: + contents: read + security-events: write # needed for SARIF upload (PR annotations / Code scanning) + actions: read + +concurrency: + group: checkov-${{ github.ref }} + cancel-in-progress: false + +jobs: + checkov: + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + + - name: Install Checkov + run: pip install --upgrade checkov + + - name: Run Checkov (monitor mode) + continue-on-error: true + run: | + mkdir -p results + checkov \ + --directory . \ + --framework terraform \ + --download-external-modules true \ + --output sarif \ + --output-file-path results/checkov.sarif \ + --quiet \ + --soft-fail true + + - name: Upload SARIF to GitHub Code Scanning + # If your repo is private and doesn't have Advanced Security, + # this step may fail; the job stays green thanks to continue-on-error above. + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results/checkov.sarif + category: checkov + + - name: Emit human-friendly text report (non-blocking) + continue-on-error: true + run: | + checkov \ + --directory . \ + --framework terraform \ + --download-external-modules true \ + --output cli \ + --quiet \ + --soft-fail true | tee checkov.txt + + - name: Upload text artifact + uses: actions/upload-artifact@v4 + with: + name: checkov-cli-report + path: checkov.txt + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 000000000..00e3ec636 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,32 @@ +name: checkov +on: + pull_request: + push: + branches: + - main +jobs: + scan: + runs-on: ubuntu-latest + permissions: + contents: read # for actions/checkout to fetch code + security-events: write # for GitHub/codeql-action/upload-sarif to upload SARIF results + + steps: + - uses: actions/checkout@v2 + + - name: Run checkov + id: checkov + uses: bridgecrewio/checkov-action@master + with: + directory: code/ + #soft_fail: true + + - name: Upload SARIF file + uses: GitHub/codeql-action/upload-sarif@v3 + + # Results are generated only on a success or failure + # this is required since GitHub by default won't run the next step + # when the previous one has failed. Alternatively, enable soft_fail in checkov action. + if: success() || failure() + with: + sarif_file: results.sarif diff --git a/code/main.tf b/code/main.tf new file mode 100644 index 000000000..031d4d635 --- /dev/null +++ b/code/main.tf @@ -0,0 +1,31 @@ +terraform { + required_version = ">= 1.3.0" + required_providers { + google = { + source = "hashicorp/google" + version = "~> 5.0" + } + } +} + +provider "google" { + project = "demo-project-id" # placeholder; not used by Checkov + region = "us-central1" +} + +# Deliberately misconfigured GCS bucket to trigger findings: +# - uniform_bucket_level_access = false (bad) +# - public IAM member (bad) +resource "google_storage_bucket" "bad_bucket" { + name = "demo-checkov-bad-bucket-12345" + location = "US" + force_destroy = true + uniform_bucket_level_access = false # Checkov should flag CKV_GCP_31 +} + +resource "google_storage_bucket_iam_member" "public_reader" { + bucket = google_storage_bucket.bad_bucket.name + role = "roles/storage.objectViewer" + member = "allUsers" # Checkov should flag public access +} + diff --git a/main.tf b/main.tf new file mode 100644 index 000000000..aab5fa478 --- /dev/null +++ b/main.tf @@ -0,0 +1,2 @@ + +# tiny change