Skip to main content
Back to Insights
Compliance9 min read

Automating Customer Due Diligence Without Hard-Coding Compliance

Jurisdiction-aware CDD policies, provider abstraction, and risk-level-driven verification depth. Configuration over code.

Automating Customer Due Diligence: Architecture for Jurisdiction-Aware CDD


Somewhere in your codebase, there is an if-statement that decides how deeply to verify a customer. It checks the country. It checks the risk level. It calls a provider. When the regulator in Spain changes the rules for enhanced due diligence, an engineer modifies the if-statement, writes a test, deploys, and hopes no other branch was affected.

This is how most CDD implementations work. It is also why expanding to a new jurisdiction takes months instead of days: the compliance logic is embedded in code, not expressed as configuration. Every new country requires development work. Every rule change requires a release cycle. Every audit requires an engineer to explain what the code does, because the MLRO cannot read it directly.

The Hard-Coded CDD Problem

The pattern is recognizable:

if country == "DE" and risk_level == "high":
    require_enhanced_document_verification()
elif country == "ES" and risk_level == "medium":
    require_standard_address_verification()
elif country == "DE" and risk_level == "low":
    require_basic_identity_check()

Scattered across the codebase. Each branch is a compliance rule encoded as application logic. The problems compound:

  • Adding a jurisdiction means modifying code. Austria requires different address verification depth than Germany. Switzerland has different documentation requirements than either. Each addition is a code change, a test cycle, a deployment.
  • Changing a rule means modifying code. The MLRO decides that high-risk customers in Spain now require enhanced document verification instead of standard. That decision travels through a ticket, waits in a sprint backlog, gets implemented by a developer who may not fully understand the regulatory context, and ships in the next release.
  • Auditing the rules means reading code. When the regulator asks "what due diligence do you perform for high-risk customers in Germany?", the answer requires an engineer to trace code paths and explain branching logic. The compliance team cannot independently verify what the system does.

The Policy Model

A CDD policy is a record, not a code branch. It has four dimensions:

DimensionValuesExample
JurisdictionCountry code or GLOBAL (fallback)DE, ES, AT, GLOBAL
Risk LevelLow, Medium, High, ProhibitedHigh
Check TypeAddress verification, document check, source of fundsaddress_verification
DepthStandard, EnhancedEnhanced

A policy record says: "For jurisdiction X, at risk level Y, perform check type Z at depth W." The system stores these as data, queryable, versionable, auditable by non-engineers.

Example policy set:

JurisdictionRisk LevelCheck TypeDepth
DELowAddress verificationStandard
DEHighAddress verificationEnhanced
ESMediumAddress verificationStandard
GLOBALLowAddress verificationStandard
GLOBALHighAddress verificationEnhanced

Resolution logic: when a CDD check is triggered, the system looks for a jurisdiction-specific policy first. If none exists, it falls back to GLOBAL. This means: launch in a new country with zero configuration, the GLOBAL policies apply automatically. Then add country-specific overrides when the compliance team is ready.

The fallback chain:

Customer Event

Address change, risk level upgrade, or periodic review triggers CDD check.

Resolve policy: jurisdiction-specific policy exists?
Jurisdiction Policy

Use the jurisdiction-specific policy for check type and depth.

No jurisdiction-specific policy found
GLOBAL Fallback

Use the GLOBAL fallback policy. Covers all jurisdictions by default.

Policy resolved
Create Check Record

Check record created with policy version, type, and depth. Routed to provider.

New country, day one: GLOBAL policies apply. No code change. No deployment. The MLRO adds jurisdiction-specific overrides through the admin interface when local regulations require different depth.

Policy Lifecycle

Policies are not static. They evolve as regulations change and as the compliance team refines its risk appetite. The lifecycle must be auditable:

Draft → Active → Archived.

Only one active policy can exist per jurisdiction × risk level × check type combination. Activating a new policy automatically archives the previous one. The archived policy remains in the database, immutable, queryable, timestamped. An auditor can reconstruct which policy was in effect for any given check at any point in time.

This matters during regulatory examination. The question is not "what are your current CDD policies?" It is "what policy was in effect when you onboarded Customer X on March 15?" If policies are code branches, the answer requires git archaeology. If policies are versioned records, the answer is a database query.

Provider Abstraction

The policy defines what to check. The provider interface defines how.

A CDD check for address verification can be fulfilled by Loqate (address validation API), Google Places (geocoding), a manual document review, or a combination. The policy says "verify the address at Enhanced depth." The provider implementation says "call Loqate, cross-reference with the postal registry, flag discrepancies for manual review."

The separation matters when providers change. Switching from Provider A to Provider B is a configuration change at the provider layer. No policy change. No code change in the CDD engine. The check type and depth remain the same, only the fulfillment mechanism changes.

This is the same pattern used for KYC verification: the system needs identity verification. Whether Identomat, Onfido, or Jumio fulfills it is a configuration choice. The onboarding flow does not know or care which provider is active.

Jurisdiction Profiles

Each jurisdiction carries more than CDD policy overrides. It carries the regulatory parameters that affect operations:

ParameterPurposeExample
Retention yearsHow long to keep records (GoBD: 10 years, HGB §257)DE: 10, ES: 10
Holiday calendarTARGET2 + national holidays for business day calculationDE: TARGET2 + German federal, ES: TARGET2 + Spanish national
CDD configurationDefault risk thresholds, required check typesConfigurable JSONB per jurisdiction
Chart of Accounts templateGL structure for jurisdiction-specific accountingSKR04 (Germany), PGC (Spain)

Business day calculation uses the jurisdiction's holiday calendar. "5 business days" in Germany is different from "5 business days" in Spain because of different public holidays. The holding period for SEPA R-transactions, the deadline for CDD check completion, the processing time for regulatory reports, all depend on the correct calendar.

Audit Trail

Every CDD check is recorded as an immutable record:

  • Policy version that was in effect
  • Check type and depth
  • Provider used
  • Result (pass, fail, manual review)
  • Timestamp (created, completed)
  • Reviewer (if manual escalation)

The check record is delete-protected at the database level (a trigger prevents DELETE operations on the audit table). Corrections are new records, not updates to existing ones. The complete history is preserved.

An auditor's path: Customer → CDD checks → for each check: which policy was active, what depth was applied, which provider fulfilled it, what was the result, who reviewed it (if manual). All from structured, queryable data. No code reading required.

Operational Impact

Market expansion without engineering. New jurisdiction? The GLOBAL fallback policies apply immediately. Country-specific overrides are added by the compliance team through the admin interface. No developer in the loop.

Rule changes without deployments. The MLRO updates a policy record. The new policy takes effect on the next check. The old policy is archived. The audit trail captures both versions and the transition timestamp.

Regulatory examination readiness. Every check is traceable to a specific policy version. Every policy change is timestamped and attributed. The compliance team can answer regulator questions directly, without engineering support.

Provider flexibility. KYC provider contract expires? Switch to a new provider through configuration. The CDD policies, the what, remain unchanged. Only the how changes.


Read more: Compliance Infrastructure | Security & Compliance


Sources:

  • AMLD5, Directive 2018/843, Art. 13 (Customer due diligence measures)
  • AMLD6, Directive 2024/1640, Art. 16-18 (Risk-based approach to CDD)
  • GoBD (Grundsätze zur ordnungsmäßigen Führung und Aufbewahrung von Büchern), 10-year retention
  • HGB §257, Retention periods for commercial records