Reference implementation. ArchRails enforces the architectural slice of this framework — this template is not itself a compliance certification, attestation, or audit outcome. Read the full disclaimer →
Attestation, not implementation. Each snippet below records a CALM-level attestation against a node, edge, or graph. The engine enforces that the attestation is present and that the agent's declared_pattern matches what you authored. It does not read your runtime code or infrastructure to verify the attestation reflects reality — verifying that algorithm: AES-256-GCM actually appears in your crypto layer is the responsibility of your runtime monitoring, infrastructure scanning, and auditor review. ArchRails enforces the contract.

Control template: GDPR Article 32 (security of processing)

Status: Stable · Version: gdpr/v1.0.0

A bundle of CALM control snippets covering the architecturally enforceable subset of GDPR Article 32 (security of processing of personal data). You copy these into your *.calm.json files on the nodes that process personal data of EU/UK data subjects.

Who GDPR applies to

Any organization that processes personal data of EU/UK data subjects, regardless of the organization's location (extraterritorial scope under Art. 3). Common categories: - EU/UK established controllers and processors - Non-EU companies offering goods/services to EU/UK residents - Non-EU companies monitoring behavior of EU/UK residents - Public-sector bodies processing personal data - Cloud providers acting as processors for EU controllers

Brexit note: UK GDPR (the onshored regime) is substantially aligned with EU GDPR; this template uses EU naming conventions but the architectural surface is the same. The Data Protection Act 2018 + UK GDPR is the UK authoritative source.

What this template covers

GDPR Art. 32 lists technical and organizational measures, including: - pseudonymisation and encryption (Art. 32(1)(a)) - ongoing confidentiality, integrity, availability, and resilience (Art. 32(1)(b)) - ability to restore data after an incident (Art. 32(1)(c)) - regular testing of measures (Art. 32(1)(d))

The architectural slice maps to ~10 controls. Plus related obligations from Art. 30 (RoPA), Art. 33 (breach notification), Art. 25 (data protection by design), and Art. 28 (processor contracts) where they have an architectural surface.

GDPR citation Architectural surface Control alias
Art. 32(1)(a) Pseudonymisation / encryption at rest gdpr-encryption-at-rest
Art. 32(1)(a) Encryption in transit gdpr-encryption-in-transit
Art. 32(1)(b) Access restriction (need-to-know) gdpr-access-restriction
Art. 17 + Art. 5(1)(e) Data retention + erasure gdpr-retention-and-erasure

4 architectural controls covering the GDPR surfaces that have implementation-shaped requirements. GDPR is heavy on process and contractual obligations (DPIA, DSAR handling, controller-processor agreements, etc.) that are NOT architectural — document those in your firm's privacy program, not your CALM.

The "personal-data-scope" pattern

A node is in GDPR scope if it processes personal data of EU/UK data subjects. Tag those nodes:

{
  "unique-id": "customer-records-service",
  "node-type": "service",
  "name": "Customer Records Service",
  "metadata": {
    "gdpr-in-scope": true,
    "data-categories": ["contact-data", "transaction-history"],
    "special-categories-processed": false,
    "data-classification": "personal-data"
  }
}

If you process special categories (Art. 9 — health, biometric, political opinion, religious belief, sex life, etc.) flip special-categories-processed: true; stricter expectations apply.

Infrastructure verification. ArchRails now verifies the following controls against your infrastructure at PR review time and during code generation (AWS): gdpr-encryption-at-rest, gdpr-retention-and-erasure.

Control snippets

Copy each block under the controls key of the node it applies to.

Art. 32(1)(a) — Encryption at rest (gdpr-encryption-at-rest)

Per-node.

"gdpr-encryption-at-rest": {
  "description": "GDPR Art. 32(1)(a) — pseudonymisation and encryption of personal data at rest as a measure proportionate to the risk.",
  "requirements": [
    {
      "requirement-url": "https://archrails.io/catalog/req/gdpr/encryption-at-rest",
      "config": {
        "control-id": "gdpr-encryption-at-rest",
        "algorithm": "AES-256-GCM",
        "key-management": "hsm-or-kms-cmk",
        "key-rotation-days": 365,
        "pseudonymization-tokens-for-direct-identifiers": true
      }
    }
  ]
}

Art. 32(1)(a) — Encryption in transit (gdpr-encryption-in-transit)

Relationship-level. Attach to edges that carry personal data.

"controls": {
  "gdpr-encryption-in-transit": {
    "description": "GDPR Art. 32(1)(a) — encryption of personal data in transit.",
    "requirements": [
      {
        "requirement-url": "https://archrails.io/catalog/req/gdpr/encryption-in-transit",
        "config": {
          "control-id": "gdpr-encryption-in-transit",
          "minimum-tls-version": ["1.2", "1.3"],
          "forbidden-fields": ["http", "ftp", "telnet", "smtp-plain", "ws"]
        }
      }
    ]
  }
}
Where enforcement actually happens for this control. This snippet is an audit attestation — it declares your intent that the edge carries TLS-protected personal data. The substantive enforcement that fires when a code change adds a non-TLS network call comes from ArchRails's relationship-protocol checks, which read the protocol declared on your CALM relationships against the calls the diff introduces. If you declare an edge with protocol: AMQPS (or any TLS-carrying protocol) the engine fires when a code change adds a plaintext call across that edge; if you declare an edge with protocol: HTTP it does not. The gdpr-encryption-in-transit snippet records the regulatory tag against the edge so an audit can pivot from a finding back to its GDPR citation; it does not itself force the engine to fire.

Art. 32(1)(b) — Access restriction (gdpr-access-restriction)

Per-node.

"gdpr-access-restriction": {
  "description": "GDPR Art. 32(1)(b) — ongoing confidentiality of personal-data processing. Access restricted to authorized personnel on a need-to-know basis.",
  "requirements": [
    {
      "requirement-url": "https://archrails.io/catalog/req/gdpr/access-restriction",
      "config": {
        "control-id": "gdpr-access-restriction",
        "authentication": "saml-sso-plus-mfa",
        "authorization": "rbac-need-to-know",
        "allowed-roles": ["customer-success-read", "support-escalation", "data-analyst-aggregated-only"],
        "review-frequency": "quarterly"
      }
    }
  ]
}

Art. 17 + Art. 5(1)(e) — Retention + erasure (gdpr-retention-and-erasure)

Per-node.

"gdpr-retention-and-erasure": {
  "description": "GDPR Art. 5(1)(e) storage-limitation principle + Art. 17 right to erasure. Documented retention period + automated erasure path for personal data at end of retention OR on a valid erasure request.",
  "requirements": [
    {
      "requirement-url": "https://archrails.io/catalog/req/gdpr/retention-and-erasure",
      "config": {
        "control-id": "gdpr-retention-and-erasure",
        "retention-policy-url": "https://internal.example.com/gdpr/retention-policy",
        "max-retention-days": 1095,
        "automated-erasure-on-policy-expiry": true,
        "erasure-on-request-sla-days": 30,
        "erasure-evidence-logged": true
      }
    }
  ]
}

What the engine actually enforces

The engine runs a constraint extractor over your authored CALM: every key under config becomes a constraint that fires when the agent's declared_pattern drifts. There is no GDPR-specific cross-cutting rule — the engine has no "if gdpr-in-scope: true, require these controls" sweep. Enforcement is graph-driven: you attach a control where you want it enforced; the absence of an attach is opt-out by silence.

For the 4 GDPR controls above, here is the enforcement map:

All checks are deterministic — pure function over your CALM JSON. The same constraint engine handles PCI DSS, SOC 2, HIPAA, MiFID II, ISO 27001:2022, NIST CSF 2, NYDFS Part 500, and any controls you author yourself.

Versioning

This is gdpr/v1.0.0 — the first stable cut. Each surviving control has per-validator firing tests + cross-language coverage across 11 Tier A languages (Python, Java, C#, TypeScript, Go, Kotlin, Scala, Rust, Ruby, Swift, PHP). Future bumps: v1.x.y for additive controls and substantive validator coverage; v2.0.0 for breaking changes (control retired, semantics changed). Updates as authoritative guidance or enforcement priorities materially shift.

Out of scope for this template

For those surfaces, pair this template with your privacy program documentation and engage a qualified DPO or privacy law firm.