WAF-SOV-050 – Key Ownership & Management Defined
Beschreibung
For all data classes, the key ownership model MUST be explicitly defined and technically enforced: Provider-Managed Keys (PMK), Customer-Managed Keys (CMK), Bring Your Own Key (BYOK), or Hold Your Own Key (HYOK). Key rotation and deletion MUST be governed by documented procedures. All data at rest MUST be encrypted; encryption with default provider-managed keys requires explicit approval for sensitive data classes.
Begründung
| Risiko | Beschreibung |
|---|---|
Risk |
Sensitive data is exposed if storage or transport lacks strong encryption. |
Risk |
Compromised keys or weak key rotation extend the blast radius of a breach. |
Anforderungen
-
For all data classes, the key ownership model MUST be explicitly defined and technically enforced: Provider-Managed Keys (PMK), Customer-Managed Keys (CMK), Bring Your Own Key (BYOK), or Hold Your Own Key (HYOK).
-
Key rotation and deletion MUST be governed by documented procedures.
-
All data at rest MUST be encrypted; encryption with default provider-managed keys requires explicit approval for sensitive data classes.
Implementierungsleitfaden
-
Document the requirement in a version-controlled policy or standard.
-
Assign ownership and establish a review cadence (e.g., quarterly).
Reifegrade
| Level | Name | Kriterien |
|---|---|---|
L1 |
Ad hoc – control not consistently applied |
* Manual evidence exists for some workloads, but coverage is unknown. |
L2 |
Standardised – policy defined and communicated |
* A version-controlled policy, ADR, or standard describes the requirement. |
L3 |
Integrated – automated validation in CI/CD |
* Terraform checks run automatically on pull requests and report results. |
L4 |
Auditable – metrics and exceptions tracked |
* Control coverage, failures, and approved exceptions are reported quarterly. |
L5 |
Optimised – continuous improvement based on data |
* Control effectiveness is measured and iteratively improved. |
Checks
waf-sov-050.tf.aws.kms-key-rotation-enabled
Engine: terraform | Provider: aws | Automated: Ja
AWS KMS CMKs must have automatic key rotation enabled
All customer-managed KMS keys must have enable_key_rotation = true to ensure key material is automatically rotated annually, limiting the impact of key compromise.
Scope: resource — aws_kms_key
Assertions:
* enable_key_rotation is true — KMS key must have enable_key_rotation = true.
Remediation: Set enable_key_rotation = true on all aws_kms_key resources.
resource "aws_kms_key" "sovereign" {
description = "Sovereign data encryption key"
enable_key_rotation = true
deletion_window_in_days = 30
policy = data.aws_iam_policy_document.kms_policy.json
}
resource "aws_kms_key" "data" {
description = "Data key"
# enable_key_rotation defaults to false
}
waf-sov-050.tf.aws.kms-key-deletion-window
Engine: terraform | Provider: aws | Automated: Ja
KMS key deletion window must be explicitly set (>= 14 days)
KMS keys must have deletion_window_in_days explicitly set to at least 14 days to prevent accidental key destruction and allow time for review and cancellation.
Scope: resource — aws_kms_key
Assertions:
* deletion_window_in_days attribute exists — KMS key is missing explicit deletion_window_in_days.
* deletion_window_in_days greater than or equal 14 — KMS key deletion_window_in_days must be >= 14 days.
Remediation: Set deletion_window_in_days >= 14 on all KMS keys.
resource "aws_kms_key" "sovereign" {
deletion_window_in_days = 30
}
resource "aws_kms_key" "sovereign" {
deletion_window_in_days = 7 # Too short for safe review
}
waf-sov-050.tf.aws.s3-bucket-kms-encryption
Engine: terraform | Provider: aws | Automated: Ja
S3 buckets must use KMS (CMK) encryption, not AES256
S3 buckets containing sovereign data must use aws:kms encryption with a customer-managed key, not the default AES256 (SSE-S3) which uses provider-managed keys.
Scope: resource — aws_s3_bucket_server_side_encryption_configuration
Assertions:
* rule.apply_server_side_encryption_by_default.sse_algorithm equals aws:kms — S3 bucket must use 'aws:kms' encryption, not 'AES256' (provider-managed keys).
* rule.apply_server_side_encryption_by_default.kms_master_key_id attribute exists — S3 KMS encryption must reference a specific CMK, not the default AWS managed key.
Remediation: Set sse_algorithm = "aws:kms" and specify kms_master_key_id pointing to a CMK.
resource "aws_s3_bucket_server_side_encryption_configuration" "sovereign" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
kms_master_key_id = aws_kms_key.sovereign.arn
}
bucket_key_enabled = true
}
}
resource "aws_s3_bucket_server_side_encryption_configuration" "data" {
bucket = aws_s3_bucket.data.id
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256" # Provider-managed key – not sovereign
}
}
}
waf-sov-050.tf.aws.ebs-volume-encrypted
Engine: terraform | Provider: aws | Automated: Ja
EBS volumes must be encrypted
All EBS volumes must have encrypted = true. This should reference a CMK for sovereign workloads rather than using the default AWS managed key.
Scope: resource — aws_ebs_volume, aws_instance
Assertions:
* encrypted is true — EBS volume must have encrypted = true.
Remediation: Set encrypted = true and optionally kms_key_id = <cmk_arn> on EBS volumes.
resource "aws_ebs_volume" "data" {
availability_zone = "eu-central-1a"
size = 100
encrypted = true
kms_key_id = aws_kms_key.sovereign.arn
}
resource "aws_ebs_volume" "data" {
availability_zone = "eu-central-1a"
size = 100
# encrypted defaults to false
}
waf-sov-050.tf.aws.rds-storage-encrypted
Engine: terraform | Provider: aws | Automated: Ja
RDS instances must have storage encryption enabled
All RDS instances and Aurora clusters must have storage_encrypted = true. KMS key ID should reference a CMK for sovereign workloads.
Scope: resource — aws_db_instance, aws_rds_cluster
Assertions:
* storage_encrypted is true — RDS storage_encrypted must be true.
Remediation: Set storage_encrypted = true and optionally kms_key_id on all RDS resources.
resource "aws_db_instance" "sovereign" {
storage_encrypted = true
kms_key_id = aws_kms_key.rds.arn
}
resource "aws_db_instance" "db" {
# storage_encrypted defaults to false
}
waf-sov-050.tf.azurerm.key-vault-soft-delete
Engine: terraform | Provider: azurerm | Automated: Ja
Azure Key Vault must have soft delete and purge protection enabled
Azure Key Vaults used for CMK storage must have soft_delete_retention_days >= 7 and purge_protection_enabled = true to prevent accidental key destruction.
Scope: resource — azurerm_key_vault
Assertions:
* purge_protection_enabled is true — Azure Key Vault must have purge_protection_enabled = true.
* soft_delete_retention_days greater than or equal 14 — Key Vault soft_delete_retention_days must be >= 14.
Remediation: Enable purge_protection_enabled = true and set soft_delete_retention_days >= 14.
resource "azurerm_key_vault" "sovereign" {
name = "kv-sovereign-prod"
location = var.azure_location
resource_group_name = azurerm_resource_group.main.name
sku_name = "premium"
soft_delete_retention_days = 90
purge_protection_enabled = true
}
resource "azurerm_key_vault" "kv" {
name = "kv-prod"
sku_name = "standard"
# purge_protection_enabled defaults to false
}
waf-sov-050.tf.stackit.key-rotation-enabled
Engine: terraform | Provider: stackit | Automated: Ja
StackIT secret manager keys must have automatic rotation enabled
StackIT Secret Manager secrets must have rotation policies configured. Automatic key rotation limits the impact of key compromise.
Scope: resource — stackit_secret_manager
Assertions:
* rotation.enabled is true — StackIT Secret Manager must have rotation.enabled = true.
Remediation: Configure rotation policies on all StackIT Secret Manager resources with enable_key_rotation = true.
resource "stackit_secret_manager" "sovereign" {
project_id = stackit_project.main.id
name = "sovereign-secrets"
rotation {
enabled = true
interval_days = 90
}
}
resource "stackit_secret_manager" "secrets" {
project_id = stackit_project.main.id
name = "secrets"
# No rotation configured
}
waf-sov-050.tf.ovh.key-rotation-enabled
Engine: terraform | Provider: ovh | Automated: Ja
OVH secret manager keys must have rotation configured
OVH secret manager secrets must have rotation policies configured for sovereign compliance.
Scope: resource — ovh_secret_manager_secret
Assertions:
* rotation block exists — OVH secret manager must have rotation policy configured.
Remediation: Configure rotation policies on all OVH secret manager resources.
# OVH secret manager with rotation enabled
# No rotation policy configured
waf-sov-050.tf.hcloud.key-rotation-enabled
Engine: terraform | Provider: hcloud | Automated: Ja
Hetzner Cloud secret store keys must have rotation configured
Hetzner Cloud secret manager must have rotation policies configured for sovereign compliance.
Scope: resource — hcloud_server
Assertions:
* labels key exists — Hetzner Cloud secrets must have rotation policy configured (add rotation-enabled label).
Remediation: Configure rotation policies on all Hetzner Cloud secret resources.
# Hetzner Cloud secret store with rotation enabled
# No rotation policy configured
waf-sov-050.tf.google.kms-key-location-and-rotation
Engine: terraform | Provider: google | Automated: Ja
GCP KMS keys must be in approved sovereign locations with rotation enabled
GCP Cloud KMS key rings and crypto keys used for sovereign data must be located in approved regions and have rotation periods configured. Customer-managed keys must be used for sensitive data classes.
Scope: resource — google_kms_crypto_key
Assertions:
* key_ring matches pattern europe-(west3|west1|north1|central2) — KMS crypto key must belong to a key ring in an approved sovereign location.
* rotation_period attribute exists — KMS crypto key must have a rotation_period configured.
Remediation: Create google_kms_key_ring in an approved sovereign location, set google_kms_crypto_key.rotation_period to at most 7776000 seconds (90 days), and use customer-managed keys for storage and database resources.
resource "google_kms_key_ring" "sovereign" {
name = "sovereign-keyring"
location = "europe-west3"
}
resource "google_kms_crypto_key" "data" {
name = "data-encryption-key"
key_ring = google_kms_key_ring.sovereign.id
rotation_period = "7776000s"
}
resource "google_kms_key_ring" "sovereign" {
name = "sovereign-keyring"
location = "us-central1"
}
resource "google_kms_crypto_key" "data" {
name = "data-encryption-key"
key_ring = google_kms_key_ring.sovereign.id
# rotation_period not set
}
Evidenz
| Art | Erforderlich | Beschreibung |
|---|---|---|
|
Erforderlich |
Terraform configuration implementing the control. |
|
Erforderlich |
Policy, ADR, or standard documenting the requirement. |
|
Optional |
Cloud console or API output confirming runtime state. |
Verwandte Controls
-
WAF-COST-040 == Regulatorisches Mapping
| Framework | Controls |
|---|---|
GDPR |
* Art. 32 – Security of processing (encryption as a technical measure) * Art. 17 – Right to erasure (cryptographic erasure via key deletion) |
BSI C5:2020 |
* CRY-01 – Cryptography policy * CRY-02 – Key management |
BSI C3A:2026 |
* Dimension 4 – Data: Key ownership model (CMK/BYOK/HYOK) * Dimension 4 – Data: External key management * Dimension 4 – Data: Client-side encryption |
EUCS (ENISA) |
* CRY-01 – Encryption at rest * CRY-03 – Key management * SOV-03 – Customer key control |
ISO 27001:2022 |
* A.8.24 – Use of cryptography * A.8.25 – Secure development life cycle |
GAIA-X |
* Sovereign Cloud – Cryptographic self-determination |