prowler-sdk-check について
prowler-sdk-check は、Prowler SDK にセキュリティチェックを追加するためのスキルです。チェックの構成、メタデータ、実装、ローカル検証に加え、プロバイダーごとの検出結果の扱い方を案内します。
主な機能
- 01チェックのファイルとディレクトリ構成を定義
- 02必須フィールドに沿ってメタデータを作成
- 03PASS、FAIL、MANUAL の結果を実装
- 04プロバイダーの権限・利用可否エラーを処理
- 05Prowler CLI コマンドでチェックを検証
活用シーン
- 01クラウドプロバイダーのサービスにチェックを追加
- 02チェックのメタデータと重大度を確認
- 03スキャンデータが取得できない場合をテスト
- 04新しいチェックをローカルで実行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ prowler-cloud/ prowler --skill prowler-sdk-checkインストール後、Claude Code で/prowler-sdk-checkを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
assets/aws_check.pyaws_metadata.jsonazure_check.pyazure_metadata.jsongcp_check.pygcp_metadata.jsonreferences/metadata-docs.md詳細
チェックの構造
prowler/providers/{provider}/services/{service}/{check_name}/
├── __init__.py
├── {check_name}.py
└── {check_name}.metadata.json
ステップごとの作成手順
1. 前提条件
- チェックが存在しないことを確認する:
prowler/providers/{provider}/services/{service}/を検索します - プロバイダーとサービスが存在することを確認する:存在しない場合は、先に作成します
- サービスに必要なメソッドがあることを確認する:データ取得のために、サービスメソッドの追加や変更が必要な場合があります
2. チェックファイルを作成する
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. チェックロジックを実装する
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. メタデータファイルを作成する
完全なスキーマは以下を、完全なテンプレートは assets/ フォルダーを参照してください。
各フィールドの詳細については、references/metadata-docs.md を参照してください。
5. チェックの検出を確認する
uv run python prowler-cli.py {provider} --list-checks | grep {check_name}
6. チェックをローカルで実行する
uv run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}
7. テストを作成する
テストパターン(PASS、FAIL、リソースなし、エラー処理)については、prowler-test-sdk スキルを参照してください。
チェックの命名規則
{service}_{resource}_{security_control}
例:
ec2_instance_public_ip_disableds3_bucket_encryption_enablediam_user_mfa_enabled
メタデータスキーマ(完全版)
{
"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": ""
}
必須フィールド
| フィールド | 説明 |
|---|---|
Provider | プロバイダー名:aws、azure、gcp、kubernetes、github、m365 |
CheckID | クラス名およびフォルダー名と一致する必要があります |
CheckTitle | 人が読めるタイトル |
Severity | low、medium、high、critical |
ServiceName | チェック対象のサービス |
Description | チェックで評価する内容 |
Risk | 要件に準拠しない場合のセキュリティ上の影響 |
Remediation.Code.CLI | 修正用の CLI コマンド |
Remediation.Recommendation.Text | 修正方法 |
重大度のガイドライン
| 重大度 | 使用する状況 |
|---|---|
critical | 直接的なデータ漏えい、RCE、権限昇格 |
high | 重大なセキュリティリスク、コンプライアンス違反 |
medium | 多層防御、ベストプラクティス |
low | 情報提供、軽微なセキュリティ強化 |
チェックレポートのステータス
| ステータス | 使用する状況 |
|---|---|
PASS | リソースが準拠しています |
FAIL | リソースが準拠していません |
MANUAL | 人による確認が必要な場合、またはリソースを評価するために必要なデータを取得できなかった場合 |
権限/可用性に関するエラーは検出結果ではありません
API 呼び出しが失敗した場合(権限やスコープの不足、API が有効になっていない、機能のライセンスがない、データを利用できないなど)に、FAIL を設定してはいけません。これはスキャン設定の問題であり、セキュリティ上の問題ではありません。FAIL にすると、誤解を招く重大度の高い検出結果として表示されます。
- サービス:エラーを記録し、空の結果とは区別して公開します(
[]ではなくNone、*_error属性、または*_lookup_failedセットなど)。この扱いを適用するのは、実際のアクセスエラーに限ります。404/not-found は通常「未設定」を意味し、正当なFAILです。また、API が無効であること自体が監査対象の制御である場合(例:GCP Access Approval)には、API が無効であることが明確なら正当なFAILです。 - チェック:評価できないことと必要な権限/API/ライセンスを
status_extendedに記載した、テナント/アカウント/プロジェクト/サブスクリプション単位のMANUAL検出結果を1件だけ出力します(リソースごとに出力しないでください)。 - 検出結果を隠すために
report.check_metadata.Severityを変更してはいけません。
if <service>_client.<data> is None:
report = CheckReport<Provider>(metadata=self.metadata(), resource={})
report.resource_name = "<Tenant-level resource>"
report.resource_id = "<stable-id>"
report.status = "MANUAL"
report.status_extended = "Cannot evaluate <requirement>: <data> could not be retrieved. Verify that <permission> is granted to the scanning identity."
return [report]
よくあるパターン
リージョンごとのリソースを扱う AWS チェック
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
複数の条件を持つチェック
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
コマンド
# Verify detection
uv run python prowler-cli.py {provider} --list-checks | grep {check_name}
# Run check
uv run python prowler-cli.py {provider} --log-level ERROR --verbose --check {check_name}
# Run with specific profile/credentials
uv run python prowler-cli.py aws --profile myprofile --check {check_name}
# Run multiple checks
uv run python prowler-cli.py {provider} --check {check1} {check2} {check3}
リソース
- テンプレート:チェックとメタデータの完全なテンプレート(AWS、Azure、GCP)については、assets/ を参照してください
- ドキュメント:公式の Prowler Developer Guide へのリンクについては、references/metadata-docs.md を参照してください
コメント
Markdown 対応