A national student-lending platform, built end to end on a bank-grade core.
A complete student-lending platform (námslán) for an Icelandic lender, built on a bank-grade core. National electronic-ID onboarding and legally binding loan signing, the full Íslandsbanki claims-and-reconciliation money pipeline, indexed (verðtryggð) loan mathematics with EU-directive APR, automated Icelandic legal document generation, and a regulator-ready audit trail, all engineered in house.
A fully shipped student-lending platform. Detailed architecture and references available on request.
- A complete national student-loan platform, application, underwriting review, disbursement and repayment, on a bank-grade core
- National eID login and hash-bound loan e-signing over Signet, with KYC/AML gating
- The full money pipeline: Íslandsbanki claims, automated reconciliation, and a balanced double-entry ledger
- Indexed (verðtrygging) loan mathematics with EU-directive APR, on a private Azure landing zone defined in Bicep
A system of systems.
Brúa is not one product but a connected platform of purpose-built systems, each engineered to do one job exceptionally well.
Icelandic eID Identity Gateway
Built for a regulated lender, the Identity Gateway runs fully isolated trust domains, borrower and staff, each on its own httpOnly cookie and JWT secret, so the portals can share a domain without ever colliding or cross-authenticating. Borrowers sign in with native Icelandic electronic identity, Smart-ID and the Audkennisapp, plus Rafraen skilriki phone eID through the shared Signet library, which resolves the real person at the source, then matches them to an account by kennitala before issuing a session. Every borrower session is server-side revocable and database-backed, so the JWT strategy re-checks each request against a live sessions table and a single logout instantly invalidates the token, while staff sessions run on a separate short-lived secret. The whole system refuses to even boot unless its JWT secrets are present and rotated away from known defaults, and tokens are written straight into hardened SameSite cookies so the raw credential never reaches browser-readable storage. Login, SMS, and registration endpoints are individually rate-limited, with every privileged authentication event written to an immutable audit trail.
Lanaskjal Signing Vault
Before a borrower can be bound to a loan, the Lanaskjal Signing Vault freezes the exact contract they see: it generates the loan document once from the confirmed terms, SHA-256 hashes the precise bytes, and persists them as an immutable, idempotent record so the hash never drifts across retries or double-clicks. Those frozen bytes are dispatched to Signet's V3 eID service over a mutual-TLS channel, credentials and the client certificate ride inside the request body and are never logged, and a single borrower-signer ceremony is opened against the document. A scheduled reconciler polls every five minutes, and the moment Signet reports the document signed it pulls back the sealed PDF, re-hashes it, and stores the signed bytes, the signer's certificate, and their kennitala alongside the original bound hash. The payoff is a true non-repudiation gate rather than a UI gesture: loan confirmation can be forced to verify, server-side, that a completed signature exists for this loan, bound to this exact document hash and this exact signer, closing the legal gap where a confirmed loan once carried no proof of what the borrower actually agreed to.
Krafa Ledger
Wired straight into Iceland's banking rails, the Krafa Ledger turns every loan installment into a registered Islandsbanki claim (krafa) and owns its money from issue to settlement, generating claims idempotently against a deterministic reference, business-day-shifting each due, create and final-date around a holiday-aware Icelandic calendar, then transmitting them through a .NET WS-Security SOAP sidecar while it fail-fasts on an unconfirmed bank number rather than mis-route a single payment. A daily poll-and-reconcile loop pulls received payments over a rolling window and matches each back to its claim by krofunumer, including superseded numbers carried across a postpone, so an in-flight payment on a replaced claim is still applied rather than silently dropped. Every matched payment is split through a regulatory waterfall, interest, then fees, then indexation, then principal, cascaded across the loan's open installments so overpayments roll forward instead of vanishing, and committed in one transaction that advances the installment, claim and loan status together. The whole pipeline is idempotent end to end: claims are unique on their reference, repayments are deduplicated by occurrence-count and external reference, and re-reads of the same payment feed resolve to a safe no-op, with cancel, postpone and write-off all auditable from the admin console.
Brúa API Gateway with Postgres Row-Level Security
Sitting in front of Iceland's student-lending core, the Brúa API gateway authenticates every request at the edge with a swappable bearer verifier, RS256 via Entra ID / Auth0 JWKS in production, an HS256 shared secret for dev and tests, then translates the verified token into database-enforced trust. Rather than relying on hand-written WHERE clauses, each operation runs inside a transaction that issues SET LOCAL ROLE brua_app and projects the caller's identity into Postgres as app.is_staff, app.user_id, and app.actor session settings, so the V1 row-level-security policies decide what every query can see; a borrower's token can only ever read their own loans, even if a route forgets to filter. From that secured context the gateway fans out to the billing, payments, and indexation modules, schedule generation, claims runs, monthly indexation, and idempotency-keyed repayments, exposing them as a clean Fastify 5 surface with Zod-validated inputs and a consistent error envelope. A separate inbound lane handles Íslandsbanki webhooks without bearer tokens, verifying an HMAC-SHA256 signature over the raw body with constant-time comparison before recording and reconciling each event in one transaction. The result is a least-privilege gateway where authorization is proven by the database itself, not just asserted by application code.
Audit & Compliance Trail
Every privileged action across Brúa writes an immutable record to an append-only audit ledger before it leaves the building, borrower and staff logins (including failed admin attempts), the full loan lifecycle of confirm, cancel, payment and auto-reject, and every staff override on disbursements and borrower records. Each entry is a parameterised, UUID-keyed row carrying a dot-namespaced action, typed actor, target, structured JSONB metadata, and the caller's IP and user-agent resolved from forwarded headers, written through a service that, by design, never throws: a failed audit write is logged at error level but is physically incapable of breaking the operation it records. A guarded admin viewer reads the trail back through indexed, paginated queries filterable by action, actor and target, while a daily retention cron enforces the storage-limitation principle, purging records past a configurable horizon that defaults to five years, the window mapped to Iceland's GDPR (Act No. 90/2018) accountability duty and AML (Act No. 140/2018) record-keeping. The result is a tamper-evident, regulator-ready account of who did what, from where, and when, without ever putting a single privileged transaction at risk.
KYC & AML Onboarding Gateway
Built to Iceland's AML obligations, the KYC & AML Onboarding Gateway stands between sign-up and any credit activity: every new user must clear a structured questionnaire covering PEP status, terrorism-financing exposure, sanctions-list membership, employment, housing, income band, and a signed accuracy declaration before the account unlocks. Sanctions and terrorism-financing answers act as hard stops, rejected first at the client and then re-enforced server-side, so a positive flag on either question fails the application identically whether it arrives through registration or a later submission. Completed responses are upserted into a one-row-per-user record and surfaced back as a single submitted flag that the app's auth guard uses to fence off the entire dashboard, redirecting anyone without a record straight back to the questionnaire. Profile self-service is deliberately scoped: users can edit email, address, and postcode through a validated settings form, while identity-defining fields like kennitala, name, and phone stay read-only, preserving the integrity of the AML record behind the account.
Azure Infrastructure (Bicep landing zone)
The entire platform runs on a private, compliance-ready Azure landing zone defined end to end in Bicep, so a regulated lender's whole footprint is reproducible from code. A main template fans out to focused modules, network and private DNS, Container Apps environment and per-app workloads, a scheduled cron Job, a private Postgres Flexible Server, Key Vault, Container Registry, Blob storage, Log Analytics, customer-managed-key encryption, and a Front Door Premium with WAF, wired into a single VNet with private endpoints so Postgres and storage never touch the public internet. Secrets live in Key Vault, data is sealed with customer-managed keys, and the public edge is fronted by Front Door + WAF, while staging and production are driven from parameter files rather than hand-edits. The whole foundation and its phased workload deploy are provisioned through GitHub Actions using OIDC federated identity, so there are no long-lived cloud credentials anywhere in the pipeline.
Transactional Outbox Relay
Built to close the gap between Brúa's loan-claim ledger and the bank, the Transactional Outbox Relay turns a two-system write that cannot share a transaction into a single safe one: billing records the bank-call intent in outbox_events in the same transaction as the claim, and this worker delivers it. Each drain claims a batch with SELECT … FOR UPDATE SKIP LOCKED, gated on next_attempt_at <= now(), so any number of relay workers can run side by side without ever grabbing the same row twice. Delivery is at-least-once and idempotent on a deterministic claimReference, so a crash before commit can only ever re-send, never double-charge; transient failures are rescheduled with capped exponential backoff (1m, 2m, 4m … up to 1h) and events that exhaust their retries are parked as failed for a human rather than lost or retried forever. The loop honours SIGINT/SIGTERM through an AbortController for graceful shutdown mid-tick, and an end-to-end integration test proves all four paths against the live V1 schema, delivered, backed-off, exhausted, and not-yet-due, before rolling back.
Canonical Loan-Math Engine
At the centre of Brúa's platform sits the Canonical Loan-Math Engine, a single source of truth that resolves every króna a borrower is quoted, and therefore contractually owes, from one shared package. It runs two purpose-built engines side by side: a non-indexed annuity engine that compounds interest monthly across multi-disbursement study and grace periods, and a CPI-indexed (verðtryggður) engine that capitalises geometric inflation into principal and grows each payment by the accumulated index factor. Origination fees, per-disbursement documentation fees and monthly admin fees are modelled explicitly and folded into full amortisation schedules, while the effective annual rate (ÁHK) is solved by Newton-Raphson IRR over real cash-flow dates, exactly as the EU Consumer Credit Directive 2008/48/EC prescribes. Because the same code powers both the customer-facing quote and the admin review screens, the engine deliberately keeps the legacy admin simple-interest variant as a distinct export, and a Vitest regression suite pins both against hand-derived textbook annuity fixtures, asserting clean amortisation, monotonic balances and the precise, documented gap between the two so no silent drift can ever reach a borrower.
Verðtrygging Indexation Engine
Wired straight into Iceland's CPI series, the Indexation Engine applies monthly verðtrygging at the source, reading the registered index for the month, deriving the period rate against each loan's last applied CPI (or its base index), and indexing the outstanding balance accordingly. Where the legacy job merely scaled every future installment by the rate, freezing the principal/interest split and quietly drifting tax-deductible-interest reporting, this engine recomputes the textbook annuity on the indexed balance, so each installment's interest is charged on the current balance and the schedule amortizes exactly to zero. Every run writes a full audit trail: a loan-level indexation record, per-installment verðbætur rows, an updated indexed principal and last-indexation date, and a balanced double-entry ledger posting that debits principal-receivable and credits indexation income. It is idempotent by design, unique per loan and month, so a re-run is safely skipped, and never retroactive, indexing a loan only for months it had already started in. The whole operation runs inside a single Postgres transaction under a staff RLS context, so it either lands completely or not at all.
Allocation & Double-Entry Ledger Engine
When money lands against a student loan, the Allocation Engine resolves exactly where it goes, splitting every repayment across an installment's components through a deterministic waterfall (interest, then fees, then indexation, then principal) that fills earlier buckets first on underpayments and surfaces any overpayment as a leftover, all to half-eyrir precision. Each repayment cascades through the loan in one atomic transaction: the installment flips to partially_paid or paid, its bank claim follows, and the loan itself is marked paid_off the moment its last installment clears. Inbound bank webhooks are reconciled through a locking inbox that acts only on still-received events and stamps them processed in the same transaction, so a re-delivered claim.paid is a guaranteed no-op rather than a double charge. Beneath the allocation layer sits a double-entry ledger that is balanced by construction, every payment posts a single Cash debit against credits to principal-receivable and interest, indexation, and fee income that always sum to the cash received, with a deferred database trigger enforcing equal debits and credits at commit. The full path, webhook to repayment to allocation to status transitions to a balanced ledger, plus proven idempotency on re-delivery, is exercised end-to-end against the live schema.
Skuldabréf Document Compiler
Built for Brúa's student-lending workflow, the Skuldabréf Document Compiler turns a single loan application into a complete, legally formatted Icelandic credit pack, skuldabréf, lánasamningur, repayment schedule, and the standardized consumer-credit disclosure (staðlaðar upplýsingar um neytendalán), rendered through a Jinja-to-LaTeX pipeline with custom delimiters and full special-character escaping so Icelandic legal text never breaks the typesetter. It calculates the loan at source: building principal from each disbursement with origination and disbursement fees, generating an annuity amortization schedule, and selecting the indexed (verðtryggt) or non-indexed (óverðtryggt) contract template automatically, pulling live REIBOR from Seðlabanki and a ten-year average CPI inflation rate from Hagstofa, with caching and sane fallbacks when the registries are unreachable. Every krónu amount is rendered both as digits and spelled out in correct Icelandic legal words, rounded once so the numeric and written figures always agree to the last króna. The service compiles each document twice with pdflatex for stable tables and references, compresses the result with Ghostscript before handing it to the Signet e-signing API, and exposes a schedule-generation endpoint that writes the full installment plan and business-day-aligned payment claims straight into the loan database.
Brúa Operations Console
The Brúa Operations Console is the staff command centre that runs an Icelandic student loan from application to final repayment, wiring every step of the lifecycle into one Next.js back-office. Caseworkers triage applications, generate contracts through the document-compiler pipeline, and dispatch them for legally binding e-signature over Signet's v3 API using a mutual-TLS client certificate and Auðkenni app, SmartID, or direct-device signing flows. The moment a signature webhook fires, the console activates the pending loan, books disbursements at the exact fees the borrower was quoted, generates the repayment schedule, and emits payment claims pre-dated to Iceland's T-3/T-2 banking calendar, then reconciles every króna against Íslandsbanki through one-click full bank syncs. For indexed loans it tracks verðtrygging continuously, recomputing principal against Hagstofa CPI data and surfacing the full rate, indexation, and consumer-price history per loan. Above it all sits a portfolio analytics and customer layer reading across both the Postgres core and the Azure bridge, with every admin route fenced behind cryptographically verified JWT sessions and fail-closed cron and service guards.
Let's build something exceptional.
Tell us your ambition and we will show you exactly what is possible, with a precise plan, a clear quote, and a team that delivers at speed.