WAF-SOV-010 – Data Residency Policy Defined
Beschreibung
A documented data-residency policy MUST exist that explicitly defines allowed regions, data classifications, and storage rules for all data types: primary data, replicas, backups, logs, traces, metrics, and metadata. The policy MUST be version-controlled and technically reflected in IaC defaults and variable validation.
Begründung
| Risiko | Beschreibung |
|---|---|
Risk |
Data may leave approved jurisdictions and violate regulatory requirements. |
Risk |
Vendor lock-in reduces future portability and sovereignty options. |
Anforderungen
-
A documented data-residency policy MUST exist that explicitly defines allowed regions, data classifications, and storage rules for all data types: primary data, replicas, backups, logs, traces, metrics, and metadata.
-
The policy MUST be version-controlled and technically reflected in IaC defaults and variable validation.
Implementierungsleitfaden
-
Document the requirement in a version-controlled policy or standard.
-
Assign ownership and establish a review cadence (e.g., quarterly).
-
Implement the required configuration as code in Terraform or equivalent IaC.
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-010.tf.any.resource-tag-data-residency
Engine: terraform | Provider: any | Automated: Ja
Data resources must carry 'data-residency' tag
Primary data resources (object storage, relational DB, NoSQL, data warehouses) must be tagged with 'data-residency' to indicate the jurisdiction constraint for that resource.
Scope: resource — aws_s3_bucket, aws_rds_instance, aws_rds_cluster, aws_dynamodb_table, aws_elasticache_cluster, aws_elasticsearch_domain, aws_opensearch_domain, azurerm_storage_account, azurerm_sql_database, azurerm_cosmosdb_account, google_storage_bucket, google_sql_database_instance, google_bigtable_instance, stackit_container_registry, stackit_mysql_instance, stackit_opensearch_instance, stackit_redis_instance, stackit_secret_manager, ovh_cloud_project, ovh_vps, ovh_dedicated_server, ovh_ip_loadbalancing, hcloud_server, hcloud_volume, hcloud_network, hcloud_load_balancer, hcloud_dns_record
Assertions:
* tags key exists — Resource is missing the 'data-residency' tag required by sovereignty policy.
* tags key exists — Resource is missing the 'data-class' tag required by data classification policy.
Remediation: Add 'data-residency' and 'data-class' tags to all data-storing resources. Acceptable values for 'data-residency': eu-only, de-only, ch-only, at-only, global-approved. Acceptable values for 'data-class': pii, health, financial, operational, public, restricted.
# AWS
resource "aws_s3_bucket" "customer_data" {
bucket = "acme-customer-data-prod"
tags = {
data-class = "pii"
data-residency = "eu-only"
environment = "production"
owner = "platform-team"
}
}
# Azure
resource "azurerm_storage_account" "customer_data" {
name = "acmestorage"
resource_group_name = azurerm_resource_group.main.name
location = "germanywestcentral"
tags = {
data-class = "pii"
data-residency = "eu-only"
environment = "production"
owner = "platform-team"
}
}
# GCP
resource "google_storage_bucket" "customer_data" {
name = "acme-customer-data-prod"
location = "europe-west3"
labels = {
data-class = "pii"
data-residency = "eu-only"
environment = "production"
owner = "platform-team"
}
}
# StackIT (SchwarzIT)
resource "stackit_container_registry" "customer_data" {
project_id = stackit_project.main.id
name = "acme-registry"
labels = {
data-class = "pii"
data-residency = "eu-only"
}
}
# OVH
resource "ovh_cloud_project" "customer_data" {
description = "Sovereign workload"
tags = ["data-residency=eu-only", "data-class=pii"]
}
# Hetzner Cloud
resource "hcloud_server" "customer_data" {
name = "sovereign-server"
server_type = "cx22"
location = "fsn1"
labels = {
data-class = "pii"
data-residency = "eu-only"
}
}
resource "aws_s3_bucket" "customer_data" {
bucket = "acme-customer-data-prod"
# Missing data-residency and data-class tags
tags = {
environment = "production"
}
}
waf-sov-010.tf.aws.provider-region-explicit
Engine: terraform | Provider: aws | Automated: Ja
AWS provider must have 'region' explicitly set
AWS provider blocks must have an explicit 'region' attribute set to prevent unintended deployments to non-sovereign regions via environment variable fallback.
Scope: provider — aws
Assertions:
* region attribute exists — AWS provider block is missing explicit 'region' attribute.
* region not empty — AWS provider 'region' must not be empty.
Remediation: Set 'region' explicitly in all AWS provider blocks. Use a variable with a validation block to restrict to approved regions.
variable "aws_region" {
type = string
default = "eu-central-1"
validation {
condition = contains(["eu-central-1", "eu-west-1"], var.aws_region)
error_message = "Region must be in approved sovereign EU list."
}
}
provider "aws" {
region = var.aws_region
}
provider "aws" {
# No region set – defaults to AWS_DEFAULT_REGION env var
}
waf-sov-010.tf.azurerm.location-explicit
Engine: terraform | Provider: azurerm | Automated: Ja
Azure resource groups must have 'location' explicitly set
Azure resource groups (and key resources) must have an explicit 'location' attribute rather than inheriting from parent or relying on environment defaults.
Scope: resource — azurerm_resource_group, azurerm_storage_account, azurerm_sql_server, azurerm_kubernetes_cluster
Assertions:
* location attribute exists — Azure resource is missing explicit 'location' attribute.
* location not empty — Azure resource 'location' must not be empty.
Remediation: Set 'location' explicitly on all Azure resources. Use a variable with a validation block to restrict to approved Azure regions.
variable "azure_location" {
type = string
default = "germanywestcentral"
validation {
condition = contains(["germanywestcentral", "westeurope", "northeurope"], var.azure_location)
error_message = "Location must be an approved sovereign Azure region."
}
}
resource "azurerm_resource_group" "main" {
name = "rg-sovereign-prod"
location = var.azure_location
}
resource "azurerm_resource_group" "main" {
name = "rg-sovereign-prod"
# No location set
}
waf-sov-010.tf.google.region-explicit
Engine: terraform | Provider: google | Automated: Ja
GCP resources must have 'region' or 'location' explicitly set
GCP resources must have 'region' or 'location' explicitly set to prevent unintended deployment to non-sovereign regions via provider-level defaults.
Scope: resource — google_storage_bucket, google_sql_database_instance, google_compute_instance, google_container_cluster, google_bigquery_dataset
Assertions:
* location attribute exists or fallback (fallback region) — GCP resource is missing explicit 'region' or 'location' attribute.
Remediation: Set 'location' or 'region' explicitly on all GCP data resources. Use a variable with validation to restrict to approved GCP regions.
variable "gcp_region" {
type = string
default = "europe-west3"
validation {
condition = startswith(var.gcp_region, "europe-")
error_message = "Only European GCP regions are approved for sovereign workloads."
}
}
resource "google_storage_bucket" "data" {
name = "acme-sovereign-data"
location = var.gcp_region
}
resource "google_storage_bucket" "data" {
name = "acme-sovereign-data"
# No location set – defaults to provider default
}
waf-sov-010.tf.stackit.region-explicit
Engine: terraform | Provider: stackit | Automated: Ja
STACKIT resources must have an explicit region
STACKIT resources must have an explicit region. This check validates the Terraform configuration uses the expected resource and attribute.
Scope: resource — stackit_project, stackit_server, stackit_ske_cluster, stackit_object_storage_bucket
Assertions:
* region attribute exists — STACKIT resource must have an explicit region.
Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.
# Example resource meets the requirement.
resource "stackit_project" "example" {
# required attribute/tag/label present
}
# Example resource does not meet the requirement.
resource "stackit_project" "example" {
# Missing required attribute/tag/label
}
waf-sov-010.config.ovh.data-residency-policy
Engine: config | Provider: ovh | Automated: Ja
OVHcloud data-residency policy must be documented
OVHcloud public-cloud resources do not expose a native region attribute consistently across all resource types. A version-controlled policy document must therefore define the approved OVHcloud regions, data classifications, and implementation rules for sovereign workloads.
Scope: file — docs/sovereign/waf-sov-010-ovh-data-residency.md
Assertions:
* content matches pattern (?i)MUST|SHALL|required|mandatory|documented|approved — OVHcloud data-residency policy file must contain a normative requirement statement.
Remediation: Create or update docs/sovereign/waf-sov-010-ovh-data-residency.md. State the approved OVHcloud regions, data-class handling, review cadence, and owner.
docs/sovereign/waf-sov-010-ovh-data-residency.md:
- Approved OVHcloud regions are documented (e.g. DE-FRA, DE-EDE, EU-CY).
- Data-class and data-residency handling for OVHcloud is defined.
- Owner and review cadence are recorded.
# `docs/sovereign/waf-sov-010-ovh-data-residency.md` is missing
# WAF-SOV-010 violation: OVHcloud data-residency policy is not documented
waf-sov-010.tf.hcloud.location-explicit
Engine: terraform | Provider: hcloud | Automated: Ja
Hetzner Cloud resources must have an explicit location
Hetzner Cloud resources must have an explicit location. This check validates the Terraform configuration uses the expected resource and attribute.
Scope: resource — hcloud_server, hcloud_volume, hcloud_network, hcloud_load_balancer
Assertions:
* location attribute exists — Hetzner Cloud resource must have an explicit location.
Remediation: Review the Terraform configuration for the listed resource types and ensure the required attribute or tag is present. See the control narrative for provider-specific guidance.
# Example resource meets the requirement.
resource "hcloud_server" "example" {
# required attribute/tag/label present
}
# Example resource does not meet the requirement.
resource "hcloud_server" "example" {
# Missing required attribute/tag/label
}
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-SEC-030 == Regulatorisches Mapping
| Framework | Controls |
|---|---|
ISO 27001:2022 |
* A.5.12 – Classification of information * A.5.33 – Protection of records * A.8.10 – Information deletion * A.5.34 – Privacy and PII protection |
ISO 27017 |
* CLD.6.3 – Shared roles and responsibilities for cloud * CLD.8.1 – Asset management for cloud customer data |
ISO 27018 |
* A.1 – Consent and choice for PII * A.11 – Information transfer and disclosure of PII |
GDPR |
* Art. 30 – Records of processing activities * Art. 44 – General principle for transfers * Art. 46 – Transfers subject to appropriate safeguards * Art. 5(1)(a) – Lawfulness, fairness and transparency |
UK GDPR |
* Art. 30 – Records of processing * Art. 44-46 – International transfers |
NIS2 |
* Art. 21(2)(d) – Supply chain and data location requirements |
DORA |
* Art. 28 – ICT third-party risk management |
EUCS (ENISA) |
* DSP-01 – Data classification and handling * GEO-01 – Data geographic location |
BSI C5:2020 |
* AM-04 – Data classification and handling * PI-02 – Location of data processing |
BSI C3A:2026 |
* Dimension 4 – Data: Data residency, data classification |
ANSSI SecNumCloud |
* Domain – Data localization and sovereignty |
BIO |
* BIO – Dataclassificatie en residentie |
ENS High |
* mp.info.1 – Datos de carácter personal * mp.info.6 – Limpieza de documentos |
NIST SP 800-53 |
* RA-2 – Security Categorization * AC-21 – Information Sharing * SC-7 – Boundary Protection |
FedRAMP |
* RA-2, SC-7 (Moderate/High baseline – data location) |
MAS TRM |
* Ch.13 – Cloud computing – data location |
ISMAP |
* Data location and residency requirements |