Skip to main content

goAML XML Export

Trust Relay implements a full goAML XML export pipeline that transforms investigation data into regulatory filings compliant with the UNODC goAML standard. This enables compliance officers to generate Suspicious Transaction Reports (STRs) directly from completed investigations, ready for submission to national Financial Intelligence Units (FIUs).


What is goAML?

goAML (go Anti-Money Laundering) is the United Nations Office on Drugs and Crime (UNODC) standard software platform for FIUs worldwide. Over 60 countries use goAML to receive, process, and analyze suspicious transaction reports from reporting entities (banks, payment providers, crypto exchanges, insurance companies).

Belgium's CTIF-CFI has mandated goAML exclusively since September 2024. The EU Anti-Money Laundering Authority (AMLA) is mandating standardized STR formats from July 2027. Trust Relay's goAML integration positions reporting entities to meet both current national and upcoming EU-wide requirements.

Supported Report Types (Phase 1)

CodeTypeDescription
STRSuspicious Transaction ReportCore AML report — the primary filing type
SARSuspicious Activity ReportBroader activity-based report

Phase 2 will add CTR (Cash Transaction Report), TFTR/TFAR (Terrorism Financing), and PEPR/PEPTR (PEP Reports).

Supported Countries

Nine country profiles ship under app/goaml/profiles/ (plus the shared _base.toml). The profile loader auto-discovers any <cc>.toml file, so GET /goaml/profiles lists all of them. Indicator code sets (app/goaml/indicators/<cc>_indicators.toml) currently exist for Belgium, Czechia, and Luxembourg; the remaining profiles load with their structural rules and an empty indicator set until indicator files are authored.

CountryFIUProfileIndicator set
BelgiumCTIF-CFIprofiles/be.tomlyes (be_indicators.toml)
CzechiaFAÚprofiles/cz.tomlyes (cz_indicators.toml)
LuxembourgCRF-FIUprofiles/lu.tomlyes (lu_indicators.toml)
FranceTRACFINprofiles/fr.tomlnot yet
GermanyFIU (Zoll)profiles/de.tomlnot yet
NetherlandsFIU-NLprofiles/nl.tomlnot yet
RomaniaONPCSBprofiles/ro.tomlnot yet
SlovakiaFSJprofiles/sk.tomlnot yet

Architecture

The export pipeline follows a five-stage linear flow: canonical entities are assembled from investigation data, enriched through a draft wizard, validated against country-specific rules, serialized to XML, and stored with full audit trail.

Pipeline Components

ComponentModuleResponsibility
Canonical Entitiesapp/models/canonical_entities.pyShared data model (persons, accounts, transactions)
Country Profilesapp/goaml/profile_loader.pyTOML-based FIU configuration with merge hierarchy
Indicator Serviceapp/goaml/indicator_service.pyCountry-specific indicator codes (predicate offences, suspicion reasons)
Data Mapperapp/goaml/mapper.pyTransforms canonical entities to goAML IR models
XML Builderapp/goaml/xml_builder.pySerializes IR to lxml element tree with _my_client tag logic
Validatorapp/goaml/validator.py25+ business rules + optional XSD schema validation
Readiness Checkerapp/goaml/readiness.pyWeighted 0-100 score with per-category breakdown
Export Serviceapp/goaml/export_service.pyOrchestrates the full pipeline: draft creation through XML generation

Canonical Entities (Shared Foundation)

The canonical entity model (app/models/canonical_entities.py) is the shared data foundation that feeds the goAML export pipeline and will be reused by future products (customs compliance vertical — EORI + guarantee validator + shipment workflow, VoP verification). Three entity types mirror the goAML schema structure:

EntitySchemaKey Fields
PersonSchemaNatural person or legal entityfirst_name, last_name, entity_name, role, date_of_birth, nationality, identification[], addresses[], pep_status, sanctions[]
AccountSchemaBank accountiban, swift_bic, institution_name, balance, currency, opened_date, closed_date
TransactionSchemaFinancial transactiontransaction_number, transaction_date, amount_local, currency_local, from_account_id, from_person_id, to_account_id, to_person_id

The CanonicalEntities container aggregates all three types plus AccountSignatorySchema junction records:

class CanonicalEntities(BaseModel):
persons: list[PersonSchema]
accounts: list[AccountSchema]
transactions: list[TransactionSchema]
signatories: list[AccountSignatorySchema]

These entities are persisted in PostgreSQL via 4 ORM tables (investigation_persons, investigation_accounts, investigation_account_signatories, investigation_transactions) and populated during the OSINT investigation phase.


Country Profile System

Each FIU has specific requirements for XML structure, mandatory fields, indicator codes, and validation rules. Trust Relay handles this through a TOML-based profile system with a three-layer merge hierarchy:

  1. _base.toml -- sensible defaults shared across all countries
  2. <country_code>.toml -- country-specific overrides (disabled nodes, currency, FIU name)
  3. Tenant configuration -- runtime overrides (e.g., rentity_id assigned by the FIU)

The GoAMLCountryProfile is a frozen dataclass that captures:

  • disabled_nodes: XML elements to suppress (e.g., Belgium disables rentity_branch)
  • supported_report_types: which report types the FIU accepts
  • assertions: validation parameters (IBAN regex, max transactions, funds code matching)
  • indicators: predicate offence and suspicion reason codes loaded from indicators/<cc>_indicators.toml
  • xsd_path: optional XSD schema file for structural validation

Readiness Scoring

Before an officer can export, the readiness checker computes a weighted 0-100 score across five categories. This guides the officer through the draft wizard by highlighting exactly what data is missing.

CategoryWeightChecks
Report Metadata20%reason_populated, indicators_selected, entity_reference
Persons25%has_persons, all_have_names, all_have_dob, all_have_nationality
Transactions30%has_transactions, all_have_amount, all_have_date, all_have_parties
Accounts15%all_have_holder, ibans_valid, swifts_valid
Compliance10%predicate_offence_present (required for STR/SAR/TFTR/TFAR)

The readiness score is recomputed on every draft update (PATCH endpoint) and returned alongside the draft data so the frontend can render progress indicators per wizard step.


Validation Engine

The validator (GoAMLValidator) enforces 25+ rules at three levels, producing typed ValidationIssue instances partitioned by severity (error, warning, info):

Report-Level Rules

RuleSeverityDescription
R1ErrorSTR/SAR/TFTR/TFAR must have at least one predicate offence indicator (PO-*)
R5Errorcurrency_code_local must match country profile
R10WarningEntity with "trust" in business field should have legal form 273
R14ErrorReason/narrative required for applicable report types
R15Errorentity_reference must be present and non-empty
TRS-02ErrorTransaction count must not exceed profile maximum

Transaction-Level Rules

RuleSeverityDescription
R7ErrorTransaction date must not be in the future
R8Erroramount_local must be greater than zero
TRS-01ErrorTransaction numbers must be unique within report
TRS-03ErrorTransfer (funds_code Q) requires accounts on both sides
TRS-04ErrorFrom/to funds codes must match (when profile requires)

Person and Account Rules

RuleSeverityDescription
R11WarningClient person birthdate should not be blank
R12ErrorBirthdate must not be placeholder 1900-01-01
R13ErrorNationality must not be "UNKNOWN"
IBAN-01ErrorIBAN must match profile regex pattern
BIC-01ErrorSWIFT/BIC must match profile regex pattern
ACC-01ErrorWhen IBAN present, account field must equal IBAN
ACC-02ErrorWhen IBAN present, SWIFT must be provided
R6ErrorClient account must have at least one signatory
R9ErrorClosed/blocked account requires a closed date

XSD Schema Validation

When an XSD file is available for the country profile (xsd/ directory), the validator additionally runs full XML schema validation via lxml.etree.XMLSchema, catching structural issues that business rules cannot express.


XML Builder

The GoAMLXMLBuilder serializes the IR model tree (GoAMLReport) into an lxml element tree, respecting:

  • Disabled nodes: elements listed in profile.disabled_nodes are silently suppressed
  • _my_client tag variants: goAML uses different XML tag names for "my client" vs. third-party entities (e.g., t_from_my_client vs. t_from, from_account_my_client vs. from_account)
  • UTF-8 XML output: with XML declaration, pretty-printed

The builder output is validated before storage and the raw XML bytes are persisted to MinIO with SHA-256 hash for integrity verification.


API Endpoints

Ten endpoints cover the full regulatory filing workflow:

Profile & Indicator Discovery

MethodPathDescription
GET/goaml/profilesList available FIU country profiles
GET/goaml/profiles/{country_code}/indicatorsList indicator codes grouped by category (predicate offences, reason for suspicion, report-type-specific)

Draft Lifecycle

MethodPathDescription
POST/cases/{case_id}/goaml/draftsCreate a new report draft (auto-populates from investigation data)
GET/cases/{case_id}/goaml/drafts/activeGet the currently active draft
PATCH/cases/{case_id}/goaml/drafts/{draft_id}Update draft fields + recompute readiness
DELETE/cases/{case_id}/goaml/drafts/{draft_id}Discard (soft-delete) a draft so a new one can be created

Validation & Export

MethodPathDescription
POST/cases/{case_id}/goaml/drafts/{draft_id}/validateDry-run validation (business rules + XSD)
POST/cases/{case_id}/goaml/drafts/{draft_id}/exportGenerate final XML, store in MinIO, create audit record

Export History

MethodPathDescription
GET/cases/{case_id}/goaml/exportsList all exports for a case
GET/goaml/exports/{export_id}/downloadDownload the generated XML file

All endpoints require authentication (get_current_user) and tenant context (get_current_tenant).


Database Schema

Seven tables support the goAML pipeline (migration 031):

TablePurpose
investigation_personsCanonical persons (natural + legal entities)
investigation_accountsBank accounts with IBAN, SWIFT, balance
investigation_account_signatoriesPerson-to-account junction (signatory role)
investigation_transactionsFinancial transactions with from/to parties
goaml_report_draftsDraft state: narrative, indicators, selected entities, readiness
goaml_exportsImmutable export records: XML hash, MinIO key, validation result
goaml_enum_mappingsTenant-customizable enum code translations

Data Flow Summary


Phase 2 Roadmap

  • Additional report types: CTR, TFTR, TFAR, PEPR, PEPTR
  • Additional country profiles: Germany (BaFin), Malta (FIAU), Netherlands (FIU-NL), Switzerland (MROS)
  • Multi-party transactions: supporting transactions with more than two sides
  • Goods/services node: for trade-based money laundering scenarios
  • Batch export: bulk generation of reports across multiple cases