Skip to content

Repository files navigation

FINIX — Financial Infrastructure NeXt

Resilient Inclusive Banking Fabric · Team Rexosphere · Duothan 6.0 Phase 2 (REBUILD)

A zero-trust, offline-capable banking platform rebuilt from the ground up: no single point of failure, a cryptographically verifiable ledger, and banking that still works without an internet connection.

This repository implements the architecture submitted in Phase 1 RECON blueprint.


What is this?

FINIX is a hackathon demo banking platform — a serious rebuild of banking for a scenario where a cyberattack has taken traditional systems offline. It is not a single monolith app; it is a mesh of smaller services (identity, accounts, ledger, payments, risk, and more) that keep working under failure, offline conditions, and strict security.

What it shows:

  • Banking that still works offline, on low-data pages, and over USSD (*334#)
  • Strong security: zero-trust, short-lived tokens, master-key recovery only inside an enclave
  • A tamper-evident ledger you can verify was not altered
  • Multiple channels: web PWA, lite page, admin console, USSD simulator

What “running it” means: Docker starts the gateway, databases, Kafka, Keycloak, and the banking services. You then open the web/admin UIs and walk through the demo.

Two ways to start: use our published images (Docker only — fastest for new users), or build everything yourself from this repo if you prefer. Same demo either way — see How to run, then docs/DEMO.md.


The problem

A Super Malware Agent has taken the world's banking systems offline. Customer data survived in backups, but the Master Key that unlocks the banking network is sealed behind security layers. Rebuilding the old monolith would only recreate the same failure: one shared database, one network zone, one compromise away from total collapse.

FINIX is designed as a banking mesh, not a banking app:

Failure in the old system How FINIX answers it
Monolith — one compromise takes everything Independent services, database per service, blast-radius containment
Implicit trust inside the network Zero trust: mTLS everywhere, continuous verification, 5-minute tokens
Master Key held by a single custodian Shamir 3-of-5 split across institutions, reconstructed only inside an enclave
Mutable logs — tampering is undetectable Append-only hash-chained ledger, Merkle-anchored and signed every 60s
100% internet-dependent — excludes rural users Offline-first vouchers, USSD *334#, low-data mode under 50 KB
Classical crypto against a 2065 threat model Post-quantum ML-KEM-768 and ML-DSA-65

Architecture

flowchart TB
    subgraph L1["Layer 1 · Edge Channels"]
        WEB["Web PWA<br/>Next.js"]
        LITE["Low-data<br/>&lt;50KB"]
        USSD["USSD<br/>*334#"]
        POS["ATM / POS"]
    end

    subgraph L2["Layer 2 · Security Edge"]
        GW["Kong API Gateway"]
        IAM["Keycloak IAM<br/>OIDC · MFA · WebAuthn"]
    end

    subgraph L4["Layer 4 · Business Services"]
        IDN["Identity"]
        ACC["Account"]
        ORC["Orchestrator<br/>Saga"]
        LED["Ledger<br/>append-only"]
        VLT["Vault<br/>Shamir 3-of-5"]
        PAY["Payment Hub<br/>Go"]
        RSK["Risk AI<br/>Python"]
        LOA["Loan"]
        CMP["Compliance"]
        NTF["Notification<br/>Node"]
    end

    subgraph L5["Layer 5 · Data & Events"]
        KFK["Kafka"]
        PG[("PostgreSQL<br/>per service")]
        RDS[("Redis")]
    end

    subgraph L6["Layer 6 · Trust Anchor"]
        ENC["Enclave Runtime<br/>reconstruct-only"]
        ANC["Merkle Anchor<br/>ML-DSA signed"]
    end

    L1 --> GW --> IAM
    GW --> L4
    ORC --> ACC & LED & PAY & RSK
    L4 --> KFK
    L4 --> PG
    IDN --> RDS
    VLT --> ENC
    LED --> ANC
Loading

Six layers, ten services, four languages. The polyglot split is deliberate — see ADR-0001.


Implementation status

This is an in-progress Phase 2 build. The table is the honest state of the repository, not the target architecture.

Milestone Scope Status
M0 Build system, convention plugins, shared kernel, compose skeleton, CI, ADRs ✅ Complete
M1 Identity + auth: Keycloak realm-as-code, PKCE BFF, DPoP, OPA, Vault PKI profile ✅ Complete
M2 Money core: account-service, append-only double-entry ledger + hash chain ✅ Complete
M3 Saga orchestrator, transactional outbox → Redpanda, AsyncAPI, chaos script ✅ Complete
M4 Vault: Shamir + Feldman VSS, custodians, enclave, ceremony UI ✅ Complete
M5 Merkle anchor, proof API, in-browser verification, tamper demo ✅ Complete
M6 PWA, offline vouchers, USSD gateway, /lite under 50 KB ✅ Complete
M7 Risk AI, adaptive step-up auth, service quarantine ✅ Complete
M8 Payment Hub, loans, compliance, notifications, admin console ✅ Complete
M9 Full QA suite, load/chaos/DR evidence, user guide ✅ Complete

What works today

M0–M9 are in tree. JVM modules pass ./gradlew verify; polyglot edges have their own tests:

  • shared-kernel — Money, JCS, Merkle, PQC, outbox, DPoP, OAuth2 resource-server defaults
  • identity-service — profiles, devices, login-risk scoring, PKCE authorize/token BFF cookies
  • account-service — open/list accounts, reserve/commit/release holds, seed personas, offline voucher register/reconcile + double-spend quarantine
  • ledger-service — balanced double-entry journals, SHA-256 hash chain, append-only DB triggers, /verify, ML-DSA Merkle anchors + proof + tamper demo
  • transaction-orchestrator — internal-transfer saga with risk gating (allow / AWAITING_STEP_UP / BLOCKED) + compensation + outbox events
  • vault-service — Shamir 3-of-5 + Feldman VSS, hybrid-sealed custodian shards, ceremony workflow
  • enclave-runtime — attestation, reconstruct-only path with key zeroing
  • ussd-gateway — Africa's Talking POST /ussd for *334# (balance, send, mini-statement, language) with Redis sessions
  • risk-ai-service — IsolationForest + rules (/v1/score), login enrichment, AI Shield quarantine, FedAvg demo; model card in docs/model-card-risk-ai.md
  • loan-service — SME micro-loans with deterministic credit decision + repayment schedule
  • compliance-service — AML/sanctions/SAR cases + party screening + risk-case ingest
  • payment-hub (Go) — LankaPay/Visa/CBDC connectors + ISO 20022 pacs.008
  • notification-service (Node) — SMS/email/push/voice templates in si/ta/en
  • Keycloak SPIinfra/keycloak/spi adaptive authenticator calls identity /login-risk
  • apps/web — offline PWA, USSD simulator, zero-JS /lite.html (<50 KB CI budget), ledger verify
  • apps/admin — ops console: ceremony, risk/shield, compliance, loans, payments, notifications
  • docsUSER-GUIDE, FIDELITY-MATRIX, DEMO, QA + runbooks
  • infra — compose core profile wires the full demo stack

How to run

Pick one path — both end in the same running demo.

Path Who it’s for Needs Command
Use published images New users, judges, quick try Docker only make demo-pull
Build yourself Contributors, offline/air-gapped, prefer source Docker + JDK 21 make demo
git clone https://github.com/Rexosphere/finix.git
cd finix

Use published images (recommended for new users)

No local Gradle build. Images are published to GHCR on every push to master / main (ghcr.io/rexosphere/finix/<service>:latest):

make demo-pull

That pulls the images, starts the stack, waits until healthy, seeds personas, and prints URLs. Then open the links below and follow docs/DEMO.md.

URL What
http://localhost:3000 Web PWA / lite / USSD simulator
http://localhost:3001 Admin / vault ceremony
http://localhost:8081 Keycloak (admin / admin)

Demo logins (password Finix!2026 for all): farmer@finix.lk, sme@finix.lk, elder@finix.lk, regulator@finix.lk.

Pin a specific commit build:

FINIX_IMAGE_TAG=sha-<shortsha> make demo-pull

If docker pull fails with unauthorized, make the GHCR packages public (org settings), or docker login ghcr.io with a PAT that can read packages.

Build yourself (optional)

Prefer not to pull prebuilt images? Build and run from this repository instead — same stack, same seed data, same URLs:

make demo

Needs Docker and JDK 21.

Useful Make targets

Command What it does
make demo-pull Pull GHCR images, start, wait healthy, seed, print URLs
make demo Build locally, start, wait healthy, seed, print URLs
make up-pull Pull + start only (no wait/seed)
make up Start with local image build (no wait/seed)
make seed Seed personas into a running stack
make logs Tail compose logs
make down Stop the stack and remove volumes

Local build / tests only

Requires JDK 21. The Gradle wrapper is pinned to a verified SHA-256 — nothing else to install for compile/unit tests.

./gradlew verify                 # full local gate (compile + tests + coverage + detekt)
./gradlew :shared-kernel:test    # tests only
./gradlew detekt                 # static analysis only
./gradlew integrationTest        # Testcontainers suites (requires Docker)

verify runs the full local gate across every module: compile, unit and property tests, static analysis, and the coverage threshold.

Integration tests start real PostgreSQL, Kafka and Keycloak containers, so they need a running Docker daemon. They are a separate source set and are deliberately excluded from check, so the main gate stays runnable without Docker.


Repository layout

finix/
├── services/
│   ├── build-logic/      Gradle convention plugins — one build contract for every service
│   └── shared-kernel/    Money, canonical JSON, Merkle, post-quantum crypto
├── config/detekt/        Static analysis ruleset
├── docs/adr/             Architecture decision records
└── gradle/               Version catalog + pinned wrapper

Services are auto-discovered: any directory under services/ with a build.gradle.kts is included in the build, so a new service can never be silently left out of ./gradlew verify.


Quality gates

Every gate below runs as part of ./gradlew verify and blocks a failing build.

Gate Threshold
Kotlin compiler Warnings are errors
detekt Zero issues against config/detekt/detekt.yml
Line coverage ≥ 80%, scoped to domain / application / crypto
Branch coverage ≥ 70%, same scope

Coverage is scoped to the hexagon interior on purpose. Adapters are covered by integration tests instead, so a single repository-wide percentage would flatter the number without meaning much.

The gates earn their place — while the kernel was being written they caught two real defects: default-locale number formatting, which would have made ledger hashes differ between machines, and an off-by-one in the ECMAScript exponent boundary, cross-checked against Node.


Documentation

Key decisions so far:

ADR Decision
0001 Faithful Spring Boot 3 + Kotlin core, polyglot at the edges
0002 Gradle native platform() BOM over io.spring.dependency-management
0003 Logical database-per-service by default, physical under a profile
0004 ML-DSA-65 anchor signatures instead of BLS aggregation

ADR-0004 is worth reading as a statement of intent: the blueprint promised BLS aggregation, but BouncyCastle ships no BLS provider and BLS is not post-quantum secure, so it would have contradicted the blueprint's own security requirements. It is recorded as not implemented rather than quietly claimed. Anything FINIX cannot deliver honestly is documented, not dressed up.


Tech stack

Layer Choice
Core services Kotlin 2.3 · Spring Boot 3.5 · JDK 21 (virtual threads)
Payment Hub Go
Risk / AI Python · FastAPI
Notifications Node.js
Web Next.js · TypeScript · Tailwind
Data PostgreSQL per service · Redis · Kafka
Identity Keycloak — OIDC, WebAuthn, TOTP
Crypto BouncyCastle — ML-KEM-768, ML-DSA-65, SHA-256
Build Gradle 9.6 · convention plugins · version catalog
Quality detekt · JaCoCo · Kotest · Testcontainers · ArchUnit

Team Rexosphere

Member GitHub
Sangeeth Kariyapperuma @NipunSGeeTH
Kalana Liyanage @Kalana-Pankaja
Ifaz Ikram @Ifaz-Ikram
Suhas Dissanayake @SuhasDissa

Built for Duothan 6.0 · IEEE Student Branch of NSBM

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages