Skip to main content

prowler-compliance

Creates, syncs, audits and manages Prowler compliance frameworks end-to-end. Covers the two supported JSON schemas (universal multi-provider and legacy per-provider), the SDK model tree (legacy attribute classes, universal ComplianceFramework, ConfigRequirements guardrails), output formatters (legacy per-framework + universal data-driven), API/UI consumption, upstream sync workflows, and cloud-auditor check-mapping reviews. Trigger: When working with compliance frameworks (CIS, CIS Controls, NIST, PCI-DSS, SOC2, GDPR, ISO27001, ENS, MITRE ATT&CK, CCC, C5, CSA CCM, DORA, KISA ISMS-P, ASD Essential Eight, DISA STIG, CISA SCuBA, SecNumCloud, FedRAMP, HIPAA, NIS2, Prowler ThreatScore), creating a universal multi-provider framework, adding ConfigRequirements guardrails, syncing with upstream catalogs, auditing check-to-requirement mappings, adding output formatters, or fixing compliance JSON bugs (duplicate IDs, empty Version, wrong Section, stale check refs).

소스 정보

저장소
prowler-cloud/prowler
최근 소스 활동
2026년 7월 21일 08:24
감지된 SKILL.md 언어
영어
스타
14,884
포크
2,402

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
17 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
prowler-compliance
description
Creates, syncs, audits and manages Prowler compliance frameworks end-to-end. Covers the two supported JSON schemas (universal multi-provider and legacy per-provider), the SDK model tree (legacy attribute classes, universal ComplianceFramework, ConfigRequirements guardrails), output formatters (legacy per-framework + universal data-driven), API/UI consumption, upstream sync workflows, and cloud-auditor check-mapping reviews. Trigger: When working with compliance frameworks (CIS, CIS Controls, NIST, PCI-DSS, SOC2, GDPR, ISO27001, ENS, MITRE ATT&CK, CCC, C5, CSA CCM, DORA, KISA ISMS-P, ASD Essential Eight, DISA STIG, CISA SCuBA, SecNumCloud, FedRAMP, HIPAA, NIS2, Prowler ThreatScore), creating a universal multi-provider framework, adding ConfigRequirements guardrails, syncing with upstream catalogs, auditing check-to-requirement mappings, adding output formatters, or fixing compliance JSON bugs (duplicate IDs, empty Version, wrong Section, stale check refs).
license
Apache-2.0
metadata
{"author":"prowler-cloud","version":"2.0","scope":["root","sdk"],"auto_invoke":["Creating/updating compliance frameworks","Creating a universal (multi-provider) compliance framework","Mapping checks to compliance controls","Adding ConfigRequirements guardrails to compliance requirements","Syncing compliance framework with upstream catalog","Auditing check-to-requirement mappings as a cloud auditor","Adding a compliance output formatter (per-provider class + table dispatcher)","Fixing compliance JSON bugs (duplicate IDs, empty Section, stale refs)"]}
allowed-tools
Read, Edit, Write, Glob, Grep, Bash, WebFetch, WebSearch, Task
## When to Use Use this skill when: - Creating a new compliance framework for any provider — **decide universal vs legacy first** (see below) - **Syncing an existing framework with an upstream source of truth** (CIS, FINOS CCC, CSA CCM, NIST, ENS, etc.) - Adding requirements to existing frameworks, or extending a universal framework to a new provider - Mapping checks to compliance controls - **Adding `ConfigRequirements` guardrails** so configurable checks can't silently satisfy a requirement with a loosened config - **Auditing existing check mappings as a cloud auditor** ("are these mappings correct?", "which checks apply?", "review the mappings") - **Adding a new legacy output formatter** (table dispatcher + per-provider classes + CSV models) - **Fixing JSON bugs**: duplicate IDs, empty Version, wrong Section, stale check refs, inconsistent FamilyName, padded tangential check mappings - Investigating why a finding/check isn't showing under the expected compliance framework in the UI - Understanding compliance framework structures and attributes The authoritative contributor doc is `docs/developer-guide/security-compliance-framework.mdx` — keep this skill and that doc consistent when either changes. For **reviewing** a compliance PR, use the sister skill [prowler-compliance-review](../prowler-compliance-review/SKILL.md) instead. ## Universal vs Legacy: The First Decision Prowler supports **two JSON schemas**. Choosing wrong means unnecessary Python code, so decide this before anything else. At load time both converge: legacy files are adapted into the universal `ComplianceFramework` model (`adapt_legacy_to_universal()`), so the difference is about **authoring cost and capabilities**, not about what the rest of Prowler sees. ### Side-by-side comparison | | Universal (recommended for new frameworks) | Legacy provider-specific | |---|---|---| | File location | `prowler/compliance/<framework>.json` (top level) | `prowler/compliance/<provider>/<framework>_<version>_<provider>.json` | | Providers | Any number, one file (`checks` dict keyed by provider) | Exactly one provider per file (one file per provider to multi-cover) | | Key style | lowercase (`framework`, `requirements`, `checks`) | Capitalized (`Framework`, `Requirements`, `Checks`) | | Attribute schema | Declared **in the JSON itself** via `attributes_metadata`, validated at load | Pydantic class per framework family in `compliance_models.py` (code change for new shapes) | | Attributes per requirement | One flat dict (`attributes: {...}`) | List of objects (`Attributes: [{...}]`) — only `Attributes[0]` is used downstream | | Table/CSV/OCSF output | Data-driven from `outputs.table_config` — **zero Python changes** | Formatter package + registrations in `compliance.py`, `__main__.py`, `export.py` | | Guardrails field | `config_requirements` (+ mandatory `Provider` per constraint) | `ConfigRequirements` (`Provider` omitted) | | Loader behavior on error | Lenient: logs + skips file (`load_compliance_framework_universal`) | Fail-fast: `sys.exit(1)` (`load_compliance_framework`) | | Loaded by | Only `get_bulk_compliance_frameworks_universal()` | Both loaders (`Compliance.get_bulk()` + universal, via adapter) | | Shipped examples | `cis_controls_8.1.json`, `csa_ccm_4.0.json`, `dora_2022_2554.json` | Everything else (~105 files across 11 providers) | ### When to use which **Use universal when** (any of these): - The framework is **new to Prowler** — no existing attribute class, no existing formatter. This is the default: zero Python changes needed. - The framework spans (or will span) **more than one provider** — DORA, CSA CCM, CIS Controls. One file covers all providers; extending to a new provider is a one-line `checks` edit. - The attribute shape is **unique to this framework** — declare it in `attributes_metadata` instead of adding a Pydantic class to the Union. **Use legacy only when extending an existing legacy family**: - A new **version** of a shipped legacy framework (CIS 8.0 for AWS → new `cis_8.0_aws.json`, same `CIS_Requirement_Attribute`, same `cis/` formatter). - An existing legacy framework for a **new provider** (ENS for m365 → new `ens_rd2022_m365.json` + `ens_m365.py` transformer). - Consistency with the family matters more than the universal benefits — a lone `cis_8.0_aws` in universal format while 20+ CIS files stay legacy would fragment the family. **Never**: start a brand-new single-provider framework as legacy "because it's only AWS today". Universal handles single-provider fine (the `checks` dict just has one key) and you skip 3 output files + 3 registrations. ### The same requirement in both schemas Universal (`prowler/compliance/my_framework_1.0.json`): ```json { "framework": "My-Framework", "name": "My Framework 1.0", "version": "1.0", "description": "...", "attributes_metadata": [ {"key": "Section", "type": "str", "required": true}, {"key": "Service", "type": "str"} ], "outputs": {"table_config": {"group_by": "Section"}}, "requirements": [ { "id": "MF-1.1", "name": "Root MFA", "description": "Root account must have MFA enabled.", "attributes": {"Section": "IAM", "Service": "iam"}, "checks": { "aws": ["iam_root_mfa_enabled"], "azure": [] } } ] } ``` Legacy (`prowler/compliance/aws/my_framework_1.0_aws.json` — plus a second file per extra provider, plus formatter + registrations): ```json { "Framework": "My-Framework", "Name": "My Framework 1.0 for AWS", "Version": "1.0", "Provider": "AWS", "Description": "...", "Requirements": [ { "Id": "MF-1.1", "Name": "Root MFA", "Description": "Root account must have MFA enabled.", "Attributes": [ {"ItemId": "MF-1.1", "Section": "IAM", "Service": "iam"} ], "Checks": ["iam_root_mfa_enabled"] } ] } ``` Same control, but the universal file already covers Azure, validates its own attribute schema, and renders table/CSV/OCSF with no code. Field-by-field references for each schema follow below. ## Architecture (Mental Model) Prowler compliance is a four-layer system. Bugs usually happen where one layer doesn't match another, so know all four before touching anything. ### Layer 1: SDK / Core Models — `prowler/lib/check/` All in **Pydantic v1** (`from pydantic.v1 import ...`). Three model groups live in `compliance_models.py`: **Legacy tree** — `Compliance` → `Compliance_Requirement` / `Mitre_Requirement`: - One `*_Requirement_Attribute` class per framework family. Registered today (Union order matters): `ASDEssentialEight`, `CIS`, `ENS`, `ISO27001_2013`, `AWS_Well_Architected`, `KISA_ISMSP`, `Prowler_ThreatScore`, `CCC`, `C5Germany`, `CSA_CCM`, `STIG` (Okta IDaaS), and `Generic_Compliance_Requirement_Attribute` as fallback. - **Generic MUST stay LAST** in `Compliance_Requirement.Attributes: list[Union[...]]` — Pydantic v1 tries union members in order; Generic first would swallow every framework-specific attribute. NIST 800-53/CSF, PCI DSS, GDPR, HIPAA, SOC2, FedRAMP, SecNumCloud etc. intentionally use Generic. - A `root_validator` rejects empty `Framework`, `Provider` or `Name`. - MITRE uses the separate `Mitre_Requirement` model (`Tactics`, `SubTechniques`, `Platforms`, `TechniqueURL` at requirement top level, per-provider `Mitre_Requirement_Attribute_{AWS,Azure,GCP}`). **Universal tree** — `ComplianceFramework` → `UniversalComplianceRequirement`: - Flat `attributes: dict` per requirement, schema declared in `attributes_metadata` (key, label, type, enum, required, `enum_display`, `enum_order`, `output_formats`). A `root_validator` rejects missing required keys, unknown keys (drift guard), enum violations, and int/float/bool type mismatches. If `attributes_metadata` is omitted, **no validation runs**. - `checks: dict[provider, list[check_id]]` — the provider list of the framework is **derived** from these keys (`get_providers()` / `supports_provider()`); the top-level `provider` field is only a fallback. - `outputs.table_config` (group_by, split_by, scoring, labels) drives the CLI table; `outputs.pdf_config` exists in the model but **is not consumed by the API PDF pipeline yet** (see Layer 4). **Guardrails** — `Compliance_Requirement_ConfigConstraint`: - Fields `Check`, `ConfigKey`, `Operator` (`lte|gte|eq|in|subset|superset`), `Value`, optional `Provider` (required in universal multi-provider files). - A `root_validator` rejects Value/Operator type mismatches at load time. - Evaluation is centralized in `prowler/lib/check/compliance_config_eval.py` (`evaluate_config_constraints`, `apply_config_status`, `get_effective_status`, `CONFIG_NOT_VALID_PREFIX = "Configuration not valid for this requirement."`), shared by CSV/OCSF/table outputs **and** the API backend. A violated constraint forces the requirement to FAIL and prepends the reason to `status_extended`. Constraints whose `ConfigKey` is absent from `audit_config` are skipped (defaults assumed compliant). **Loaders**: - `Compliance.get_bulk(provider)` — legacy: scans only `prowler/compliance/{provider}/` (+ external JSONs via the `prowler.compliance` entry-point group). Does NOT see top-level universal files. - `get_bulk_compliance_frameworks_universal(provider)` — scans **both** the top-level `prowler/compliance/` and every provider subdirectory, adapting legacy files via `adapt_legacy_to_universal()` (flattens `Attributes[0]` to a dict, wraps `Checks` as `{provider: [...]}`, infers `attributes_metadata`). Also loads external universal frameworks via the `prowler.compliance.universal` entry-point group (built-ins win collisions). - `get_check_compliance(finding, provider_type, bulk_checks_metadata)` lives in **`prowler/lib/outputs/compliance/compliance_check.py`** (not in `lib/check/compliance.py`). It builds the per-finding dict keyed `f"{Framework}-{Version}"` **only when Version is non-empty** — an empty Version silently produces the key `"{Framework}"` and breaks downstream filters and tests. - `prowler/lib/check/compliance.py` now contains only `update_checks_metadata_with_compliance()`. ### Layer 2: JSON Catalogs — `prowler/compliance/` See "Compliance Catalog Coverage" below. ### Layer 3: Output Formatters — `prowler/lib/outputs/compliance/` **Universal path** (no Python needed per framework): - `universal/universal_table.py` — `get_universal_table()`, renders the CLI table from `outputs.table_config` + `attributes_metadata`. - `universal/universal_output.py` — `UniversalComplianceOutput`, builds the CSV Pydantic model **dynamically** from `attributes_metadata`. - `universal/ocsf_compliance.py` — `OCSFComplianceOutput`; OCSF output is **always generated** for universal frameworks regardless of `--output-formats`. - Orchestrated by `process_universal_compliance_frameworks()` in `compliance.py`, which runs **before** any legacy dispatch and removes the processed frameworks from the set. **Legacy path** — per-framework directory, usually: ```text {framework}/ ├── __init__.py ├── {framework}.py # get_{framework}_table() summary-table function ├── {framework}_{provider}.py # One ComplianceOutput subclass per provider └── models.py # One Pydantic CSV row model per provider ``` Directories today: `asd_essential_eight`, `aws_well_architected`, `c5`, `ccc`, `cis`, `cisa_scuba`, `ens`, `generic`, `iso27001`, `kisa_ismsp`, `mitre_attack`, `okta_idaas_stig`, `prowler_threatscore`, `universal`. Known deviations (don't "fix" them without a reason): `iso27001/` has no table file (falls to the generic table), `aws_well_architected/` has no per-provider files, `cisa_scuba/` only ships googleworkspace. - CSV writers emit `;`-delimited files with UPPERCASE headers (`ComplianceOutput.batch_write_data_to_file`). Field names in `models.py` are **public API** — renaming breaks downstream consumers. - **Circular import rule**: the table file (`{framework}.py`) must not import `Finding` directly or transitively (`compliance.compliance` → table module → `ComplianceOutput` → `Finding` → `get_check_compliance` → cycle). Keep table files bare (`colorama`, `tabulate`, `prowler.config.config`); when a module genuinely needs both, use `if TYPE_CHECKING:` or function-local imports (see `universal_output.py` / `process_universal_compliance_frameworks`). - Legacy table functions have no docstrings; the universal ones do. Match the style of the file family you're touching. - Dispatcher `display_compliance_table()` in `compliance.py` order: universal (`table_config`) first → `cis_` → `ens_` → `mitre_attack` → `kisa` → `prowler_threatscore_` → `c5_` → `ccc_` → `asd_essential_eight` (substring) → `okta_idaas_stig` → else provider hook (`provider.display_compliance_table()`, may raise `NotImplementedError`) → `get_generic_compliance_table()`. iso27001, aws_well_architected and cisa_scuba ride the fallback on purpose.
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기