关于 prowler-compliance
prowler-compliance 是用于构建和维护 Prowler 合规框架及检查映射的贡献者技能。它说明架构选择、框架加载、配置防护和输出流程。
主要功能
- 01通用与旧版架构指南
- 02框架和要求建模
- 03检查项与控制项映射指南
- 04ConfigRequirements 配置防护
- 05输出与格式化器架构
适用场景
- 01添加合规框架
- 02将框架扩展到其他提供商
- 03审查检查项映射
- 04排查框架结果问题
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ prowler-cloud/ prowler --skill prowler-compliance安装后在 Claude Code 中输入/prowler-compliance确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
assets/audit_framework_template.pybuild_inventory.pycis_framework.jsondump_section.pyens_framework.jsongeneric_framework.jsoniso27001_framework.jsonmitre_attack_framework.jsonprowler_threatscore_framework.jsonquery_checks.pysync_framework.pyassets/configs/ccc.yamlassets/parsers/__init__.pyfinos_ccc.pyreferences/check-mapping-reference.mdcompliance-docs.md详细介绍
适用场景
在以下情况下使用此技能:
- 为任意提供商创建新的合规框架——先决定采用通用格式还是旧版格式(见下文)
- 将现有框架与上游事实来源同步(CIS、FINOS CCC、CSA CCM、NIST、ENS 等)
- 为现有框架添加要求,或将通用框架扩展到新的提供商
- 将检查映射到合规控制项
- 添加
ConfigRequirements防护机制,避免可配置检查因配置放宽而悄然满足要求 - 以云审计员的身份审计现有检查映射(“这些映射正确吗?”、“哪些检查适用?”、“审查这些映射”)
- 添加新的旧版输出格式化器(表格分发器 + 各提供商的类 + CSV 模型)
- 修复 JSON 问题:重复 ID、Version 为空、Section 错误、检查引用过时、FamilyName 不一致、包含冗余的关联检查映射
- 调查为何某项发现/检查未在 UI 中显示于预期的合规框架下
- 了解合规框架的结构和属性
权威贡献者文档为 docs/developer-guide/security-compliance-framework.mdx——
任一文档变更时,都要确保此技能与该文档保持一致。要审查合规 PR,请改用配套技能
prowler-compliance-review。
通用格式还是旧版格式:首要决策
Prowler 支持两种 JSON 架构。选错会导致不必要的 Python
代码,因此在做其他事情之前先决定格式。加载时,两者都会汇聚到通用的
ComplianceFramework 模型中(通过 adapt_legacy_to_universal() 适配),所以差别在于编写成本
和功能,而非 Prowler 其他部分所能看到的内容。
并排对比
| 通用格式(新框架推荐) | 旧版按提供商划分的格式 | |
|---|---|---|
| 文件位置 | prowler/compliance/<framework>.json(顶层) | prowler/compliance/<provider>/<framework>_<version>_<provider>.json |
| 提供商 | 任意数量,一个文件(checks 字典以提供商为键) | 每个文件恰好对应一个提供商(需为每个提供商分别创建文件才能覆盖多个提供商) |
| 键名风格 | 小写(framework、requirements、checks) | 首字母大写(Framework、Requirements、Checks) |
| 属性架构 | 通过 attributes_metadata 在 JSON 本身中声明,加载时验证 | 每个框架系列在 compliance_models.py 中都有一个 Pydantic 类(新增结构需要修改代码) |
| 每项要求的属性 | 一个扁平字典(attributes: {...}) | 对象列表(Attributes: [{...}])——下游仅使用 Attributes[0] |
| 表格/CSV/OCSF 输出 | 由 outputs.table_config 驱动——无需修改 Python | 格式化器包 + 在 compliance.py、__main__.py、export.py 中注册 |
| 防护字段 | config_requirements(+ 每项约束都必须包含 Provider) | ConfigRequirements(省略 Provider) |
| 加载器出错时的行为 | 宽松:记录日志并跳过文件(load_compliance_framework_universal) | 遇错即退出:sys.exit(1)(load_compliance_framework) |
| 加载入口 | 仅 get_bulk_compliance_frameworks_universal() | 两个加载器都会加载(Compliance.get_bulk() 和通用加载器,后者通过适配器加载) |
| 随附示例 | cis_controls_8.1.json、csa_ccm_4.0.json、dora_2022_2554.json | 其他所有文件(11 个提供商中约有 105 个文件) |
应该使用哪种方式
在以下任一情况下使用通用格式:
- 该框架对 Prowler 来说是全新的——没有现有属性类,也没有现有格式化器。这是默认选择:无需修改 Python。
- 该框架涵盖(或将涵盖)多个提供商——DORA、CSA CCM、CIS Controls。一个文件即可覆盖所有提供商;扩展到新提供商只需编辑一行
checks。 - 该框架的属性结构独具特色——在
attributes_metadata中声明,而不是向 Union 添加 Pydantic 类。
仅在扩展现有旧版框架系列时使用旧版格式:
- 已发布的旧版框架推出新版本(AWS 的 CIS 8.0 → 新建
cis_8.0_aws.json,使用相同的CIS_Requirement_Attribute和cis/格式化器)。 - 为新提供商添加现有旧版框架(m365 的 ENS → 新建
ens_rd2022_m365.json+ens_m365.py转换器)。 - 系列一致性比通用格式的优势更重要——如果
cis_8.0_aws单独使用通用格式,而 20 多个 CIS 文件仍使用旧版格式,就会导致系列分散。
切勿:仅仅因为目前只有 AWS,就将全新的单提供商框架设为旧版格式。通用格式完全支持单提供商(checks 字典只需一个键),还能省去 3 个输出文件和 3 处注册。
两种模式中的同一项要求
通用格式(prowler/compliance/my_framework_1.0.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": []
}
}
]
}
旧版格式(prowler/compliance/aws/my_framework_1.0_aws.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"]
}
]
}
控制项相同,但通用格式文件已涵盖 Azure,可验证自身的属性架构,并且无需编写代码即可生成表格、CSV 和 OCSF。下面将逐字段介绍两种模式。
架构(概念模型)
Prowler 合规性是一个四层系统。问题通常出现在某一层与其他层不匹配时,因此在着手修改前,请先了解全部四层。
第 1 层:SDK / 核心模型 — prowler/lib/check/
全部使用 Pydantic v1(from pydantic.v1 import ...)。compliance_models.py 中包含三组模型:
旧版树 — Compliance → Compliance_Requirement / Mitre_Requirement:
- 每个框架系列对应一个
*_Requirement_Attribute类。目前已注册(Union 顺序很重要):ASDEssentialEight、CIS、ENS、ISO27001_2013、AWS_Well_Architected、KISA_ISMSP、Prowler_ThreatScore、CCC、C5Germany、CSA_CCM、STIG(Okta IDaaS),以及作为后备的Generic_Compliance_Requirement_Attribute。 - Generic 必须保持在
Compliance_Requirement.Attributes: list[Union[...]]的最后 — Pydantic v1 会按顺序尝试 Union 成员;如果 Generic 排在最前,就会吞掉所有 框架专用属性。NIST 800-53/CSF、PCI DSS、GDPR、HIPAA、SOC2、 FedRAMP、SecNumCloud 等框架会有意使用 Generic。 root_validator会拒绝空的Framework、Provider或Name。- MITRE 使用独立的
Mitre_Requirement模型(Tactics、SubTechniques、Platforms、TechniqueURL位于 requirement 顶层,每个提供商使用Mitre_Requirement_Attribute_{AWS,Azure,GCP})。
通用树 — ComplianceFramework → UniversalComplianceRequirement:
- 每个 requirement 都有扁平的
attributes: dict,其架构在attributes_metadata中声明(key、label、type、enum、required、enum_display、enum_order、output_formats)。root_validator会拒绝缺少必填项、 未知键(漂移保护)、违反枚举约束,以及 int/float/bool 类型不匹配的情况。 如果省略attributes_metadata,则不会运行任何校验。 checks: dict[provider, list[check_id]]— 框架的提供商列表由这些键推导而来 (get_providers()/supports_provider());顶层的provider字段仅作为后备。outputs.table_config(group_by、split_by、scoring、labels)驱动 CLI 表格;模型中存在outputs.pdf_config,但API PDF 管道目前尚未使用它 (见第 4 层)。
防护规则 — Compliance_Requirement_ConfigConstraint:
- 字段包括
Check、ConfigKey、Operator(lte|gte|eq|in|subset|superset)、Value,以及可选的Provider(通用多提供商文件中必填)。 root_validator会在加载时拒绝 Value/Operator 类型不匹配的情况。- 评估逻辑集中在
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."), 由 CSV/OCSF/表格输出以及 API 后端共享。违反约束会强制将 requirement 设为 FAIL, 并在status_extended前添加原因。如果audit_config中不存在对应的ConfigKey,则会跳过该约束(假定默认值符合要求)。
加载器:
Compliance.get_bulk(provider)— 旧版:仅扫描prowler/compliance/{provider}/(以及通过prowler.complianceentry-point group 加载的外部 JSON)。不会读取顶层的通用文件。get_bulk_compliance_frameworks_universal(provider)— 同时扫描顶层prowler/compliance/和所有提供商子目录,并通过adapt_legacy_to_universal()转换旧版文件(将Attributes[0]展平为 dict,将Checks封装为{provider: [...]},推断attributes_metadata)。 还会通过prowler.compliance.universalentry-point group 加载外部通用框架 (发生冲突时以内置框架为准)。get_check_compliance(finding, provider_type, bulk_checks_metadata)位于prowler/lib/outputs/compliance/compliance_check.py(不在lib/check/compliance.py中)。它会构建以f"{Framework}-{Version}"为键的 单条 finding 字典,仅当 Version 非空时才会这样做 — 如果 Version 为空, 会静默生成键"{Framework}",导致下游筛选器和测试出错。prowler/lib/check/compliance.py现在仅包含update_checks_metadata_with_compliance()。
第 2 层:JSON 目录 — prowler/compliance/
参见下文“合规目录覆盖范围”。
第 3 层:输出格式化器 — prowler/lib/outputs/compliance/
通用路径(每种框架都无需 Python):
universal/universal_table.py—get_universal_table(),根据outputs.table_config和attributes_metadata渲染 CLI 表格。universal/universal_output.py—UniversalComplianceOutput,根据attributes_metadata动态构建 CSV Pydantic 模型。universal/ocsf_compliance.py—OCSFComplianceOutput;无论--output-formats为何,通用框架都会始终生成 OCSF 输出。- 由
compliance.py中的process_universal_compliance_frameworks()编排,该函数会在任何旧版分派之前运行,并从集合中移除已处理的框架。
旧版路径 — 每个框架一个目录,通常如下:
{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
当前目录:asd_essential_eight、aws_well_architected、c5、ccc、
cis、cisa_scuba、ens、generic、iso27001、kisa_ismsp、
mitre_attack、okta_idaas_stig、prowler_threatscore、universal。
已知偏差(没有充分理由时不要“修复”):iso27001/ 没有表格文件(会回退到通用表格),aws_well_architected/ 没有按云服务提供商划分的文件,cisa_scuba/ 仅提供 googleworkspace。
- CSV 写入器会生成以
;分隔、带有大写表头的文件 (ComplianceOutput.batch_write_data_to_file)。models.py中的字段名称属于公共 API,重命名会破坏下游使用方。 - 循环导入规则:表格文件(
{framework}.py)不得直接或间接导入Finding(compliance.compliance→ 表格模块 →ComplianceOutput→Finding→get_check_compliance→ 循环)。表格文件应保持精简(colorama、tabulate、prowler.config.config);当某个模块确实需要同时使用这些内容时,使用if TYPE_CHECKING:或函数内导入(参见universal_output.py/process_universal_compliance_frameworks)。 - 旧版表格函数没有文档字符串;通用表格函数则有。修改时应遵循所改文件所属系列的风格。
compliance.py中的分派器display_compliance_table()按以下顺序处理: 通用(table_config)优先 →cis_→ens_→mitre_attack→kisa→prowler_threatscore_→c5_→ccc_→asd_essential_eight(子字符串)→okta_idaas_stig→ 否则调用云服务提供商钩子 (provider.display_compliance_table(),可能引发NotImplementedError)→get_generic_compliance_table()。iso27001、aws_well_architected 和 cisa_scuba 有意使用回退路径。
第 4 层:API / UI
- API 惰性加载器:
api/src/backend/api/compliance.py—LazyComplianceTemplate/LazyChecksMapping(基于get_bulk_compliance_frameworks_universal的按提供商惰性缓存,并通过 Gunicorn 在后台预热)。 - API CSV 导出分发:
api/src/backend/tasks/jobs/export.py中的COMPLIANCE_CLASS_MAP,由tasks/tasks.py使用。它是一个provider → [(predicate, exporter_class)]字典,并以GenericCompliance作为 回退。谓词混用了多版本系列的startswith(cis_、ens_、iso27001_、ccc_、cisa_scuba_等)和真正单例的 精确匹配name == ...(mitre_attack_aws、prowler_threatscore_*、asd_essential_eight_aws——而c5_azure/c5_gcp的处理方式不一致,aws 则使用startswith("c5_"))。 经验法则:如果框架以后可能增加版本或变体,就使用startswith。 - API 概览数据导入:
api/src/backend/tasks/jobs/scan.py中的create_compliance_requirements()从惰性模板构建各区域的行,并持久化ComplianceRequirementOverview(使用 COPY,失败时回退到 bulk-create),以及ComplianceOverviewSummary。 - API PDF 报告:
api/src/backend/tasks/jobs/reports/— 硬编码的FRAMEWORK_REGISTRY(使用自有的FrameworkConfig数据类,而非 SDK 的PDFConfig),每个框架对应一个生成器类。目前只有prowler_threatscore、ens、nis2、csa_ccm和cis支持 PDF; 添加 PDF 需要新增生成器类、注册项,并在report.py中接入。 - UI 映射器路由:
ui/lib/compliance/compliance-mapper.ts—getComplianceMappers()根据 JSON 的framework值进行映射 (例如"CIS"、"CIS-Controls"、"DORA"、"Okta-IDaaS-STIG")。未注册的 框架会自动回退到通用映射器 +GenericCustomDetails——专用映射器/详情面板是 一项重要增强功能,而非正常渲染的必要条件。 - UI 分组因映射器而异:通用映射器和 cis 按
Section/SubSection分组,iso 按Category分组,ccc 按FamilyName分组。 全部读取attributes[0]——同一 JSON 中的值不一致时会拆分为不同的树分支,因此发布前请先规范化。 - UI 类型:
ui/types/compliance.ts— 每个框架对应一个*AttributesMetadata接口,并将其添加到AttributesItemData元数据联合类型中。 - UI 图标:
ui/components/icons/compliance/+IconCompliance.tsx。 注册采用按顺序进行的子字符串匹配(COMPLIANCE_LOGOS):将框架专用关键词放在通用关键词之前 (nist放在nis2之前,cisa放在cis之前;aws则刻意放在最后)。
CLI 流水线(端到端)
prowler aws --compliance cis_7.0_aws # framework key = JSON basename
↓
Compliance.get_bulk("aws") # legacy frameworks
get_bulk_compliance_frameworks_universal("aws") # legacy (adapted) + universal
↓
update_checks_metadata_with_compliance() # attaches compliance to CheckMetadata
↓
execute_checks() → Finding objects
↓
get_check_compliance(finding, "aws", bulk) # dict "{Framework}-{Version}" → [req_ids]
↓
process_universal_compliance_frameworks() # universal: CSV + OCSF, then removed from set
per-provider elif branches in __main__.py # legacy: AWSCIS(...).batch_write_data_to_file()
↓
display_compliance_table() # universal table first, then legacy elifs,
# then generic fallback
合规目录覆盖范围
截至 2026-07 的数量(109 个 JSON 文件)。请先重新生成,再信任这些数据:
for d in prowler/compliance/*/; do printf "%s: %s\n" "$(basename $d)" "$(ls $d*.json 2>/dev/null | wc -l)"; done
ls prowler/compliance/*.json # universal, top-level
通用(顶层,多提供商):cis_controls_8.1.json(18 个提供商)、csa_ccm_4.0.json(aws/azure/gcp/alibabacloud/oraclecloud)、dora_2022_2554.json(aws/azure/gcp/alibabacloud/cloudflare)。
旧版的各提供商文件(框架系列,版本不尽列):
| 提供商 | # | 框架系列 |
|---|---|---|
| aws | 45 | CIS 1.4–7.0、NIST 800-53 r4/r5、NIST 800-171 r2、NIST CSF 1.1/2.0、PCI 3.2.1/4.0、ISO 27001 2013/2022、HIPAA、GDPR、SOC2、FedRAMP low/moderate r4 + 20x KSI low、ENS RD2022、MITRE ATT&CK、C5、CCC、CISA、FFIEC、RBI、Well-Architected(安全性/可靠性)、FTR、FSBP、AWS AI Security Framework、AWS Account Security Onboarding、Audit Manager Control Tower、GxP 21 CFR 11 / EU Annex 11、KISA ISMS-P 2023(en+ko)、NIS2、ASD Essential Eight、SecNumCloud 3.2、Prowler ThreatScore |
| azure | 19 | CIS 2.0–6.0、ISO 27001 2022、ENS RD2022、MITRE ATT&CK、PCI 4.0、HIPAA、SOC2、NIS2、RBI、C5、CCC、FedRAMP 20x KSI low、SecNumCloud 3.2、Prowler ThreatScore |
| gcp | 17 | CIS 2.0–5.0、ISO 27001 2022、ENS RD2022、MITRE ATT&CK、PCI 4.0、HIPAA、SOC2、NIS2、RBI、C5、CCC、FedRAMP 20x KSI low、SecNumCloud 3.2、Prowler ThreatScore |
| kubernetes | 8 | CIS 1.8–2.0.1、ISO 27001 2022、PCI 4.0、Prowler ThreatScore |
| m365 | 5 | CIS 4.0/6.0/7.0、ISO 27001 2022、Prowler ThreatScore |
| alibabacloud | 3 | CIS 2.0、SecNumCloud 3.2、Prowler ThreatScore |
| oraclecloud | 3 | CIS 3.0/3.1、SecNumCloud 3.2 |
| github | 2 | CIS 1.0/1.2.0 |
| googleworkspace | 2 | CIS 1.3、CISA SCuBA 0.6 |
| okta | 1 | Okta IDaaS STIG V1R2 |
| nhn | 1 | ISO 27001 2022 |
有合规目录但尚无框架的提供商:cloudflare、iac、linode、llm、mongodbatlas、openstack、stackit。通用 checks 字典中的提供商键必须与 prowler/providers/ 下的目录名称匹配(小写)。
通用架构参考
完整规范见 docs/developer-guide/security-compliance-framework.mdx。骨架:
{
"framework": "DORA",
"name": "Digital Operational Resilience Act (DORA) 2022/2554",
"version": "2022/2554",
"description": "Shown in --list-compliance and PDF reports.",
"icon": "dora",
"attributes_metadata": [
{"key": "Pillar", "label": "Pillar", "type": "str", "required": true,
"enum": ["ICT Risk Management", "..."],
"output_formats": {"csv": true, "ocsf": true}},
{"key": "Article", "type": "str", "required": true}
],
"outputs": {
"table_config": {"group_by": "Pillar"},
"pdf_config": {"group_by_field": "Pillar", "charts": ["..."]}
},
"requirements": [
{
"id": "DORA-Art5",
"name": "Governance and organisation",
"description": "Requirement text verbatim from the source.",
"attributes": {"Pillar": "ICT Risk Management", "Article": "Article 5"},
"checks": {
"aws": ["iam_no_root_access_key"],
"azure": [],
"gcp": []
},
"config_requirements": [
{"Check": "iam_user_accesskey_unused", "Provider": "aws",
"ConfigKey": "max_unused_access_keys_days", "Operator": "lte", "Value": 45}
]
}
]
}
通用字段,顶层(ComplianceFramework)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
framework | string | 是 | 简短标识符(DORA、CSA-CCM、CIS-Controls)。UI 映射器根据此键进行路由。 |
name | string | 是 | 易读的全名。 |
version | string | 否(不可留空) | 框架版本/版次(8.1、2022/2554)。 |
description | string | 是 | 显示在 --list-compliance 和 PDF 报告中。 |
provider | string | 否 | 仅作回退 — 有效的提供商列表根据各项要求中 checks 的键推导得出(get_providers())。 |
icon | string | 否 | 简短的图标标识。 |
attributes_metadata | array | 否(强烈建议) | 声明每个 attributes 键的架构。如果省略,则完全不会运行属性验证。 |
outputs | object | 否 | table_config(CLI 表格)+ pdf_config(已建模,但 API 尚未使用)。 |
requirements | array | 是 | 要求对象列表(见下文)。 |
通用字段,每项要求(UniversalComplianceRequirement)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
id | string | 是 | 在框架内唯一。 |
description | string | 是 | 与来源中的要求文本完全一致。 |
name | string | 否 | 简短标题。 |
attributes | dict | 否(默认为 {}) | 扁平字典;每个键都必须在 attributes_metadata 中声明(存在元数据时,加载时会拒绝未知键)。 |
checks | dict | 否(默认为 {}) | {provider: [check_ids]},键须为小写并与 prowler/providers/ 下的目录名称匹配。空列表 = 该提供商的手动要求。 |
config_requirements | array | 否 | 防护规则;每项约束都必须包含 Provider。 |
tactics、sub_techniques、platforms、technique_url | — | 否 | MITRE 风格的扩展字段(改编旧版 MITRE 文件时自动填充)。 |
attributes_metadata 条目字段(AttributeMetadata)
| 字段 | 类型 | 说明 |
|---|---|---|
key | string(必填) | 在 requirement.attributes 中使用的属性名称。 |
label | string | CSV 表头 / PDF 中显示的易读标签。 |
type | string | str(默认)、int、float、bool、list_str、list_dict。加载时仅强制校验 int/float/bool,其余仅用于文档说明。 |
enum | list | 允许的值 — 加载时强制校验。值集合固定时务必使用。 |
required | bool | 加载时强制校验:每项要求都必须包含该键,且值不能为空。 |
enum_display / enum_order | dict / list | 每个枚举值的视觉元数据(标签、缩写、颜色、图标)以及 PDF 渲染的排序。 |
chart_label | string | 将属性用于图表时的坐标轴标签。 |
output_formats | object | {"csv": bool, "ocsf": bool},两者默认均为 true — 用于控制是否包含在对应输出中。 |
关键规则:
--compliance键 = 不含.json的 JSON 文件名(dora_2022_2554)。- 自动发现:无需
__init__.py、格式化器或调度器注册。 table_config.group_by、pdf_config.group_by_field以及每个charts[].group_by都必须引用attributes_metadata中声明的键。- 运行时类型校验仅涵盖
int/float/bool;str/list_str/list_dict仅用于文档说明。 - 扩展到新提供商 = 向
requirement.checks添加一个键。无需其他操作。 - 加载时不会自动校验检查是否存在 — 拼错的检查 ID 会静默地生成没有发现结果的要求。务必运行检查存在性对照校验(见 Validation)。
- 在通用文件中,务必为每条配置约束设置
Provider,这样针对 AWS 检查编写的护栏就不会影响对同一要求进行的 Azure/GCP 扫描。
旧版架构参考
旧版文件基本结构:
{
"Framework": "FRAMEWORK_NAME",
"Name": "Full Framework Name with Version",
"Version": "X.X",
"Provider": "AWS",
"Description": "Framework description...",
"Requirements": [
{
"Id": "requirement_id",
"Name": "Optional requirement name",
"Description": "Requirement description",
"Attributes": [ ... ],
"Checks": ["check_name_1"],
"ConfigRequirements": [ ... ]
}
]
}
旧版顶层字段(Compliance)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
Framework | string | 是(非空,已校验) | 规范标识符(CIS、ENS、NIST-800-53-Revision-5)。 |
Name | string | 是(非空,已校验) | 带版本号的易读名称。 |
Version | string | 模型中可选 — 实际使用时切勿留空 | Version 为空会使 get_check_compliance() 键静默退化为 "{Framework}"(注意事项 #4)。必须与文件名中的版本子串一致。 |
Provider | string | 是(非空,已校验) | 大写的单一提供商(AWS、AZURE、GCP、M365 等)。一个文件对应一个提供商。 |
Description | string | 是 | 框架的范围和用途。 |
Requirements | array | 是 | 要求对象(如下),MITRE 文件则使用 Mitre_Requirement 对象。 |
旧版逐条要求字段(Compliance_Requirement)
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
Id | string | 是 | 框架内唯一;严格遵循来源编号(1.1、A.5.1、CCC.Core.CN01.AR01)。 |
Description | string | 是 | 与来源目录中的内容完全一致。 |
Name | string | 否 | 可选的简短标题(NIST 风格目录会使用)。 |
Attributes | 对象数组 | 是 | 根据下方的属性类并集解析;通用适配后仅保留 Attributes[0],并由其决定 UI 分组。 |
Checks | 字符串数组 | 是 | 用于自动化该要求的检查 ID;[] = 手动处理。 |
ConfigRequirements | array | 否 | 护栏;由于文件仅对应一个提供商,省略 Provider。 |
MITRE 文件改用 Mitre_Requirement,并在要求顶层增加
Tactics、SubTechniques、Platforms、TechniqueURL。
各框架系列的属性结构
与通用格式(架构内嵌于文件)不同,旧版需求的 Attributes 必须与
Compliance_Requirement.Attributes 中注册的某个 Pydantic 类匹配——如果某种结构
与任何类都不匹配,会静默回退到 Generic,并丢失其特定字段。最常见的结构
(完整字段集见 compliance_models.py):
CIS — cis_{version}_{provider}
{
"Section": "1 Identity and Access Management",
"SubSection": "Optional subsection",
"Profile": "Level 1",
"AssessmentStatus": "Automated",
"Description": "...", "RationaleStatement": "...", "ImpactStatement": "...",
"RemediationProcedure": "...", "AuditProcedure": "...",
"AdditionalInformation": "...", "DefaultValue": "...", "References": "https://..."
}
Profile:Level 1|Level 2|E3 Level 1|E3 Level 2|E5 Level 1|E5 Level 2。
AssessmentStatus:Automated|Manual。
ENS — ens_rd2022_{provider}
{
"IdGrupoControl": "op.acc.1", "Marco": "operacional",
"Categoria": "control de acceso", "DescripcionControl": "...",
"Nivel": "alto", "Tipo": "requisito",
"Dimensiones": ["trazabilidad", "autenticidad"],
"ModoEjecucion": "automatico", "Dependencias": []
}
Nivel:opcional|bajo|medio|alto。Tipo:refuerzo|requisito|recomendacion|medida。
Dimensiones:confidencialidad|integridad|trazabilidad|autenticidad|disponibilidad。
ISO 27001 — iso27001_{year}_{provider}
{
"Category": "A.5 Organizational controls",
"Objetive_ID": "A.5.1", "Objetive_Name": "Policies for information security",
"Check_Summary": "Summary of what is being checked"
}
注意:Objetive_ID / Objetive_Name 使用的正是这一(错误)拼写。
MITRE ATT&CK — mitre_attack_{provider}(单独的需求模型)
{
"Name": "Exploit Public-Facing Application", "Id": "T1190",
"Tactics": ["Initial Access"], "SubTechniques": [],
"Platforms": ["IaaS"], "Description": "...",
"TechniqueURL": "https://attack.mitre.org/techniques/T1190/",
"Checks": ["guardduty_is_enabled"],
"Attributes": [
{"AWSService": "Amazon GuardDuty", "Category": "Detect",
"Value": "Minimal", "Comment": "..."}
]
}
其他提供商使用 AzureService/GCPService。Category:
Detect|Protect|Respond。Value:Minimal|Partial|Significant。
CCC — ccc_{provider}
{
"FamilyName": "Data", "FamilyDescription": "...",
"Section": "CCC.Core.CN01 Encrypt Data for Transmission", "SubSection": "",
"SubSectionObjective": "...",
"Applicability": ["tlp-green", "tlp-amber", "tlp-red"],
"Recommendation": "...",
"SectionThreatMappings": [{"ReferenceId": "CCC", "Identifiers": ["CCC.Core.TH02"]}],
"SectionGuidelineMappings": [{"ReferenceId": "NIST-CSF", "Identifiers": ["PR.DS-02"]}]
}
Applicability 包含 TLP 标签(tlp-clear|tlp-green|tlp-amber|tlp-red)。
ASD Essential Eight — asd_essential_eight_aws
{
"Section": "Patch applications", "MaturityLevel": "ML1",
"AssessmentStatus": "Automated", "CloudApplicability": "partial",
"MitigatedThreats": ["..."], "Description": "...",
"RationaleStatement": "...", "ImpactStatement": "...",
"RemediationProcedure": "...", "AuditProcedure": "...",
"AdditionalInformation": "...", "References": "..."
}
MaturityLevel:ML1|ML2|ML3。CloudApplicability:full|partial|limited|non-applicable。
DISA STIG — okta_idaas_stig_v1r2_okta
{
"Section": "...", "Severity": "high", "RuleID": "...", "StigID": "...",
"CCI": ["CCI-000015"], "CheckText": "...", "FixText": "..."
}
Severity:high|medium|low(映射到 CAT I/II/III)。
其他已注册的结构
- AWS Well-Architected(
aws_well_architected_framework_{pillar}_pillar_aws):Name、WellArchitectedQuestionId、WellArchitectedPracticeId、Section、SubSection、LevelOfRisk、AssessmentMethod、Description、ImplementationGuidanceUrl。 - KISA ISMS-P(
kisa_isms_p_2023_{provider}):Domain、Subdomain、Section、AuditChecklist、RelatedRegulations、AuditEvidence、NonComplianceCases。 - C5(
c5_{provider}):Section、SubSection、Type、AboutCriteria、ComplementaryCriteria。 - CSA CCM(旧版结构;随附的 CSA CCM 4.0 为通用格式):
Section、CCMLite、IaaS、PaaS、SaaS、ScopeApplicability。 - Prowler ThreatScore(
prowler_threatscore_{provider}):Title、Section、SubSection、AttributeDescription、AdditionalInformation、LevelOfRisk(1–5)、Weight(1/8/10/100/1000)。支柱:1 IAM、2 攻击 面、3 日志记录与监控、4 加密。适用于 aws、azure、gcp、kubernetes、m365、alibabacloud。 - Generic(回退):
ItemId、Section、SubSection、SubGroup、Service、Type、Comment——均为可选字段。用于 NIST、PCI、GDPR、 HIPAA、SOC2、FedRAMP、CISA、FFIEC、RBI、NIS2、GxP、SecNumCloud 等。
配置护栏(ConfigRequirements)
由可配置检查
支持的需求,可能会因放宽 audit_config 而被静默地判定为“已满足”(例如 CIS 要求未使用的凭证保留 45 天,但扫描使用了 max_unused_access_keys_days: 120)。
护栏会强制此类需求判定为 FAIL:
"ConfigRequirements": [
{"Check": "iam_user_accesskey_unused",
"ConfigKey": "max_unused_access_keys_days", "Operator": "lte", "Value": 45}
]
- 运算符:
lte/gte(数值阈值)、eq(开关/精确值——使用 JSON 布尔值,而非 0/1)、in(标量属于允许集合)、subset(允许列表—— 扩大范围会导致检查失败)、superset(拒绝列表——移除条目会导致检查失败)。 Value必须是控制文本所容许的最严格设置。ConfigKey必须与检查读取的键完全一致;未知键会被静默跳过(假定默认值符合要求)。- 护栏只会收紧要求(PASS→FAIL),不会放宽要求。
- 通用文件:小写的
config_requirements+ 每个约束都必须包含Provider。 - 测试:
tests/lib/check/compliance_config_eval_test.py、compliance_config_constraint_model_test.py、compliance_config_requirements_data_test.py,以及tests/lib/outputs/compliance/下各输出对应的测试。
工作流 A:将框架与上游目录同步
当框架由上游维护(CIS Benchmarks、FINOS CCC、CSA CCM、NIST、ENS 等),而 Prowler 需要跟进时使用。
步骤 1 — 缓存上游源
将所有上游文件下载到本地缓存,避免迭代时访问网络。对于 FINOS CCC:
mkdir -p /tmp/ccc_upstream
catalogs="core/ccc storage/object management/auditlog management/logging ..."
for p in $catalogs; do
safe=$(echo "$p" | tr '/' '_')
gh api "repos/finos/common-cloud-controls/contents/catalogs/$p/controls.yaml" \
-H "Accept: application/vnd.github.raw" > "/tmp/ccc_upstream/${safe}.yaml"
done
步骤 2 — 使用框架配置运行通用同步运行器
同步工具分为三个层,因此添加框架只需提供 YAML 配置(以及针对不熟悉的上游格式的解析器模块):
skills/prowler-compliance/assets/
├── sync_framework.py # generic runner — works for any framework
├── configs/ccc.yaml # per-framework config (canonical example)
└── parsers/finos_ccc.py # parser module for FINOS CCC YAML
python skills/prowler-compliance/assets/sync_framework.py \
skills/prowler-compliance/assets/configs/ccc.yaml
运行器会加载配置,动态导入 parser.module,调用
parse_upstream(config) -> list[dict],然后应用通用后处理(ID 唯一性安全检查、FamilyName 规范化、使用配置驱动的回退键保留旧版检查映射),并通过 Pydantic 后验证写入提供商 JSON。
添加新框架同步:
- 编写
assets/configs/{framework}.yaml(参见ccc.yaml)。必需部分:framework—name、display_name、version(不得为空——运行器会拒绝启动,因为空的 Version 会破坏get_check_compliance()键)、description_template。providers—{key, display}对组成的列表。output.path_template— 例如:"prowler/compliance/{provider}/cis_{version}_{provider}.json"。upstream.dir— 本地缓存(步骤 1)。parser.module—parsers/下的模块;其余parser.配置会以不透明形式传递。post_processing.check_preservation.primary_key(几乎总是Id)和fallback_keys—Attributes[0]字段名列表,组合成元组,用于在 ID 变更时恢复映射。CCC:- [Section, Applicability];CIS:- [Section, Profile];NIST:- [ItemId]。列表类型字段会自动冻结为frozenset。post_processing.family_name_normalization(可选)— 原始值 → 规范值映射;UI 按完全匹配的属性值分组,否则上游变体会成为单独的树分支。
- 复用现有解析器,或编写实现
parse_upstream(config) -> list[dict]的parsers/{name}.py,返回 Prowler 格式的要求,并确保 ID 唯一。运行器遇到重复 ID 会报错——绝不会静默重新编号,因为修改规范上游 ID(CIS1.1.1、NISTAC-2(1))会造成灾难性后果。解析器负责处理所有上游格式差异:外来前缀重写、实际冲突重新编号、多种结构处理。
运行器已处理的注意事项(来自 FINOS CCC v2025.10 同步):
- 多种上游 YAML 结构。 大多数 FINOS CCC 目录使用
control-families: [...],但storage/object使用顶层controls: [...]。只支持单一结构的解析器会静默丢弃整个目录——这个确切的错误曾导致 ObjStor 在一次完整迭代中被丢弃。请分别用每种结构的一个文件进行测试。 - 空白字符合并。 上游
|块标量会保留换行符;Prowler 存储为单行文本。使用" ".join(value.split())合并。 - 外来前缀 ID 重写。 上游会在多个目录间别名引用要求,并保留原始前缀(嵌套在
CCC.Logging.CN03下的CCC.AuditLog.CN08.AR01)——请重写以匹配父级(CCC.Logging.CN03.AR01)。 - 真实的上游冲突。 两个不同的要求共享一个 ID(上游笔误):将第二个要求重新编号为下一个可用编号;检查映射保留逻辑会通过回退键恢复映射。
- 填充
Version— 快速失败胜过静默的键错误。
步骤 3 — 提交前验证
运行下方完整的验证流程(通用加载器 + 检查项存在性 + CLI 冒烟测试 + pytest)。
第 4 步 — 根据需要添加属性模型
仅当框架包含 Generic_Compliance_Requirement_Attribute
以外的字段且必须保持旧版兼容时才需要。将类添加到
compliance_models.py,并将其注册到
Compliance_Requirement.Attributes Union 中的 Generic 之前(Generic 保持在最后)。
对于新框架,优先使用通用的 attributes_metadata。
工作流 B:以云审计员身份审计检查项映射
当用户要求审查现有映射时使用。此项是价值最高的合规任务——它能发现覆盖率为零的虚增映射,以及遗漏的有效覆盖映射。
黄金法则
Prowler 检查项的标题/风险 必须如实描述要求文本的内容。“相关”还不够。如果没有检查项真正满足该要求,请将检查项列表留空(MANUAL)——诚实地标记为 MANUAL,胜过虚增覆盖率。
审计流程
-
按提供商构建检查项清单 —
assets/build_inventory.py(为prowler/providers/下发现的每个提供商写入/tmp/checks_{provider}.json)。 -
查询清单 —
assets/query_checks.py(从仓库根目录运行):python skills/prowler-compliance/assets/query_checks.py aws encryption transit # keyword AND-search python skills/prowler-compliance/assets/query_checks.py aws --service iam # all iam checks python skills/prowler-compliance/assets/query_checks.py aws --id kms_cmk_rotation_enabled -
导出带有当前映射的框架章节 —
assets/dump_section.py:python skills/prowler-compliance/assets/dump_section.py ccc "CCC.Core." python skills/prowler-compliance/assets/dump_section.py cis_5.0_aws "1." -
编码明确的 REPLACE 决策 —
assets/audit_framework_template.py:DECISIONS = {} DECISIONS["CCC.Core.CN01.AR01"] = { "aws": ["cloudfront_distributions_https_enabled", ...], "azure": ["storage_secure_transfer_required_is_enabled", ...], "gcp": ["cloudsql_instance_ssl_connections"], # Missing provider key = leave the legacy mapping untouched } # Empty list = EXPLICITLY MANUAL (overwrites legacy) DECISIONS["CCC.Core.CN01.AR07"] = {"aws": [], "azure": [], "gcp": []}使用 REPLACE,而非 PATCH。 完整列表能让审计可重现,并揭示旧版数据中隐藏的假设。
-
预先验证每个检查项 ID 是否存在于清单中;脚本必须中止,并在标准错误输出中列出拼写错误(实际审计曾发现
storage_secure_transfer_required_enabled→storage_secure_transfer_required_is_enabled、sqlserver_minimum_tls_version_12→sqlserver_recommended_minimal_tls_version,以及多个根本不存在的检查项)。 -
应用 + 验证 + 测试:
python /path/to/audit_script.py uv run pytest -n auto tests/lib/outputs/compliance/ tests/lib/check/ -q
对于整理后的映射表(要求文本 → AWS/Azure/GCP 检查项),以及 Prowler 确实无法验证的控制项列表,请参阅 references/check-mapping-reference.md。
工作流 C:添加新的通用框架
- 按照上文的通用架构参考,编写
prowler/compliance/{framework}_{version}.json(以dora_2022_2554.json或csa_ccm_4.0.json为模板)。 - 在
attributes_metadata中声明每个属性(尽可能设置required/enum——这就是加载时验证机制),并设置outputs.table_config.group_by。 - 按提供商映射检查项;对于可配置的检查项,添加
config_requirements(含Provider);对于手动要求,保留空列表——包含源目录中的每一项要求(覆盖率百分比取决于完整的分母)。 - 进行验证(见下文)。CLI 表格/CSV/OCSF 无需进行任何 Python 注册。
- 可选:添加一流的 UI 支持:在
ui/lib/compliance/{framework}.tsx中编写映射器,在getComplianceMappers()中使用 JSON 的framework值注册,添加详情面板、*AttributesMetadata类型和图标(关键词顺序很重要!)。在此之前,通用映射器会负责渲染。 - 可选:添加 API 扩展:在
COMPLIANCE_CLASS_MAP中添加 CSV 导出器条目;如需 PDF,则添加 PDF 生成器和FRAMEWORK_REGISTRY条目。 - 测试:在
tests/lib/check/universal_compliance_models_test.py中添加加载新 JSON 的测试用例。参数化测试test_loads_as_universal已会自动发现该文件。 - 为高关注度框架添加变更日志片段
prowler/changelog.d/<slug>.added.md,并在docs/user-guide/compliance/tutorials/下添加用户指南教程。
工作流 D:添加新的旧版输出格式化器
仅适用于现有旧版系列中的新成员。严格遵循 c5/ 或 ccc/
布局:
- 使用
mkdir prowler/lib/outputs/compliance/{framework}创建目录,并添加__init__.py。 {framework}.py— 复制c5/c5.py,修改函数名和框架字符串;差异应仅限这几行。不要添加文档字符串(旧版风格)。models.py— 每个提供商使用一个 Pydantic CSV 行模型。各提供商的列集不同(AccountId/Region与SubscriptionId/Location,或ProjectId/Location);按提供商拆分文件是惯例——不要将它们合并成参数化类,审阅者会拒绝。{framework}_{provider}.py—{Framework}_{Provider}(ComplianceOutput),并实现transform();此文件可以导入Finding。- 注册:
compliance.py→display_compliance_table()中的elif分支(以及顶部导入)。prowler/__main__.py→ 按提供商设置elif compliance_name.startswith(...)分支,实例化写入器类。api/src/backend/tasks/jobs/export.py→COMPLIANCE_CLASS_MAP条目(系列使用startswith,仅真正的单例使用精确匹配)。
- 在
tests/lib/outputs/compliance/{framework}/下添加测试,并在tests/lib/outputs/compliance/fixtures.py中添加夹具(各添加 1 个已评估和 1 个手动要求,以覆盖两条transform()路径)。
循环导入警告:表格文件不得直接或间接导入 Finding(循环链路:compliance.compliance → table → ComplianceOutput → Finding → get_check_compliance → compliance.compliance)。保持文件精简;确实需要两者时,使用 TYPE_CHECKING/函数局部导入。
验证(每次提交前运行)
-
加载架构(两种格式):
from prowler.lib.check.compliance_models import ( load_compliance_framework_universal, get_bulk_compliance_frameworks_universal, ) fw = load_compliance_framework_universal("prowler/compliance/<file>.json") assert fw is not None, "check logs for the ValidationError" print(fw.framework, len(fw.requirements), fw.get_providers()) assert "<file_basename>" in get_bulk_compliance_frameworks_universal("aws")请记住:通用加载器较为宽容(会跳过有问题的文件并记录日志)——必须执行
assert fw is not None,扫描通过并不能证明一切正常。 -
检查是否存在——没有加载器会验证这一点;过时的 ID 会悄无声息地失去作用:
import json from pathlib import Path for prov in ["aws", "azure", "gcp"]: real = {p.stem.replace(".metadata", "") for p in Path(f"prowler/providers/{prov}/services").rglob("*.metadata.json")} data = json.load(open(f"prowler/compliance/{prov}/<file>.json")) refs = {c for r in data["Requirements"] for c in r["Checks"]} missing = refs - real assert not missing, f"{prov} missing: {missing}"(对于通用文件,请改用
r.get("checks", {}).get(prov, [])——要求可能会合理地省略某个提供商键。) -
CLI 冒烟测试:
uv run python prowler-cli.py <provider> --list-compliance # appears? uv run python prowler-cli.py <provider> --compliance <key> --log-level ERROR检查
output/compliance/下的 CSV、摘要表格各部分,以及发现项汇总。 -
测试:
uv run pytest -n auto tests/lib/check/universal_compliance_models_test.py \ tests/lib/outputs/compliance/test_loads_as_universal会针对prowler/compliance/中的每个 JSON 文件(顶层及子目录)运行参数化测试——即使你没有编写专门的测试,格式错误的文件也会在此导致 CI 失败。 -
CI/pre-commit 的覆盖范围:pre-commit 只保证 JSON 格式正确且美观(
check-json、pretty-format-json)——不进行语义验证。工作流.github/workflows/pr-check-compliance-mapping.yml会标记新增检查但未映射到任何框架的 PR(标签needs-compliance-review;使用标签no-compliance-check可跳过)。语义验证由上述 pytest 测试套件和手动运行skills/prowler-compliance-review/assets/validate_compliance.py完成(注意:该验证器假定使用旧版架构)。 -
Prowler 本地服务器:运行
docker compose up,确认合规性页面能够呈现要求、章节和小组件。
惯例与经验教训
- 优先采用通用格式。 新框架如果一开始就采用旧格式,需要 3 个输出文件和 3 处注册;同一框架采用通用格式则完全不需要。仅扩展旧格式系列。
Generic_Compliance_Requirement_Attribute必须放在旧格式 Attributes 联合类型的最后——Pydantic v1 会按顺序尝试成员;如果 Generic 排在最前面,就会悄无声息地吞掉所有特定形状。compliance_models.py中处处使用 Pydantic v1 (from pydantic.v1 import ...)。不要混用 v2。get_check_compliance()位于prowler/lib/outputs/compliance/compliance_check.py,只有 Version 非空时才用f"{Framework}-{Version}"作为字典键。绝不能提交Version: ""——键会悄无声息地退化为"{Framework}",导致筛选、测试和--compliance出错。对于旧格式文件,文件名中的版本子串必须与Version一致(CLI 会读取compliance_framework.split("_")[1])。Compliance.get_bulk()不会读取顶层通用格式文件——只有get_bulk_compliance_frameworks_universal()会读取。新代码路径必须接入通用格式加载器。- 加载器的容错行为不同:旧格式加载器遇到损坏的 JSON 会退出进程;通用格式加载器则会记录日志并跳过。修改后找不到某个框架,通常是通用格式加载器将其丢弃了——请检查日志。
- 防止循环导入:旧格式表格分发器文件不得(直接或间接)导入
Finding。如果某个模块需要同时使用两侧内容,请使用TYPE_CHECKING或函数内导入(通用格式格式化器就是这样做的)。 - 每个提供商对应一个格式化器文件是旧格式惯例——但在指出问题前,要了解例外情况(iso27001 没有表格文件,aws_well_architected 没有按提供商划分的文件,cisa_scuba 仅适用于 googleworkspace)。CSV 模型字段名称属于公开 API。
- CSV 输出:分隔符为
;,表头为大写。无论--output-formats如何设置,通用格式框架始终会生成 OCSF 合规性输出。 COMPLIANCE_CLASS_MAP混用了不同的判断方式:多版本系列使用startswith,单例使用精确的==。不确定时使用startswith——精确匹配曾导致带版本的 CCC 变体无法通过,直到 2026 年才修复。- UI 分组按映射器分别处理,且始终使用
attributes[0]:generic/cis →Section/SubSection,iso →Category,ccc →FamilyName。值不一致(或 Section 为空)会产生孤立或重复的树分支——发布前请先规范化。 - UI 有通用回退方案——未注册的框架仍会渲染。专用映射器/面板/图标属于增强项,并非前置条件。
- 图标注册在
IconCompliance.tsx中按子串顺序匹配——特定关键词必须排在通用关键词之前(nist在nis2之前,cisa在cis之前,aws最后)。 - API PDF 流程目前还不是由
PDFConfig驱动——它有自己的FRAMEWORK_REGISTRY(包含 5 个框架)。不要以为在 JSON 中添加pdf_config就会在 Prowler App 中生成 PDF。 - 编写 JSON 前,先根据每个提供商的清单验证所有检查 ID。没有任何加载器会发现拼写错误;该要求只会永远匹配不到发现项。
- 对于审计决策,REPLACE 优于 PATCH——完整明确的列表便于复现,也能暴露旧有假设。
- 没有适用的检查项时,使用 MANUAL 才是正确做法。 不要用无关的检查项凑数;合规报告必须保持可操作性。
- 纳入来源目录中的每一项要求,无论是否自动化——合规百分比以要求总数作为分母。
- 各提供商的覆盖范围并不对称(AWS 覆盖较全;Azure/GCP 覆盖较少;新提供商覆盖最少)。接受这种情况——不要强求 Prowler 无法验证的覆盖一致性。
- 编写防护规则:使用容忍范围内最严格的
Value,ConfigKey拼写必须完全准确,通用格式文件必须包含Provider,布尔值必须使用 JSON 布尔值。格式错误的约束会被视为满足——请通过配置测试进行验证,不要因为没有报错就掉以轻心。
实用单行命令
# Find duplicate requirement IDs (legacy | universal)
jq -r '.Requirements[].Id' file.json | sort | uniq -d
jq -r '.requirements[].id' file.json | sort | uniq -d
# Count manual requirements (legacy | universal, per provider)
jq '[.Requirements[] | select((.Checks | length) == 0)] | length' file.json
jq '[.requirements[] | select((.checks.aws // [] | length) == 0)] | length' file.json
# List unique check references (legacy | universal)
jq -r '.Requirements[].Checks[]' file.json | sort -u
jq -r '.requirements[].checks[]? | .[]' file.json | sort -u
# Providers covered by a universal framework
jq '[.requirements[].checks | keys[]] | unique' file.json
# Spot inconsistent grouping values (UI tree branches)
jq '[.Requirements[].Attributes[0].Section] | unique' file.json
jq '[.Requirements[].Attributes[0].FamilyName] | unique' file.json
# Requirements with config guardrails (empty arrays are truthy in jq — check length)
jq '[.Requirements[] | select((.ConfigRequirements // []) | length > 0)] | length' file.json
# Diff requirement ids between two versions
diff <(jq -r '.Requirements[].Id' a.json | sort) <(jq -r '.Requirements[].Id' b.json | sort)
# Where is a check mapped across all frameworks?
grep -rl "my_check_name" prowler/compliance/
# Does a check exist?
find prowler/providers/aws/services -name "{check_id}.metadata.json"
# Validate one file with the universal loader
python -c "from prowler.lib.check.compliance_models import load_compliance_framework_universal as l; fw=l('prowler/compliance/aws/cis_7.0_aws.json'); print(fw.framework, len(fw.requirements))"
命令
prowler {provider} --list-compliance
prowler {provider} --compliance cis_7.0_aws
prowler aws --compliance cis_7.0_aws pci_4.0_aws
prowler aws --compliance dora_2022_2554 # universal key = file basename
prowler aws --list-compliance-requirements cis_7.0_aws
prowler aws --compliance cis_7.0_aws -M csv json html
代码索引
第 1 层 — SDK / 核心
prowler/lib/check/compliance_models.py— 旧版和通用模型树、Compliance_Requirement_ConfigConstraint、所有加载器以及 旧版→通用版适配器prowler/lib/check/compliance.py—update_checks_metadata_with_complianceprowler/lib/check/compliance_config_eval.py— 防护规则评估 (与 API 共用)prowler/lib/outputs/compliance/compliance_check.py—get_check_complianceprowler/lib/check/utils.py—list_compliance_modules
第 2 层 — JSON 目录
prowler/compliance/*.json— 通用、多云厂商(自动发现)prowler/compliance/{provider}/— 旧版、按云厂商划分(自动发现)
第 3 层 — 输出格式化器
prowler/lib/outputs/compliance/universal/—universal_table.py、universal_output.py、ocsf_compliance.pyprowler/lib/outputs/compliance/{framework}/— 旧版的各框架软件包prowler/lib/outputs/compliance/compliance.py—process_universal_compliance_frameworks、display_compliance_tableprowler/lib/outputs/compliance/compliance_output.py—ComplianceOutput基类 + CSV 编写器prowler/__main__.py— 通用处理 + 按云厂商划分的旧版编写器分支
第 4 层 — API / UI
api/src/backend/api/compliance.py—LazyComplianceTemplate、LazyChecksMapping、缓存预热api/src/backend/tasks/jobs/export.py—COMPLIANCE_CLASS_MAPapi/src/backend/tasks/jobs/scan.py—create_compliance_requirements(概览数据摄取)api/src/backend/tasks/jobs/reports/— PDF 生成器 +FRAMEWORK_REGISTRYui/lib/compliance/compliance-mapper.ts— 映射器路由 + 通用回退ui/lib/compliance/{framework}.tsx— 各框架映射器ui/components/compliance/compliance-custom-details/— 详情面板ui/types/compliance.ts— 属性元数据类型ui/components/icons/compliance/+IconCompliance.tsx— 图标(有序)
测试
tests/lib/check/universal_compliance_models_test.py— 包含针对所有已发布 JSON 的 参数化测试test_loads_as_universaltests/lib/check/compliance_check_test.py、compliance_config_eval_test.py、compliance_config_constraint_model_test.py、compliance_config_requirements_data_test.py、mitre_config_requirements_test.pytests/lib/outputs/compliance/— 各框架 + 通用 + 分发器 + 配置状态覆盖测试;共用fixtures.py
资源
- 文档(贡献者的权威信息来源):
docs/developer-guide/security-compliance-framework.mdx(两种架构、 防护措施、验证、PR 流程)、docs/user-guide/compliance/tutorials/compliance.mdx、docs/user-guide/compliance/tutorials/cross-provider-compliance.mdx - 仓库工具(
util/compliance/):CSV→JSON 生成器 (generate_json_from_csv/)、ccc/from_yaml_to_json.py、compliance_mapper/、threatscore/ - 技能资源(assets/):
sync_framework.py+configs/ccc.yaml+parsers/finos_ccc.py— 配置驱动的上游同步(工作流 A)build_inventory.py、query_checks.py、dump_section.py、audit_framework_template.py— 审计工具(工作流 B)- 旧版 JSON 模板:
cis_framework.json、ens_framework.json、iso27001_framework.json、mitre_attack_framework.json、prowler_threatscore_framework.json、generic_framework.json
- 参考资料: references/compliance-docs.md — 模型/加载器 快速参考; references/check-mapping-reference.md — 精选的要求文本 → 检查项映射表 + 诚实列出的 MANUAL 清单
- 相关技能:
prowler-compliance-review — PR
审查清单 +
validate_compliance.py(旧版架构验证器) - 编辑此技能的 frontmatter 后,运行
./skills/skill-sync/assets/sync.sh,以重新生成 AGENTS.md 自动调用 表格。