Skip to content

Latest commit

 

History

11 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Prowler IaC Scan Pipeline + Claude Code Auto-Remediation Demo

This demo shows an end-to-end security workflow: Prowler scans the Terraform code in your repo on every push/PR, sends findings to Prowler Cloud, and then Claude Code consumes those findings via the Prowler MCP Server to automatically fix the issues and open a pull request. Merging that PR triggers the next scan, closing the loop.

Architecture

The workflow is a continuous loop, not a one-shot pipeline: every push or PR is scanned, findings land in Prowler Cloud, Claude Code turns them into a remediation PR, and merging that PR triggers the next scan that verifies the fixes.

flowchart TD
    tf["Terraform code<br/>(terraform/)"]
    gha["GitHub Actions<br/>prowler iac --scan-path ./terraform"]
    cloud["Prowler Cloud<br/>(findings)"]
    cc["Claude Code<br/>(auto-remediation)"]
    pr["Pull request<br/>(security fixes)"]

    tf -- "push / PR" --> gha
    gha -- "--push-to-cloud" --> cloud
    cloud -- "Prowler MCP Server" --> cc
    cc -- "fix + open PR" --> pr
    pr -- "merge re-triggers the scan" --> tf
Loading

Key point: Prowler scans the IaC files directly (prowler iac --scan-path ./terraform) — no AWS credentials needed for the scan. It detects misconfigurations in the Terraform code itself before anything is deployed.

Prerequisites

No AWS credentials are needed — Prowler's iac provider scans the code statically.

Quick Start

  1. Fork/clone this repo
  2. Add the PROWLER_CLOUD_API_KEY GitHub secret
  3. Push to main or open a PR (triggers Prowler IaC scan)
  4. Set PROWLER_APP_API_KEY env var and open Claude Code in this repo
  5. Ask Claude Code to query findings and fix the Terraform

Part 1: CI Pipeline Setup

1.1 GitHub Secret

Go to Settings > Secrets and variables > Actions and add:

Secret Description
PROWLER_CLOUD_API_KEY API key from Prowler Cloud (needs "Manage Ingestions")

That's it — no AWS credentials required for IaC scanning.

Note: If PROWLER_CLOUD_API_KEY is not set, --push-to-cloud is silently skipped and results are only saved locally as OCSF JSON under output/. Make sure the secret is configured before running the workflow.

1.2 GitHub Actions Workflow

The workflow is at .github/workflows/prowler-scan.yml. It triggers when Terraform files change:

name: Prowler IaC Scan

on:
  push:
    branches: [main]
    paths:
      - "terraform/**"
      - ".github/workflows/**"
  pull_request:
    branches: [main]
    paths:
      - "terraform/**"
  workflow_dispatch:

permissions:
  contents: read

jobs:
  prowler-iac-scan:
    name: Scan IaC with Prowler
    runs-on: ubuntu-latest

    steps:
      - name: Harden the runner (Audit all outbound calls)
        uses: step-security/harden-runner@a5ad31d6a139d249332a2605b85202e8c0b78450 # v2.19.1
        with:
          egress-policy: audit

      - name: Checkout code
        uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1

      - name: Install Trivy
        run: |
          sudo apt-get install -y wget apt-transport-https gnupg
          wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | gpg --dearmor | sudo tee /usr/share/keyrings/trivy.gpg > /dev/null
          echo "deb [signed-by=/usr/share/keyrings/trivy.gpg] https://aquasecurity.github.io/trivy-repo/deb generic main" | sudo tee /etc/apt/sources.list.d/trivy.list
          sudo apt-get update
          sudo apt-get install -y trivy

      - name: Install Prowler
        run: pip install prowler

      - name: Run Prowler IaC Scan
        env:
          PROWLER_CLOUD_API_KEY: ${{ secrets.PROWLER_CLOUD_API_KEY }}
        run: prowler iac --scan-path ./terraform --push-to-cloud --provider-uid https://github.com/prowler-cloud/iac-scan-pipeline-testing

What it does:

  • Hardens the runner with StepSecurity harden-runner (audits outbound network calls)
  • Checks out the repo code
  • Installs Trivy — Prowler's IaC provider uses it as the scanning engine
  • Installs Prowler
  • Runs prowler iac --scan-path ./terraform to scan the Terraform files for misconfigurations
  • --push-to-cloud sends findings to Prowler Cloud (requires PROWLER_CLOUD_API_KEY — without it the push is silently skipped and results are only saved locally)
  • --provider-uid identifies this repo as the IaC source in Prowler Cloud

Note: Third-party actions are pinned to a commit SHA (with the version in a comment) as a supply-chain best practice. When you fork, update --provider-uid to point at your own repository.

Forks: Pull requests from forks don't have access to repository secrets, so PROWLER_CLOUD_API_KEY won't be available and the cloud push is skipped for fork PRs. Push to your own fork's main (or use workflow_dispatch) to push findings to Prowler Cloud.

Triggers:

  • Push to main — scans on every merge that changes terraform/ files
  • Pull requests — scans the IaC in the PR before merge
  • Manual trigger — via the Actions tab (workflow_dispatch)

1.3 Verifying the Scan

  1. Go to the Actions tab in your GitHub repo
  2. Select "Prowler IaC Scan" and click "Run workflow" (or push a change to terraform/)
  3. Once complete, go to Prowler Cloud to see the findings

Part 2: Prowler MCP Server Setup

The Prowler MCP Server lets Claude Code query and analyze your security findings directly.

Option A: Prowler Cloud MCP (Recommended)

This repo includes a pre-configured .mcp.json that points at the managed Prowler Cloud MCP endpoint and reads your API key from the PROWLER_APP_API_KEY environment variable:

{
  "mcpServers": {
    "prowler": {
      "type": "http",
      "url": "https://mcp.prowler.com/mcp",
      "headers": {
        "Authorization": "Bearer ${PROWLER_APP_API_KEY}"
      }
    }
  }
}

You just need to set the API key before launching Claude Code:

export PROWLER_APP_API_KEY="pk_your_key_here"

Generate an API key at: Prowler Cloud > Settings > API Keys (needs full access permissions).

Option B: Local Docker (STDIO)

If you prefer to run the MCP server locally:

docker pull prowlercloud/prowler-mcp

Update .mcp.json to:

{
  "mcpServers": {
    "prowler": {
      "type": "stdio",
      "command": "docker",
      "args": ["run", "-i", "--rm", "-e", "PROWLER_APP_API_KEY", "prowlercloud/prowler-mcp"],
      "env": {
        "PROWLER_APP_API_KEY": "pk_your_key_here"
      }
    }
  }
}

Option C: Self-Hosted HTTP

docker run --rm -p 8000:8000 \
  -e PROWLER_APP_API_KEY="pk_your_key_here" \
  prowlercloud/prowler-mcp --transport http --host 0.0.0.0 --port 8000

Update .mcp.json to:

{
  "mcpServers": {
    "prowler": {
      "type": "url",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Verify MCP Connection

cd iac-scan-pipeline-testing
claude mcp list

You should see the prowler server listed and connected.


Part 3: Demo Walkthrough

3.1 The Intentionally Vulnerable Terraform

The terraform/main.tf contains resources with deliberate security misconfigurations that Prowler's IaC scanner will detect:

Resource Issue Expected Finding
S3 Bucket No server-side encryption S3 bucket without default encryption
S3 Bucket No versioning S3 bucket without versioning enabled
S3 Bucket No public access block S3 bucket without public access block
Security Group SSH open to 0.0.0.0/0 Security group allows SSH from internet
Security Group RDP open to 0.0.0.0/0 Security group allows RDP from internet
EC2 Instance IMDSv1 enabled EC2 instance not using IMDSv2
EC2 Instance EBS volume not encrypted EBS volume without encryption
RDS Instance Publicly accessible RDS instance is publicly accessible
RDS Instance Storage not encrypted RDS instance storage not encrypted
RDS Instance No backup retention RDS instance without backup enabled

3.2 Step-by-Step Demo

Step 1: Push the vulnerable Terraform and trigger the scan

Push the repo to GitHub. The workflow triggers automatically when terraform/ files change on main, or you can manually trigger it from the Actions tab.

Step 2: View findings in Prowler Cloud

Open Prowler Cloud and review the findings. You should see multiple FAIL results from the IaC scan matching the table above.

Step 3: Open Claude Code

cd iac-scan-pipeline-testing
export PROWLER_APP_API_KEY="pk_your_key_here"
claude

Step 4: Query findings via MCP

Ask Claude Code to pull in the findings:

> List all FAIL findings from Prowler
> Show me the critical and high severity findings
> What S3 security issues were found in the IaC scan?

Step 5: Fix the Terraform and open a PR

> Fix all the security findings in the terraform/ directory and open a PR with the changes

Claude Code will:

  • Analyze each finding from Prowler
  • Edit terraform/main.tf to add encryption, versioning, public access blocks, restrict security group CIDRs, enforce IMDSv2, etc.
  • Create a branch, commit, and open a PR

Step 6: Review the PR

Review the diff. You should see changes like:

  • aws_s3_bucket_server_side_encryption_configuration resource added
  • aws_s3_bucket_versioning resource added
  • aws_s3_bucket_public_access_block resource added
  • Security group CIDRs restricted from 0.0.0.0/0 to specific ranges
  • metadata_options block with http_tokens = "required" (IMDSv2)
  • encrypted = true on EBS volumes
  • publicly_accessible = false and storage_encrypted = true on RDS
  • backup_retention_period increased

Step 7: Merge and re-scan

Merge the PR. The push to main triggers a new Prowler IaC scan. Verify in Prowler Cloud that the findings are now resolved.


Sample Claude Code Prompts

Prompt Purpose
List all FAIL findings from Prowler Get a summary of all issues
Summarize the security posture of my Terraform code based on Prowler findings High-level overview
What are the critical and high severity findings? Prioritize remediation
Fix the S3 bucket in terraform/main.tf to address all Prowler findings Targeted fix
Fix all Prowler findings in this repo and open a PR Full auto-remediation
Explain the finding about SSH being open to the internet Learn about a specific issue

Prowler IaC Supported Formats

Prowler's IaC scanner supports more than just Terraform:

Format File Extensions
Terraform *.tf, *.tf.json, *.tfvars, plan files
CloudFormation *.yml, *.yaml, *.json
Kubernetes *.yml, *.yaml, *.json
Docker Dockerfile, Containerfile
Helm *.yml, *.yaml, *.tpl, *.tar.gz
Azure ARM Templates *.json
Ansible *.yml, *.yaml, *.json

Troubleshooting

Issue Solution
MCP server not connecting Verify PROWLER_APP_API_KEY is set and valid. Run claude mcp list to check.
GitHub Actions failing Verify the PROWLER_CLOUD_API_KEY secret is set in the repo settings.
No findings in Prowler Cloud Check the workflow logs for "Push to Prowler Cloud skipped: no API key configured" — this means PROWLER_CLOUD_API_KEY is not set.
Claude Code can't create a PR Ensure gh CLI is authenticated: gh auth status.

References


License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details.

About

Demo: Prowler IaC scanning + Claude Code auto-remediation via MCP Server

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages