Control-Schema Referenz
WAF++ Controls sind maschinenlesbare YAML-Dateien. Sie definieren, was geprüft wird, wie geprüft wird, und welche Evidenz erwartet wird. Diese Seite dokumentiert die vollständige Schema-Struktur für Control-Autoren und Contributors.
Dateikonventionen
-
Ablageort:
modules/controls/controls/ -
Dateiname:
WAF-{PILLAR}-{NNN}.yml(z.B.WAF-SOV-010.yml,WAF-COST-040.yml) -
Encoding: UTF-8
-
Sprache: Englisch (Control-Dateien), unabhängig von der Sprache der Narrative-Seiten
Top-Level Felder
id: # string – eindeutige Control-ID (WAF-SOV-010)
title: # string – kurzer, aktiver Titel ("Data Residency Policy Defined")
pillar: # string – Pillar-Name (sovereign | cost | security | reliability | operations | architecture | governance)
status: # string – active | deprecated | draft
severity: # string – critical | high | medium | low
category: # string – Kategorisierung innerhalb des Pillars (z.B. "data-residency", "cost-allocation")
type: # list – [governance, configuration, automation, process, architecture]
tags: # list – freie Tags für Suche und Filterung
description: # > – Was dieses Control fordert (normativ, z.B. "MUST carry tags")
rationale: # > – Warum dieses Control existiert (Risikobegründung)
threat: # list – Konkrete Bedrohungen bei Nicht-Einhaltung
regulatory_mapping: # list – Zuordnung zu Compliance-Rahmenwerken (siehe unten)
implementation_guidance: # list – Konkrete Umsetzungsschritte (Checkliste)
maturity_levels: # map – 5 Reifegradebenen (level_1 bis level_5)
evidence: # map – required + optional Evidenzarten
checks: # list – Automatisierte und manuelle Prüfschritte (siehe unten)
references: # map – Links zu Narrative-Seiten und verwandten Controls
severity
| Wert | Bedeutung |
|---|---|
|
Unmittelbares Sicherheits- oder Compliance-Risiko. Kein Deploy ohne Remediation. |
|
Erhebliches Risiko. Kurzfristige Remediation erforderlich (max. 2 Wochen). |
|
Verbesserungsbedarf. Mittelfristig adressieren (nächstes Quartal). |
|
Best-Practice-Abweichung. Opportunistisch beheben. |
type
Ein Control kann mehrere Typen haben:
| Wert | Bedeutung |
|---|---|
|
Organisatorische Anforderung (Policies, Prozesse, Dokumentation) |
|
Technische Konfiguration in IaC oder Cloud-Diensten |
|
Erfordert automatisierte Prüfung oder Durchsetzung |
|
Wiederkehrender Prozess (z.B. monatlicher Review) |
|
Architekturentscheidung auf System- oder Plattformebene |
regulatory_mapping
Ordnet das Control einem oder mehreren Compliance-Rahmenwerken zu.
regulatory_mapping:
- framework: "GDPR"
controls:
- "Art. 44 – General principle for transfers"
- "Art. 46 – Transfers subject to appropriate safeguards"
- framework: "BSI C5:2020"
controls:
- "OPS-04 – Data management"
- framework: "ISO 27001:2022"
controls:
- "A.5.12 – Classification of information"
- framework: "EUCS (ENISA)"
controls:
- "DSP-01 – Data classification"
- framework: "GAIA-X"
controls:
- "Sovereign Cloud – Data location requirements"
Unterstützte Rahmenwerke: GDPR, BSI C5:2020, ISO 27001:2022, EUCS (ENISA), GAIA-X, FinOps Foundation, ISO 20000, Internal Governance.
maturity_levels
Fünf Reifegradebenen mit Beschreibung und messbaren Kriterien.
maturity_levels:
level_1:
description: "Ad hoc – keine strukturierten Controls"
criteria:
- "Erste messbare Bedingung auf Level 1"
level_2:
description: "Standardisiert – manuell umgesetzt"
criteria:
- "..."
level_3:
description: "Integriert – automatisiert und in CI geprüft"
criteria:
- "..."
level_4:
description: "Souverän – vollständig auditierbar"
criteria:
- "..."
level_5:
description: "Optimiert – kontinuierliche Verbesserung"
criteria:
- "..."
Jedes Level baut auf dem vorherigen auf. Level 3+ erfordern in der Regel automatisierte Prüfung (wafpass oder äquivalent).
evidence
Definiert die Evidenzarten, die bei einem Audit erwartet werden.
evidence:
required:
- kind: "governance"
description: "Policy-Dokument, version-controlled."
- kind: "iac"
description: "Terraform-Konfiguration, die die Anforderung umsetzt."
optional:
- kind: "architecture"
description: "Architekturdiagramm mit Datenflüssen."
- kind: "process"
description: "Protokoll des letzten Reviews."
- kind: "config"
description: "Export aus Cloud-Konsole oder Inventory-Tool."
Erlaubte kind-Werte
| kind | Typische Evidenz |
|---|---|
|
Policy-Dokumente, ADRs, Entscheidungsregister (versioniert in Git) |
|
Terraform-Konfiguration, Helm-Charts, Kustomize-Manifeste |
|
Architekturdiagramme, Datenfluss-Diagramme, Netzwerktopologien |
|
Meeting-Protokolle, Review-Berichte, Audit-Logs, Kalendereinträge |
|
Cloud-Konsolen-Screenshots, CLI-Outputs, Inventory-Exports, API-Responses |
checks
Eine Liste von Prüfschritten.
Jeder Check ist entweder automatisiert (ausführbar durch wafpass) oder manuell.
checks:
- id: "waf-sov-010.tf.aws.provider-region-explicit" # eindeutige Check-ID
engine: "terraform" # terraform | manual | api
provider: "aws" # aws | azurerm | google | any
automated: true # true | false
severity: "critical" # critical | high | medium | low
title: "AWS provider must have 'region' explicitly set"
description: >
Kurze Beschreibung, was dieser Check prüft und warum.
scope:
block_type: "provider" # resource | provider | variable | terraform | module
provider_name: "aws" # nur bei block_type: provider
resource_types: # nur bei block_type: resource
- "aws_s3_bucket"
assertions:
- attribute: "region"
op: "attribute_exists"
message: "AWS provider block is missing explicit 'region' attribute."
on_fail: "violation"
remediation: >
Set 'region' explicitly in all AWS provider blocks.
example:
compliant: |
provider "aws" {
region = var.aws_region
}
non_compliant: |
provider "aws" {
# No region set
}
id-Konvention für Checks
{control-id}.{engine}.{provider}.{kurzbeschreibung}
│ │ │ │
│ │ │ └── Kebab-case, max 40 Zeichen
│ │ └─────────────── aws | azurerm | google | any | manual
│ └──────────────────────── terraform | manual | api
└──────────────────────────────────── z.B. waf-sov-010 (lowercase)
Beispiel: waf-cost-010.tf.aws.compute-mandatory-tags
engine
| Wert | Bedeutung |
|---|---|
|
Check wird gegen HCL2-Terraform-Dateien ausgeführt (wafpass) |
|
Manueller Review erforderlich; |
|
Prüfung erfordert Live-Abfrage der Cloud-API (wafpass unterstützt dies noch nicht) |
scope
Definiert, welche Terraform-Blöcke geprüft werden:
| block_type | Zusatzfelder | Beschreibung |
|---|---|---|
|
|
Terraform |
|
|
Terraform |
|
– |
Alle |
|
– |
Der |
|
– |
Alle |
assertions
Jede Assertion definiert eine einzelne Bedingung, die ein Terraform-Block erfüllen muss. Alle Assertions eines Checks müssen bestehen, damit der Check als PASS gilt.
assertions:
- attribute: "tags" # Attributpfad (dot-notation für verschachtelte Werte)
op: "key_exists" # Operator (siehe Tabelle unten)
key: "cost-center" # für key_exists
expected: "COST" # für equals, not_equals, in, not_in, greater_than_or_equal, less_than_or_equal
pattern: "^eu-" # für matches, not_matches (Regex)
fallback_attribute: "region" # für attribute_exists_or_fallback
message: "Resource is missing the mandatory 'cost-center' tag."
Assertion-Felder
| Feld | Pflicht | Beschreibung |
|---|---|---|
|
Ja |
Attributpfad im Terraform-Block. Dot-notation für verschachtelte Werte: |
|
Ja |
Operator (siehe Tabelle unten). |
|
Nur bei |
Schlüsselname innerhalb einer Map (z.B. Tag-Key). |
|
Operator-abhängig |
Erwarteter Wert. Bei |
|
Nur bei |
Regulärer Ausdruck (Python re-Syntax). |
|
Nur bei |
Alternatives Attribut, das geprüft wird, wenn das primäre fehlt. |
|
Nein |
Fehlermeldung bei FAIL. Wird im wafpass-Output angezeigt. Wenn weggelassen, generiert die Engine eine Standard-Meldung. |
Operator-Referenz
| Operator | Benötigte Felder | Prüft |
|---|---|---|
|
|
Attribut vorhanden und nicht |
|
|
Primär- oder Fallback-Attribut vorhanden |
|
|
Attribut vorhanden, nicht |
|
|
Attributwert == |
|
|
Attributwert != |
|
|
Attributwert ist in der erlaubten Liste |
|
|
Attributwert ist nicht in der verbotenen Liste |
|
|
Attributwert ist |
|
|
Attributwert ist |
|
|
Numerischer Attributwert >= |
|
|
Numerischer Attributwert ⇐ |
|
|
Attributwert entspricht dem Regex-Pattern |
|
|
Attributwert entspricht dem Regex-Pattern nicht |
|
|
Schlüssel |
|
– |
Terraform-Block des angegebenen Typs existiert (Scope-Match genügt) |
|
|
Eine andere Ressource referenziert diesen Block (z.B. Flow Log referenziert VPC) |
|
|
Attributwert enthält den Substring |
references
Verknüpft das Control mit der Narrative-Dokumentation.
references:
narrative: "modules/pillar-sovereign/pages/controls.adoc#WAF-SOV-010"
best_practice: "modules/pillar-sovereign/pages/best-practices/bp-data-residency.adoc"
related_controls:
- "WAF-SOV-020"
- "WAF-SOV-030"
Vollständiges Beispiel-Control
Das folgende Beispiel zeigt ein minimal-vollständiges Control, das alle Pflichtfelder enthält und direkt von wafpass ausgewertet werden kann:
id: WAF-COST-010
title: "Cost Allocation Tagging Enforced"
pillar: "cost"
status: "active"
severity: "high"
category: "cost-allocation"
type: ['governance', 'configuration']
tags: ['tagging', 'cost-allocation', 'finops']
description: >
All cloud resources MUST carry mandatory cost allocation tags:
cost-center, owner, environment, and workload.
rationale: >
Without consistent tagging, cloud costs cannot be allocated to workloads or teams.
Manual tagging is unreliable; IaC-enforced tags are the only sustainable approach.
threat:
- "Unallocated cloud spend making workload cost ownership impossible"
- "Budget overruns not attributable to specific teams"
regulatory_mapping:
- framework: "FinOps Foundation"
controls:
- "Inform Phase – Cost Allocation and Showback"
implementation_guidance:
- "Define a mandatory tag taxonomy: cost-center, owner, environment, workload."
- "Use a shared Terraform module to output the complete tag map."
- "Enforce tagging in CI/CD with wafpass --fail-on critical."
maturity_levels:
level_1:
description: "Ad-hoc tagging, no standard taxonomy"
criteria:
- "Some resources are tagged but no consistent taxonomy exists"
level_2:
description: "Taxonomy documented, manual tagging"
criteria:
- "Mandatory tag taxonomy is documented and version-controlled"
level_3:
description: "IaC-enforced with CI gate"
criteria:
- "Shared mandatory-tags module is used by all IaC deployments"
- "CI pipeline checks tag compliance on every PR"
level_4:
description: "Automated remediation and chargeback"
criteria:
- "Automated remediation tags untagged resources within 24 hours"
level_5:
description: "Full cost allocation with automated attribution"
criteria:
- "100% cost allocation to workloads and teams"
evidence:
required:
- kind: "governance"
description: "Tag taxonomy document (version-controlled)."
- kind: "iac"
description: "Shared mandatory-tags Terraform module."
optional:
- kind: "process"
description: "Monthly tagging compliance report."
checks:
- id: "waf-cost-010.tf.aws.compute-mandatory-tags"
engine: "terraform"
provider: "aws"
automated: true
severity: "high"
title: "AWS resources must have all mandatory cost allocation tags"
description: >
Compute and data resources must carry cost-center, owner, environment, and workload tags.
scope:
block_type: "resource"
resource_types:
- "aws_instance"
- "aws_s3_bucket"
- "aws_lambda_function"
assertions:
- attribute: "tags"
op: "key_exists"
key: "cost-center"
message: "Resource is missing the mandatory 'cost-center' tag."
- attribute: "tags"
op: "key_exists"
key: "owner"
message: "Resource is missing the mandatory 'owner' tag."
- attribute: "tags"
op: "key_exists"
key: "environment"
message: "Resource is missing the mandatory 'environment' tag."
- attribute: "tags"
op: "key_exists"
key: "workload"
message: "Resource is missing the mandatory 'workload' tag."
on_fail: "violation"
remediation: >
Use the shared mandatory-tags module. Set tags = module.tags.tags on every resource.
example:
compliant: |
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
tags = {
cost-center = "fintech-platform"
owner = "payments-team"
environment = "production"
workload = "payment-service"
}
}
non_compliant: |
resource "aws_instance" "app" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.medium"
tags = {
Name = "payment-app"
# Missing: cost-center, owner, environment, workload
}
}
references:
narrative: "modules/pillar-cost/pages/controls.adoc#WAF-COST-010"
best_practice: "modules/pillar-cost/pages/best-practices/bp-tagging.adoc"
related_controls:
- "WAF-COST-020"
- "WAF-COST-030"
Neues Control einreichen
-
ID vergeben – nächste freie Nummer im Pillar (z.B.
WAF-COST-110); Nummern werden nicht wiederverwendet. -
YAML erstellen – Datei nach obigem Schema anlegen, alle Pflichtfelder befüllen.
-
Automated Checks validieren – lokal testen:
wafpass check ./tests/fixtures/ --controls WAF-COST-110 -
Narrative-Seite erstellen – passende
.adoc-Datei im Pillar-Modul anlegen und inreferences.narrativeverlinken. -
Pull Request öffnen – Control-YAML + Narrative-Seite gemeinsam einreichen. Der PR-Titel sollte die Control-ID enthalten.
Weiterführende Seiten
-
WAF++ PASS – CLI Referenz – wie Controls ausgeführt werden
-
Controls-Katalog – alle vorhandenen Controls
-
Assessment-Methodik – Controls im Assessment-Kontext