WAF++ WAF++
Back to WAF++ Homepage

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

ID-Schema

WAF - \{PILLAR} - \{NNN}
 │       │         │
 │       │         └── Dreistellige Nummer (010, 020, ..., 100)
 │       └──────────── Pillar-Kürzel (SOV, COST, SEC, REL, OPS, PERF, SUS)
 └──────────────────── Präfix: Well Architected Framework

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

critical

Unmittelbares Sicherheits- oder Compliance-Risiko. Kein Deploy ohne Remediation.

high

Erhebliches Risiko. Kurzfristige Remediation erforderlich (max. 2 Wochen).

medium

Verbesserungsbedarf. Mittelfristig adressieren (nächstes Quartal).

low

Best-Practice-Abweichung. Opportunistisch beheben.

type

Ein Control kann mehrere Typen haben:

Wert Bedeutung

governance

Organisatorische Anforderung (Policies, Prozesse, Dokumentation)

configuration

Technische Konfiguration in IaC oder Cloud-Diensten

automation

Erfordert automatisierte Prüfung oder Durchsetzung

process

Wiederkehrender Prozess (z.B. monatlicher Review)

architecture

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

governance

Policy-Dokumente, ADRs, Entscheidungsregister (versioniert in Git)

iac

Terraform-Konfiguration, Helm-Charts, Kustomize-Manifeste

architecture

Architekturdiagramme, Datenfluss-Diagramme, Netzwerktopologien

process

Meeting-Protokolle, Review-Berichte, Audit-Logs, Kalendereinträge

config

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

terraform

Check wird gegen HCL2-Terraform-Dateien ausgeführt (wafpass)

manual

Manueller Review erforderlich; automated: false ist immer gesetzt

api

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

resource

resource_types: [list]

Terraform resource-Blöcke des angegebenen Typs (z.B. aws_s3_bucket)

provider

provider_name: string

Terraform provider-Blöcke (z.B. provider "aws" {})

variable

Alle variable-Blöcke in der Konfiguration

terraform

Der terraform-Block (required_providers, required_version)

module

Alle module-Blöcke


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

attribute

Ja

Attributpfad im Terraform-Block. Dot-notation für verschachtelte Werte: tags.cost-center, logging_config.bucket.

op

Ja

Operator (siehe Tabelle unten).

key

Nur bei key_exists

Schlüsselname innerhalb einer Map (z.B. Tag-Key).

expected

Operator-abhängig

Erwarteter Wert. Bei in/not_in eine Liste. Bei greater_than_or_equal/less_than_or_equal eine Zahl.

pattern

Nur bei matches/not_matches

Regulärer Ausdruck (Python re-Syntax).

fallback_attribute

Nur bei attribute_exists_or_fallback

Alternatives Attribut, das geprüft wird, wenn das primäre fehlt.

message

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

attribute_exists

attribute

Attribut vorhanden und nicht null

attribute_exists_or_fallback

attribute, fallback_attribute

Primär- oder Fallback-Attribut vorhanden

not_empty

attribute

Attribut vorhanden, nicht null, nicht "" / [] / {}

equals

attribute, expected

Attributwert == expected

not_equals

attribute, expected

Attributwert != expected

in

attribute, expected (Liste)

Attributwert ist in der erlaubten Liste

not_in

attribute, expected (Liste)

Attributwert ist nicht in der verbotenen Liste

is_true

attribute

Attributwert ist true (auch als String)

is_false

attribute

Attributwert ist false (auch als String)

greater_than_or_equal

attribute, expected (Zahl)

Numerischer Attributwert >= expected

less_than_or_equal

attribute, expected (Zahl)

Numerischer Attributwert ⇐ expected

matches

attribute, pattern

Attributwert entspricht dem Regex-Pattern

not_matches

attribute, pattern

Attributwert entspricht dem Regex-Pattern nicht

key_exists

attribute, key

Schlüssel key existiert in der Map attribute (z.B. in tags)

block_exists

Terraform-Block des angegebenen Typs existiert (Scope-Match genügt)

has_associated_resource

attribute

Eine andere Ressource referenziert diesen Block (z.B. Flow Log referenziert VPC)

not_contains

attribute, expected

Attributwert enthält den Substring expected nicht


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

  1. ID vergeben – nächste freie Nummer im Pillar (z.B. WAF-COST-110); Nummern werden nicht wiederverwendet.

  2. YAML erstellen – Datei nach obigem Schema anlegen, alle Pflichtfelder befüllen.

  3. Automated Checks validieren – lokal testen:

    wafpass check ./tests/fixtures/ --controls WAF-COST-110
  4. Narrative-Seite erstellen – passende .adoc-Datei im Pillar-Modul anlegen und in references.narrative verlinken.

  5. Pull Request öffnen – Control-YAML + Narrative-Seite gemeinsam einreichen. Der PR-Titel sollte die Control-ID enthalten.


Weiterführende Seiten