Skip to content
In the news TRM Labs × Finray — audit-ready crypto transaction monitoring for banking
Finray
Book a briefing

Finray platform · Corebanq · Architecture overview

Full system architecture

Evidence-based architecture overview of Corebanq, the core banking platform behind regulated EU PI / EMI institutions. Compiled from source-code analysis of the live system. The page is the single point of reference for technical buyers, integration engineers, and procurement teams evaluating the platform.

Source-of-truth
Live Corebanq monorepo — Go API + listener service + multi-tenant SPA
Cut-off
2026-05-07
Scope
Runtime tiers, internal adapters, storage, cloud, external integrations
Audience
Technical buyers · integration engineers · platform architects

/0.1 At-a-glance

Six numbers that define the platform shape

The platform is a Go-on-Postgres core banking system with a multi-tenant React SPA in front and an event-driven listener service behind. The numbers below are evidence-based from the live source tree at the cut-off date — every component referenced in the sections that follow is indexed under one of them.

45+
API modules · Go
3
Microservices · API · Listener · Frontend
14
Internal Go connectors
17
External integrations
8
Common cross-cutting packages
5
Shared frontend libraries

/0.2 Stack signature

Eight runtime anchors

The technology stack is deliberately narrow. One language for all backend services (Go), one database for all authoritative state (PostgreSQL), one orchestrator (Kubernetes on EKS), one cloud (AWS). Every component below is in production use; nothing is research-stage.

Go 1.25
API + connectors + listener
TypeScript / React 19
Multi-tenant white-label SPA
PostgreSQL
Authoritative ledger + outbox
Redis
Cache · rate limits · pub/sub
Kubernetes / EKS
Production runtime
AWS
Managed services + secrets
RabbitMQ
Outbox relay · event queue
DSL Engine
Banking-product workflow rules

/0.3 Surfaces & gateway

Customer-side, operator-side, and the edge between them

Two SPAs (customer + admin) sit in front of one API gateway. The gateway authenticates, authorises, rate-limits, and tenant-routes every request before any module sees it. There is exactly one surface for the platform and exactly one gateway — multi-tenant routing is internal, never per-tenant deployment.

Client tier

web-app

Customer portal

Multi-tenant white-label SPA. Per-tenant theming, locale and routing resolved at boot. SSE-driven notifications.

React Router DOM v7TanStack QueryZustandMUI v7Axios + auth refreshreact-hook-form + Zodi18nextSSE notifications
admin-app

Backoffice

Operator-side controls — KYC/KYB review, transaction monitoring, RBAC management, DSL editor, risk dashboard.

Admin portalKYC/KYB reviewTransaction monitoringRBAC managementDSL editor (Monaco)Risk dashboard
Shared packages

Turborepo monorepo

npm workspaces splitting the SPA into composable surfaces shared across customer + admin + Storybook.

packages/apipackages/storespackages/uipackages/hookspackages/i18npackages/constantspackages/brandspackages/iconspackages/utilspackages/onboarding
Storybook

Component library

Self-hosted UI documentation with theme variants and MSW-mocked API responses.

UI componentsMSW mocksTheme variants

Gateway tier

HTTP/HTTPS server

Edge router

Go · Chi Router v5 on :8080 / :8443. Every request enters here; authentication, rate limiting and tenant isolation are enforced before any module sees it.

CORS middlewareJWT auth (golang-jwt/v5)RBAC authorisationRedis-backed rate limitHSTS / TLSRequest IDHTTP→HTTPS redirectRequest loggerGraceful shutdownLifecycle middleware
Auth system

JWT + OTP + TOTP + MFA

Access + refresh tokens, email OTP, TOTP via pquerna/otp, password reset, invite flow, full session-audit trail.

Access token (JWT)Refresh tokenEmail OTPTOTP (pquerna/otp)2FA verificationPassword resetInvite flowSession audit
RBAC engine

Role-based access control

Roles, permissions and API endpoint registry. Dynamic config via YAML. Modules are license-gated at the engine.

RolesPermissionsAPI endpoints registryDynamic RBAC configYAML role definitionsLicense-gated modules
Health checks

/v1/check/* endpoints

Per-dependency liveness probes. Each dependency a separate endpoint so a degraded subsystem doesn't fail the whole platform.

DBRedisEmailSMSQueueStorageOCRLLMTOTPCrypto rails

Client ↔ gateway transports — HTTPS REST / JSON, Server-Sent Events, JWT bearer auth.


/0.4 Core API modules

Eight functional clusters · 45+ Go modules

The Go API is structured as functional clusters — each cluster a directory under corebanq.api/ with its own subpackages, GORM models, and DSL hooks where applicable. The double-entry ledger sits at the centre; every other cluster integrates with it via the outbox pattern (see /0.8) so no module owns its own settlement.

Core banking

Double-entry ledger system

  • accounts
  • ledgers
  • transactions
  • transfers
  • currencies
  • balance_history
  • tariffs
  • invoices
  • payers
  • recipients
  • counterparties
  • charts
Outbox patternSubledgerReconciliationFX spreads
FX engine

Multi-source rate provider

  • fx module
  • fx spreads
  • fx tariffs
  • fx scheduler
ECB ratesCentral-bank reference feedCoinMarketCapCrypto-rails FXDefault rates (YAML)
Compliance & AML

KYC · KYB · KYT

  • kyc
  • kyb
  • kyt
  • risk
  • ops
IDV pollingQueue consumerVelocity rulesAML screeningRisk assessment
Crypto rails

Crypto payment integration

  • crp module
  • crp webhook
  • crp api
  • crp setup jobs
gRPC clientREST clientQueue consumerLicense-gatedMerchant management
Customer & identity

Users · roles · personas

  • customers
  • users
  • personas
  • roles
  • rbac
  • addresses
  • signatories
  • profile
B2B teamsKYC linksInvite flowMFA
Documents & QES

e-Signature · PDF · uploads

  • qes
  • pdfgen
  • uploads
  • items
  • products
  • templateadmin
QES providerPDF formsOCR (GoTesseract)QR invoicesForm templates
Comms & platform admin

Notifications · chat · config

  • notifications
  • chats
  • preferences
  • appconfigadmin
  • i18nadmin
  • countries
  • tasks
  • modulesmisc
SSE pushEmail notifyPush notifyChat rooms
DSL / rule engine

Banking-product workflow DSL

  • dsl module (API)
  • dsl library
  • trx library
  • IWT product
  • OWT product
  • OWN product
Custom interpreterGL booking from rulesTransaction state machineProduct-version audit

DSL example — outward wire transfer rule

# OWT — outward wire transfer
rule "OWT" {
  when case {
    tariff   { type: "exchange" }
    gl-batch { txn = id
      book ledger = "22011" op = debit
    }
    call  { interface: "kyt_service" }
    route { event: "complete" }
  }
}

Banking products are first-class artefacts compiled and versioned by the rule engine. Every rule is auditable — the same DSL that runs the platform is also the audit trail of what ran.


/0.5 Internal connectors

Fourteen single-purpose adapters

Every external runtime concern (a database, a queue, an SMS gateway, an LLM endpoint) sits behind a single-purpose adapter under corebanq.api/connectors/. Modules consume adapters by interface; the adapter is the only place that knows the wire format. Adapter-swapping is a configuration change, not a refactor.

db

PostgreSQL via GORM + pgx/v5

Connection poolgorm_loggerMigrations
ram

Redis · rate limits · cache

In-memoryRedis driverRate counter
email

Mailjet · AWS SES · SMTP

TemplatesWebhookDB overlay
sms

Twilio SDK

OTP SMSTemplatesi18n
queue

RabbitMQ · AWS SQS · Local

amqp091-goSQSLocalQueue
storage

MinIO · AWS S3

minio-go/v7aws-sdk-v2/s3File mgmt
kyc

Identity verification · sanctions

IDV providerSanctions DBPolling
kyt

Fiat + crypto monitoring

Fiat screeningCrypto KYTTRX adapter
crp

Crypto payment rails

gRPC clientREST clientMerchant mgmt
lm

LLM — Bedrock · Ollama

AWS BedrockOllamaChat assist
ocr

GoTesseract microservice

Document OCRHTTP service:8081
im

Telegram · Console driver

Telegram botTemplatesPluggable
totp

TOTP 2FA (pquerna/otp)

QR generationBarcodeAudit log
push

Push notifications

FirebaseAPNs

/0.6 Storage & runtime

Eight services on the production runtime

Production runs on Kubernetes (EKS, eu-central-2). Development runs on Docker Compose with the same service list, minus AWS-managed substitutions. PostgreSQL is the source of truth for every record; Redis carries ephemeral state only; RabbitMQ is the reliable-messaging bus that connects the API to the listener service.

PostgreSQL

Primary database

GORM ORM, pgx/v5 driver, port :5432

Schemas: outbox, preferences, chat, reconciliation, kyc, …

Redis

Cache + rate limits

go-redis/v9, port :6379, REQUIREPASS auth

TOTP state, webhook dedup, pub/sub

RabbitMQ

Message broker

amqp091-go driver, AMQP :5672, mgmt :15672

KYC/CRP event queues, outbox relay

MinIO

Object storage

minio-go/v7, API :9000, console :9001

Uploads, KYB docs, PDF forms

GoTesseract

OCR microservice

Custom Docker image, HTTP :8081

Document OCR

Ollama

Self-hosted LLM

mistral:7b-q4 default, port :11434

Optional AI profile [ai]

Mail dev server

SMTP capture (dev only)

SMTP :1025, UI :8025

Development environment

corebanq.listener

Event / webhook service

Go · HTTP :8090, metrics :8091, health :8092, pprof :8093

TOTP workers, webhook delivery, queue relay


/0.7 Cloud & external

AWS-managed core, narrow third-party perimeter

The cloud surface is small and named — eight AWS services plus a third-party integration list grouped by control category. Every external integration sits behind one of the internal connectors in /0.5 — there is no direct external call from a module.

AWS managed services

AWS SES

Transactional email

aws-sdk-v2/ses
AWS SNS

Push notifications

aws-sdk-v2/sns
AWS SQS

Managed queue

aws-sdk-v2/sqs
AWS S3

Object storage (prod)

aws-sdk-v2/s3
AWS Bedrock

Managed LLM API

bedrockruntime
AWS SSM

Secrets / config

aws-sdk-v2/ssm
AWS EKS

Kubernetes cluster

Production runtime
AWS ECR

Container registry

Docker images

Third-party integrations

KYC

Identity-verification provider

Document verification, liveness check, IDV sessions, webhook callbacks.

KYC / sanctions

Sanctions-list provider

Sanctions list screening, PEP checks, self-hosted or API.

KYT / AML

Fiat transaction-monitoring vendor

Fiat transaction monitoring, AML screening, alerts.

KYT / AML

XZiel (xziel-api)

Universal transaction schema, financial-monitoring platform, enrichment. Same group; fully integrated.

KYB

National company registry

Operator-jurisdiction company registry feed, credit-bureau adapter, TLS client.

KYB

National commercial register

Operator-jurisdiction commercial register, company search by registry ID.

QES

Qualified e-signature provider

EU/EEA-eligible Qualified Electronic Signatures, signatory invite flow, certificate issuance.

FX rates

ECB reference feed

EUR reference rates, BUY/SELL rate source for ledger booking.

FX rates

Central-bank reference feed

Operator-base-currency reference rates, daily rate feed.

FX / crypto

CoinMarketCap

Crypto-to-fiat exchange rates, live price feeds.

Payments

Crypto payment gateway

Crypto rails, merchant management, gRPC + REST.

Email

Mailjet

Transactional email API, bounce handling, templates.

SMS

Twilio

SMS delivery (OTP, alerts), twilio-go SDK, i18n templates.

Messaging

Telegram bot API

Instant messaging for ops alerts / compliance, telegram-bot-api/v5.

CI / CD

Self-hosted GitLab

Stage runner on EKS, ECR push.

Quality

SonarQube

Code quality analysis, sonar-project.properties present in all services.


/0.8 Transaction lifecycle

Outward wire transfer — DSL-driven state machine

Transactions are not implemented as ad-hoc Go code. They are declared as DSL rules — OWT_1.0.0.dsl, IWT_1.0.0.dsl, OWN_1.0.0.dsl — interpreted by the rule engine. The diagram below is the actual state machine for an outward wire, not a stylised summary. Every node is a step the engine takes; every transition is auditable.

Initiation
Customer request init (DSL rule) tariff {exchange} tariff {transfer} route → before-kyt
Pre-flight booking
gl-batch before-kyt Debit operator current account Credit suspense account call kyt_service
KYT green path
kyt-green ✓ call payment_gateway gl-batch kyt-green Debit suspense → Credit nostro notify email: owt_completed complete ✓
KYT red path
kyt-red ✗ gl-batch reverse notify compliance reversed ✗
KYT hold path
kyt-hold ⏸ suspended — await compliance manual review → kyt-green / kyt-red

Reliable messaging — outbox pattern

Side effects never block the API. Each module writes the side-effect intent into a Postgres outbox row in the same transaction as the state change. A poller fans the outbox into RabbitMQ; corebanq.listener consumes from RabbitMQ and delivers webhooks, runs TOTP workflows, and persists Redis state. If the listener stalls, the API does not.

Outbox
corebanq.api (main) outbox.Publish() · Postgres outbox.main poll → RabbitMQ (AMQP) corebanq.listener consumes webhook · TOTP · Redis

Outbox events — customer_created, signatory_verified, signatory_forms_uploaded, signatory_accepted, document_signed.


/0.9 Data model

Twelve principal entities behind the API

The Postgres schema is normalised around twelve principal entity groups. GORM models map 1:1 to the API response shapes; there is no service-side aggregation layer that could drift from the database.

Customers

B2C / B2B records, KYC status, risk level, signatories, teams.

Accounts

Multi-currency, IBAN, status, balance, statement.

Ledgers

Chart of accounts, entries, balance history, subledger, reconciliation.

Transactions

Inward / outward / internal transfers, events, state machine, ranges.

KYC / KYB

IDV sessions, identity-verification provider records, registry data, risk.

Users & roles

Auth, RBAC, roles, permissions, TOTP audit, session.

Tariffs & FX

Fee structures, spreads, validity periods, FX quotes.

Products & DSL

Product rules history, DSL audit logs, templates.

Recipients

Counterparties, bank accounts, contacts, IBAN validation.

Crypto rails

Merchants, crypto txns, webhooks, setup jobs, fees, refunds.

QES

Signature rooms, signatories, documents, e-signature certificate.

Preferences

User & customer preferences, app config overlay.

Certificate of Registration NQA · UKAS Management Systems
ISO/IEC 27001:2022 Certificate of Registration issued by NQA to Finray Technologies Ltd, certificate number 215646, valid 21 October 2025 to 21 October 2028
Search
Type to search across Finray, products, company, and journal.

    Press Esc to close · to open the highlighted result.

    Book a briefing 01 / 03

    Step 01

    Identify the institution

    Who is requesting the briefing.