ADR-0186: Navin KYC / AML Agent, a KYC, KYB, screening and AML product layer on top of the Control Plane
- Status: accepted on 2026-11-04; the two open choices were decided by the user (section 12)
- Date: 2026-11-04
- French version: ../ADR-0186-navin-kyc-aml-agent.md
- Scope: new project
navin-kyc-aml/(FastAPI backend, workers, screens in the shared sector-agent frontend (ADR-0180), Navin integration), additive Control Plane domainservices/control-plane/src/eai/domains/kyc_aml(instance lifecycle, migrations V240 to V249), additive OpenFGA types (deploy/policies/openfga/model.fga), OPA packageeai.kyc_aml(deploy/policies/opa/kyc_aml.rego), contractscontracts/v1/kyc-*.schema.json, Enterprise portal journey, service template prepared and not published - Related documents: ADR-0101 (licence policy), ADR-0108 (Opik), ADR-0110 (OpenSearch), ADR-0111 (SeaweedFS, no
MinIO), ADR-0166 (ClamAV and YARA-X), ADR-0174 (Mem0 and Cognee memory), ADR-0175 (Navin Enterprise RAG Agent),
audit
navin-kyc-aml/docs/en/NAVIN_INTEGRATION_AUDIT.md
Context
The customer asks for a KYC / AML agent for a bank: KYC cases of natural and legal persons, documents with extraction and provenance, KYB and beneficial owners, sanctions, PEP and adverse media screening, risk scoring, CDD, EDD and periodic reviews, AML transaction monitoring, investigations and suspicious activity reports, copilot, reports and administration.
The audit of 2026-11-04 shows that the Control Plane already provides file scanning, object storage, approvals, connectors, DLP and Presidio, RAG, memory, the agent runtime, lineage, evidence and the chained audit. It provides no KYC, KYB, screening or AML logic. The only previous product present in the repository is the RAG Agent (ADR-0175), whose structure is reused.
Decision
1. Product layer, same model as ADR-0175
| Who | Does what |
|---|---|
| Navin Manager | installs and runs the runtime (API, workers, web), TLS, health, backups, upgrades |
| Control Plane | tenants, projects, roles, file scanning, storage, approvals, connectors, DLP, RAG, memory, quotas, audit, policies, traces, instance lifecycle (/v1/kyc-aml/instances) |
| KYC / AML backend | cases, documents and extraction, KYB, screening, risk, reviews, AML monitoring, investigations, reports; it calls the Control Plane only through the enterprise_ai SDK |
The backend never talks directly to Docling, ClamAV, YARA-X, Presidio, Qdrant, Cognee or LiteLLM. It owns the
PostgreSQL schema kyc_aml (Alembic, forced RLS, context set by a transaction local set_config) and a Redis
namespace kept for ephemeral data. Development ports: web 3475, API 8475.
2. Reuse
The bricks of the RAG Agent are reused as adapted and tested copies in the new project: Keycloak token and JWKS
validation, context from /v1/me, OpenFGA and OPA authorization through the Control Plane, per-tenant transactions,
durable queue with a signed identity, SSE with resume, validated citations, observability without personal data,
OIDC PKCE BFF. The bricks announced for the Compliance & Audit, Customer Operations and Fraud & Anomaly Investigation
products are not present at the time of this decision: they are not assumed, sharing will happen after their merge.
3. The banking system stays the source of customers
A KYC case references the customer of the banking system (external_ref, source system); the product creates no
competing master data. Connectors are read only by default; a write towards the banking system needs an explicit
configuration, an OPA policy and an approval.
4. Nothing regulatory is hard coded
- Regulatory frameworks, versions, obligations, controls and applicability are data chosen by the bank and validated by compliance: no text (European or other) is applied by default, nothing is applicable without validation.
- Ownership and control thresholds, match thresholds, risk weights, review periods, AML rules and screening lists are versioned per jurisdiction and configured by the bank. A jurisdiction without a configured threshold refuses the computation instead of applying an implicit value (no hard coded 25 %).
5. Deterministic computations
- Ownership: deterministic engine on the ownership graph, multiple paths, cross holdings and circular structures resolved by summing simple paths with a stop on cycles (no naive multiplication), control rights separate from ownership rights, exact decimal arithmetic. The result is a UBO proposal, never validated without an analyst.
- Risk scoring: versioned model, explicit factors, visible missing data, reproducible score; an override needs a reason, an approval and a trace.
- The language model never establishes a regulatory fact: it proposes, summarises and cites.
6. Screening
- Deterministic Navin engine (Unicode normalisation, transliteration, aliases, exact and approximate matching, attributes such as date of birth and nationality), with no third party dependency or licensed data.
- List sources are configured and licensed by the bank (connector or import); each list version is hashed (SHA-256) and dated, its freshness is checked and a stale list is flagged.
- A match is a potential match alert, never "sanctioned" on a name score; every decision goes through a human review. The PEP module is separate; adverse media distinguish allegation, investigation and decision.
7. Documents
Pipeline through the Control Plane: quarantine, ClamAV, YARA-X (refusal when an engine does not answer), SeaweedFS or customer storage, Docling. Each extracted field keeps its document, page, method, status and reviewer. OCR is never presented as an authenticity check; "identity verified" needs an approved procedure. An external verification service is called only when configured; biometrics are disabled by default.
8. AML monitoring, investigations and reports
- Versioned AML rules, readable and editable only by authorised people (thresholds never go out to the other roles), idempotent ingestion (a replayed event creates no second alert), correlation without erasing the original alerts, separate from transaction fraud.
- Investigations with a timeline, evidence with a chain of custody (fingerprint and history, no silent change), hypotheses and decisions.
- Suspicious activity reports: preparation, validation, confidential archive, no electronic submission without a
configured official interface and never automatic. Compartmentalisation inside the
kyc_amlschema by RLS and OpenFGA (choice of the user, section 12): a dedicated RLS policy needs, besides the tenant, a transaction flag set only by the authorised path after the OpenFGA and OPA check. No disclosure to the customer (tipping-off), including towards the general copilot, channels, notifications and external models.
9. Authorization
- Additive OpenFGA types:
kyc_instance,kyc_customer,kyc_case,kyc_document,kyc_ubo,kyc_screening,kyc_edd,aml_alert,aml_investigation,aml_report,kyc_export,kyc_tool. - OPA package
eai.kyc_aml: KYC approval, risk override, alert closure, report access, regulatory submission, export, AML rule change, maker-checker (no self approval). Everything is refused when the engine does not answer (fail-closed); an object of another tenant answers 404. - Read only by default for agents and connectors; a delegation never widens rights.
10. AI, memory and observability
- Regulatory knowledge base through the existing ingestion of the
knowledgedomain, with jurisdiction and version; citations checked by the server. - Cognee according to the validated trial of ADR-0175 (standard profile of ADR-0174, pgvector, LadybugDB), isolated per tenant; never the official source of UBOs, never a memory of a suspicion as a fact.
- Logical agents on the Navin runtime, tools with complete contracts, approvals for risky actions.
- Observability according to ADR-0101: OpenTelemetry, Opik without identity data, low cardinality Prometheus, Alloy, OpenSearch, Jaeger, OpenLineage. Grafana, Loki and Tempo are AGPL-3.0 and refused.
11. Truth of capabilities
No feature is declared done without a real test; an untested connector is never declared operational; external
lists are not refreshed automatically offline; limits are written in navin-kyc-aml/docs/KNOWN_LIMITATIONS.md.
12. Choices put to the user
- Screening engine: deterministic Navin engine, lists supplied and licensed by the bank (chosen). Rejected: OpenSanctions yente and nomenklatura (data under CC-BY-NC, paid commercial use, licence exception needed) and an external provider only (commercial contract, no real test possible).
- Report compartmentalisation: same
kyc_amlschema, RLS and OpenFGA (chosen). Rejected: separate schema with a dedicated database role. Accepted risk: an application authorization error may expose a report; it is reduced by the dedicated RLS policy of section 8 and covered by leak tests.
Consequences
- The product stays light and versioned separately; its rules and lists are data of the bank.
- Two migration tools: Alembic for
kyc_aml,V*.sql(V240 to V249) for the Control Plane. - Tests use fictitious local lists; screening quality in production depends on the lists of the bank.
Rejected alternatives
- Standalone backend with its own file scanning, OCR and model calls: duplication of governance.
- Customer master data competing with the banking system.
- A "sanctioned" decision or a UBO validation by the AI.
- Automatic submission of a suspicious activity report.
- Immediate publication in the Manager catalogue.