Lux Docs
Regulated

Compliance Integration

KYC, AML, sanctions screening, and regulatory frameworks

The luxfi/compliance module provides a complete regulated financial compliance stack: identity verification, KYC orchestration, AML/sanctions screening, transaction monitoring, payment compliance, and multi-jurisdiction regulatory frameworks. Zero external dependencies -- standard library only.

Overview

               ┌──────────────────┐
               │   complianced    │
               │     :8091        │
               └────────┬─────────┘

        ┌────────────────┼────────────────┐
        │                │                │
  ┌─────┴─────┐   ┌─────┴─────┐   ┌─────┴─────┐
  │    IDV    │   │    AML    │   │ Payments  │
  │ Providers │   │ Screening │   │Compliance │
  └─────┬─────┘   └─────┬─────┘   └─────┬─────┘
        │                │                │
   ┌────┼────┐      ┌───┼───┐       ┌───┼───┐
   │    │    │      │   │   │       │   │   │
 Jumio Onfido Plaid OFAC EU PEP  Travel CTR Stablecoin
                     SDN HMT       Rule     Validation

Identity Verification Providers

Three IDV providers are supported out of the box. Each implements the same provider interface: initiate verification, check status, and parse webhooks.

ProviderAPIFeaturesEnv Vars
JumioNetverify v4ID + selfie, liveness, document verificationJUMIO_API_TOKEN, JUMIO_API_SECRET, JUMIO_WEBHOOK_SECRET
Onfidov3.6Applicant, check, SDK token, watchlist screeningONFIDO_API_TOKEN, ONFIDO_WEBHOOK_SECRET
PlaidIdentity VerificationSession-based IDV, bank-linked identityPLAID_CLIENT_ID, PLAID_SECRET, PLAID_WEBHOOK_SECRET

All providers validate webhook signatures via HMAC-SHA256.

import (
    "github.com/luxfi/compliance/pkg/kyc"
    "github.com/luxfi/compliance/pkg/idv"
)

svc := kyc.NewService()
svc.RegisterProvider(idv.NewJumio(idv.JumioConfig{
    APIToken:      os.Getenv("JUMIO_API_TOKEN"),
    APISecret:     os.Getenv("JUMIO_API_SECRET"),
    WebhookSecret: os.Getenv("JUMIO_WEBHOOK_SECRET"),
}))

Application status flow:

draft -> pending -> pending_kyc -> approved
                                -> rejected

KYC status flow:

not_started -> pending -> verified
                       -> failed

AML Screening

Sanctions & PEP Screening

Screen individuals against global sanctions lists and politically exposed persons databases:

  • OFAC SDN -- US Treasury Office of Foreign Assets Control
  • EU consolidated sanctions -- European Union sanctions list
  • UK HM Treasury -- Her Majesty's Treasury sanctions list
  • PEP databases -- Politically Exposed Persons
  • Adverse media -- Negative news screening

Match types: exact, fuzzy (Levenshtein distance), partial. Risk scoring: low, medium, high, critical.

import "github.com/luxfi/compliance/pkg/aml"

screeningSvc := aml.NewScreeningService()
result, err := screeningSvc.Screen(ctx, aml.ScreenRequest{
    FullName:    "John Doe",
    DateOfBirth: "1985-03-15",
    Country:     "US",
})
// result.Matches contains any sanctions/PEP hits with scores

Transaction Monitoring

The rules engine detects suspicious transaction patterns. InstallDefaultRules adds the three mandatory FinCEN baselines:

monSvc := aml.NewMonitoringService()
aml.InstallDefaultRules(monSvc)

This installs:

RuleTypeThresholdRegulation
CTR thresholdSingle amount$10,00031 CFR 1010.311
StructuringPattern detection$9,000-$9,99931 USC 5324
Velocity (24h)Aggregate volume$50,000Enhanced KYC trigger

Add custom rules:

monSvc.AddRule(aml.Rule{
    ID:              "high-value-crypto",
    Type:            aml.RuleSingleAmount,
    ThresholdAmount: 25000,
    Currency:        "USD",
    Enabled:         true,
    Severity:        aml.SeverityHigh,
    Description:     "Flag crypto transactions over $25,000",
})

Alert lifecycle: open -> investigating -> escalated -> closed/filed.

Real-Time AML Engine

For real-time scored monitoring beyond in-process static rules, delegate to the Lux AML engine (github.com/luxfi/aml, the amld service) — a native, single-binary AML/CFT monitoring engine. It evaluates every transaction against a configurable rules DSL and a weight-of-evidence scoring model, returning an action, a risk score, activation alerts, and sanctions matches. Screen a transaction over its versioned HTTP API:

// POST /v1/aml/transactions on the Lux AML engine (amld :8090)
req, _ := http.NewRequest("POST", amlEngineURL+"/v1/aml/transactions", body)
req.Header.Set("X-Org-Id", orgID) // set by the gateway from the JWT owner claim
resp, err := http.DefaultClient.Do(req)
// -> { "action": "allow|review|flag|block|report", "score": 0.0-1.0,
//      "alert_ids": [...], "case_id": "..." }

Set AML_ENGINE_URL to the engine address and treat an unreachable engine as fail-closed (reject) for regulated products. The engine auto-opens a case on any block or report action. See the Lux AML engine reference for the rules DSL, the 20 starter typologies, scoring, and the admin UI.

Regulatory Frameworks

Multi-jurisdiction compliance rules are built in:

JurisdictionRegulatorKey Requirements
USAFinCEN, SEC, FINRABSA (CIP, CTR $10k+, SAR), suitability, accredited investor
UKFCARegistration, 5AMLD CDD/EDD, HM Treasury sanctions
Isle of ManIOMFSADesignated Business, AML/CFT Code 2019, source of wealth/funds

Each jurisdiction defines: required identity fields, application validation rules, and transaction limits.

import "github.com/luxfi/compliance/pkg/regulatory"

jur := regulatory.Get("USA")
err := jur.ValidateApplication(application)
limits := jur.TransactionLimits()

Payment Compliance

Travel Rule

FATF Recommendation 16 requires originator and beneficiary information for transfers over $3,000:

import "github.com/luxfi/compliance/pkg/payments"

result := payments.ValidateTravelRule(payments.TransferInfo{
    Amount:           5000,
    OriginatorName:   "Alice",
    BeneficiaryName:  "Bob",
    OriginatorAddr:   "123 Main St",
})
// result.Compliant = true if all required fields present

CTR Detection

Flags transactions at or above $10,000 for Currency Transaction Report filing.

Stablecoin Validation

Token allowlists, per-jurisdiction policies, and address risk scoring with chain analysis integration point.

Integration Methods

Go Library (import directly)

The most common integration. Import packages and use them in your Go application:

import (
    "github.com/luxfi/compliance/pkg/kyc"
    "github.com/luxfi/compliance/pkg/idv"
    "github.com/luxfi/compliance/pkg/aml"
    "github.com/luxfi/compliance/pkg/regulatory"
    "github.com/luxfi/compliance/pkg/payments"
)

HTTP API (standalone server)

Run complianced as a standalone service and call it over HTTP:

go build -o complianced ./cmd/complianced/
JUMIO_API_TOKEN=... COMPLIANCE_API_KEY=... ./complianced
MethodPathDescription
POST/v1/kyc/verifyInitiate KYC verification
GET/v1/kyc/status/{id}Check verification status
POST/v1/aml/screenScreen against sanctions/PEP
POST/v1/aml/monitorMonitor transaction
GET/v1/aml/alertsList alerts
POST/v1/payments/validateValidate payment compliance
GET/v1/regulatory/{jurisdiction}Get jurisdiction requirements

Auth: X-Api-Key header. Health check at /healthz requires no auth.

TypeScript SDK

The @luxbank/compliance SDK provides a TypeScript client for NestJS applications:

import { ComplianceModule } from '@luxbank/compliance'

ComplianceModule.forRoot({
  baseUrl: process.env.COMPLIANCE_BASE_URL || 'http://compliance:8091',
  apiKey: process.env.COMPLIANCE_API_KEY || '',
})

The TypeScript SDK lives in luxfi/bank/pkg/compliance.

On this page