prowler-sdk-check

prowler-sdk-check

Beliebt

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.).

13KSterne
1.9KForks
Aktualisiert 1/22/2026
SKILL.md
readonlyread-only
name
prowler-sdk-check
description

>

version
"1.0"

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

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

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

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

6. Run Check Locally

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)

{
  "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

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

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

# 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/ for complete check and metadata templates (AWS, Azure, GCP)
  • Documentation: See references/metadata-docs.md for official Prowler Developer Guide links

You Might Also Like

Related Skills

coding-agent

coding-agent

179Kdev-codegen

Run Codex CLI, Claude Code, OpenCode, or Pi Coding Agent via background process for programmatic control.

openclaw avataropenclaw
Holen
add-uint-support

add-uint-support

97Kdev-codegen

Add unsigned integer (uint) type support to PyTorch operators by updating AT_DISPATCH macros. Use when adding support for uint16, uint32, uint64 types to operators, kernels, or when user mentions enabling unsigned types, barebones unsigned types, or uint support.

pytorch avatarpytorch
Holen
at-dispatch-v2

at-dispatch-v2

97Kdev-codegen

Convert PyTorch AT_DISPATCH macros to AT_DISPATCH_V2 format in ATen C++ code. Use when porting AT_DISPATCH_ALL_TYPES_AND*, AT_DISPATCH_FLOATING_TYPES*, or other dispatch macros to the new v2 API. For ATen kernel files, CUDA kernels, and native operator implementations.

pytorch avatarpytorch
Holen
skill-writer

skill-writer

97Kdev-codegen

Guide users through creating Agent Skills for Claude Code. Use when the user wants to create, write, author, or design a new Skill, or needs help with SKILL.md files, frontmatter, or skill structure.

pytorch avatarpytorch
Holen

Implements JavaScript classes in C++ using JavaScriptCore. Use when creating new JS classes with C++ bindings, prototypes, or constructors.

oven-sh avataroven-sh
Holen

Creates JavaScript classes using Bun's Zig bindings generator (.classes.ts). Use when implementing new JS APIs in Zig with JSC integration.

oven-sh avataroven-sh
Holen