home / skills / prowler-cloud / prowler / prowler-sdk-check

prowler-sdk-check skill

/skills/prowler-sdk-check

This skill creates Prowler security checks for SDK providers, generating implementation and metadata to ensure consistent security checks across services.

npx playbooks add skill prowler-cloud/prowler --skill prowler-sdk-check

Review the files below or copy the command above to add this skill to your agents.

Files (8)
SKILL.md
8.0 KB
---
name: prowler-sdk-check
description: >
  Creates Prowler security checks following SDK architecture patterns.
  Trigger: When creating or updating a Prowler SDK security check (implementation + metadata) for any provider (AWS, Azure, GCP, K8s, GitHub, etc.).
license: Apache-2.0
metadata:
  author: prowler-cloud
  version: "1.0"
  scope: [root, sdk]
  auto_invoke:
    - "Creating new checks"
    - "Updating existing checks and metadata"
allowed-tools: Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
---

## Check Structure

```
prowler/providers/{provider}/services/{service}/{check_name}/
├── __init__.py
├── {check_name}.py
└── {check_name}.metadata.json
```

---

## Step-by-Step Creation Process

### 1. Prerequisites

- **Verify check doesn't exist**: Search `prowler/providers/{provider}/services/{service}/`
- **Ensure provider and service exist** - create them first if not
- **Confirm service has required methods** - may need to add/modify service methods to get data

### 2. Create Check Files

```bash
mkdir -p prowler/providers/{provider}/services/{service}/{check_name}
touch prowler/providers/{provider}/services/{service}/{check_name}/__init__.py
touch prowler/providers/{provider}/services/{service}/{check_name}/{check_name}.py
touch prowler/providers/{provider}/services/{service}/{check_name}/{check_name}.metadata.json
```

### 3. Implement Check Logic

```python
from prowler.lib.check.models import Check, Check_Report_{Provider}
from prowler.providers.{provider}.services.{service}.{service}_client import {service}_client

class {check_name}(Check):
    """Ensure that {resource} meets {security_requirement}."""
    def execute(self) -> list[Check_Report_{Provider}]:
        """Execute the check logic.

        Returns:
            A list of reports containing the result of the check.
        """
        findings = []
        for resource in {service}_client.{resources}:
            report = Check_Report_{Provider}(metadata=self.metadata(), resource=resource)
            report.status = "PASS" if resource.is_compliant else "FAIL"
            report.status_extended = f"Resource {resource.name} compliance status."
            findings.append(report)
        return findings
```

### 4. Create Metadata File

See complete schema below and `assets/` folder for complete templates.
For detailed field documentation, see `references/metadata-docs.md`.

### 5. Verify Check Detection

```bash
poetry run python prowler-cli.py {provider} --list-checks | grep {check_name}
```

### 6. Run Check Locally

```bash
poetry run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}
```

### 7. Create Tests

See `prowler-test-sdk` skill for test patterns (PASS, FAIL, no resources, error handling).

---

## Check Naming Convention

```
{service}_{resource}_{security_control}
```

Examples:
- `ec2_instance_public_ip_disabled`
- `s3_bucket_encryption_enabled`
- `iam_user_mfa_enabled`

---

## Metadata Schema (COMPLETE)

```json
{
  "Provider": "aws",
  "CheckID": "{check_name}",
  "CheckTitle": "Human-readable title",
  "CheckType": [
    "Software and Configuration Checks/AWS Security Best Practices",
    "Software and Configuration Checks/Industry and Regulatory Standards/AWS Foundational Security Best Practices"
  ],
  "ServiceName": "{service}",
  "SubServiceName": "",
  "ResourceIdTemplate": "",
  "Severity": "low|medium|high|critical",
  "ResourceType": "AwsEc2Instance|Other",
  "ResourceGroup": "security|compute|storage|network",
  "Description": "**Bold resource name**. Detailed explanation of what this check evaluates and why it matters.",
  "Risk": "What happens if non-compliant. Explain attack vectors, data exposure risks, compliance impact.",
  "RelatedUrl": "",
  "AdditionalURLs": [
    "https://docs.aws.amazon.com/..."
  ],
  "Remediation": {
    "Code": {
      "CLI": "aws {service} {command} --option value",
      "NativeIaC": "```yaml\nResources:\n  Resource:\n    Type: AWS::{Service}::{Resource}\n    Properties:\n      Key: value  # This line fixes the issue\n```",
      "Other": "1. Console steps\n2. Step by step",
      "Terraform": "```hcl\nresource \"aws_{service}_{resource}\" \"example\" {\n  key = \"value\"  # This line fixes the issue\n}\n```"
    },
    "Recommendation": {
      "Text": "Detailed recommendation for remediation.",
      "Url": "https://hub.prowler.com/check/{check_name}"
    }
  },
  "Categories": [
    "identity-access",
    "encryption",
    "logging",
    "forensics-ready",
    "internet-exposed",
    "trust-boundaries"
  ],
  "DependsOn": [],
  "RelatedTo": [],
  "Notes": ""
}
```

### Required Fields

| Field | Description |
|-------|-------------|
| `Provider` | Provider name: aws, azure, gcp, kubernetes, github, m365 |
| `CheckID` | Must match class name and folder name |
| `CheckTitle` | Human-readable title |
| `Severity` | `low`, `medium`, `high`, `critical` |
| `ServiceName` | Service being checked |
| `Description` | What the check evaluates |
| `Risk` | Security impact of non-compliance |
| `Remediation.Code.CLI` | CLI fix command |
| `Remediation.Recommendation.Text` | How to fix |

### Severity Guidelines

| Severity | When to Use |
|----------|-------------|
| `critical` | Direct data exposure, RCE, privilege escalation |
| `high` | Significant security risk, compliance violation |
| `medium` | Defense-in-depth, best practice |
| `low` | Informational, minor hardening |

---

## Check Report Statuses

| Status | When to Use |
|--------|-------------|
| `PASS` | Resource is compliant |
| `FAIL` | Resource is non-compliant |
| `MANUAL` | Requires human verification |

---

## Common Patterns

### AWS Check with Regional Resources

```python
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.s3.s3_client import s3_client

class s3_bucket_encryption_enabled(Check):
    def execute(self) -> list[Check_Report_AWS]:
        findings = []
        for bucket in s3_client.buckets.values():
            report = Check_Report_AWS(metadata=self.metadata(), resource=bucket)
            if bucket.encryption:
                report.status = "PASS"
                report.status_extended = f"S3 bucket {bucket.name} has encryption enabled."
            else:
                report.status = "FAIL"
                report.status_extended = f"S3 bucket {bucket.name} does not have encryption enabled."
            findings.append(report)
        return findings
```

### Check with Multiple Conditions

```python
from prowler.lib.check.models import Check, Check_Report_AWS
from prowler.providers.aws.services.ec2.ec2_client import ec2_client

class ec2_instance_hardened(Check):
    def execute(self) -> list[Check_Report_AWS]:
        findings = []
        for instance in ec2_client.instances:
            report = Check_Report_AWS(metadata=self.metadata(), resource=instance)

            issues = []
            if instance.public_ip:
                issues.append("has public IP")
            if not instance.metadata_options.http_tokens == "required":
                issues.append("IMDSv2 not enforced")

            if issues:
                report.status = "FAIL"
                report.status_extended = f"Instance {instance.id} {', '.join(issues)}."
            else:
                report.status = "PASS"
                report.status_extended = f"Instance {instance.id} is properly hardened."

            findings.append(report)
        return findings
```

---

## Commands

```bash
# Verify detection
poetry run python prowler-cli.py {provider} --list-checks | grep {check_name}

# Run check
poetry run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}

# Run with specific profile/credentials
poetry run python prowler-cli.py aws --profile myprofile --check {check_name}

# Run multiple checks
poetry run python prowler-cli.py {provider} --check {check1} {check2} {check3}
```

## Resources

- **Templates**: See [assets/](assets/) for complete check and metadata templates (AWS, Azure, GCP)
- **Documentation**: See [references/metadata-docs.md](references/metadata-docs.md) for official Prowler Developer Guide links

Overview

This skill automates creation of Prowler SDK security checks following established SDK architecture patterns. It guides authors through folder layout, check implementation, metadata schema, and local verification commands. The skill ensures checks are consistent with provider conventions and ready for integration and testing.

How this skill works

The skill inspects the provider/service layout and scaffolds the check directory with __init__.py, implementation, and metadata files. It provides code patterns for the Check class, report generation, and common conditional logic, plus a complete metadata JSON schema and required fields. Finally, it includes verification and run commands and pointers for test creation.

When to use it

  • You are adding a new Prowler security check for any supported provider (AWS, Azure, GCP, Kubernetes, GitHub, etc.).
  • You need a clear, consistent template for check implementation and metadata to match Prowler SDK conventions.
  • You are updating an existing check and must follow naming, metadata, and reporting standards.
  • You want to validate that the new check is discoverable and runnable locally before submitting.
  • You are writing unit tests for check outcomes and need test patterns (PASS, FAIL, no resources, errors).

Best practices

  • Verify the check does not already exist and that the provider/service directories are present before creating files.
  • Name the check using service_resource_securitycontrol convention and ensure CheckID, class name, and folder name match exactly.
  • Populate required metadata fields (Provider, CheckID, CheckTitle, Severity, ServiceName, Description, Risk, Remediation) and include actionable CLI/Terraform examples.
  • Use provider-specific report models (e.g., Check_Report_AWS) and set status to PASS, FAIL, or MANUAL with clear status_extended text.
  • Add tests covering positive, negative, empty-resource, and error scenarios and verify detection with the provided list-checks command.

Example use cases

  • Create aws/s3/s3_bucket_encryption_enabled with metadata and code that iterates s3_client.buckets and reports encryption status.
  • Add an ec2_instance_hardened check that inspects public IP and IMDSv2 enforcement and produces aggregated status_extended messages.
  • Implement a GitHub repository secret-check that enumerates repos and flags missing secret-scanning or branch protections.
  • Update an existing cloud service to add a new resource type and extend the service client methods so the check can access needed data.
  • Run local verification and debugging with poetry run python prowler-cli.py {provider} --check {check_name} and iterate until tests pass.

FAQ

How do I ensure the check is discovered by Prowler?

Place the folder under prowler/providers/{provider}/services/{service}/{check_name} with matching CheckID and class name, then run the list-checks command to verify discovery.

Which metadata fields are mandatory?

Required fields include Provider, CheckID, CheckTitle, Severity, ServiceName, Description, Risk, Remediation.Code.CLI, and Remediation.Recommendation.Text. Ensure values match the check implementation.

What report statuses should I use?

Use PASS for compliant resources, FAIL for non-compliant, and MANUAL when human verification is required. Add clear status_extended messages explaining findings.