fintech_devcon 2025 Talk: Securing a Banking Platform's API + UI

16 Sep 2025
Ben Howdle

Ben Howdle

Fractional CTO & Product Advisor
Helping startups build and scale

Securing a Banking System's UI and API

The below was a talk delivered at fintech_devcon in August 2025 in Denver, CO. I've adapted it into the blog post below...

fintech_devcon 2025

I've spent the last several years building fintech products from the ground up. Today, though, I want to talk about something that often gets bolted on far too late: security.

Not security as a checklist. This is about building systems that are secure by design — from the UI all the way to the backend — and doing it in a way that doesn't suck the life out of your product or your team.

And let's be honest: systems are rarely, if ever, 100% secure. Once you accept this sobering fact, you can free yourself to focus on threat prioritisation over straight coverage. What I'll share here is how we made security an invisible but powerful layer in our systems. Not just for compliance, but to genuinely protect users without compromising developer experience… too much.


Who Am I and Why This Talk?

I'm a consultant today, but previously I was CTO of two banking startups — Letter Bank and WorkMade. We built full-stack banking platforms, handling everything from onboarding to internal tools to user-facing dashboards.

That period, roughly from 2019 to 2023, was a crash course in building secure financial systems. And unlike most 2025 talks, this one features absolutely zero AI. It's vintage, if you will.

Across those startups, I spent five years leading engineering teams, deeply involved in every aspect of the product lifecycle. We weren't just shipping features — we were handling real money, real risk, and all the constraints that come with that.

At the first company, I was engineer #1. I laid the foundations — including the security model — and saw firsthand how those early decisions could either set you up for success… or endless pain.

That's the perspective I want to share: not just what we did, but why it mattered, and how it actually played out.


What You'll Hear

This is not theory. It's one giant case study of real production systems with real customers.

There aren't many security talks that get to boast big wins. In this space, positive news is simply the absence of negative incidents. But for context:

  • We passed pen tests.
  • We didn't lose anyone's money.
  • We didn't suffer breaches (no external ones, anyway — more on that later).

So, this is a dump of lessons from five years of paranoid architecture and low-level background anxiety.


fintech_devcon 2025

The Three Big Takeaways

If there are three things I'd love for you to leave with, they're these:

  1. Mask every backend ID. Leaking internals is mostly downside, and concealing them is mostly upside — though it does come at a cost, which I'll get into.
  2. Declarative authorization. Centralise your rules, and bake them into functionality, network, and system layers.
  3. Immutability. For me, security is less about static state and more about narrative. I want to see the why and how events occurred over time, not just the what.

Attack Vectors (or: Don't Build Death Stars with Exhaust Ports)

Whenever I think about system security, I start with a simple question: how can this system be attacked? From which angles, in what ways, by who?

If you're building the Death Star, you don't want to realise too late that you left an exposed exhaust port.

Think about it: this was the Empire's most ambitious engineering project. Unlimited budget. Top talent. Built under Palpatine's iron grip. But even with all that control, they made one critical mistake. They underestimated what a single overlooked vulnerability could do.

And because of that, the whole system collapsed. The Rebel Alliance didn't brute-force their way in. They exploited poor system design.

That's what we're avoiding when we build defensible systems. You can have firewalls, encryption, auth — all the compliance boxes ticked — but if you leave one path exposed through bad assumptions or inconsistent patterns, there's your exhaust port.

Your threat surfaces are everywhere:

  • The UI (a hostile environment with random clicks on random devices).
  • Webhooks (easy target unless hardened).
  • The API (usually the most attacked).
  • And staff (even the best-intentioned human can be phished).

The point: map your attack vectors early. Zoom out. What's exposed? Where's your exhaust port?


Trust Is Paramount

You don't get many chances to lose customer trust — just the one. And it's almost impossible to win back.

We weren't just handling 1s and 0s. We were handling payroll, rent, food. A single bug might mean someone's mortgage doesn't go through.

So yeah, I'd rather lose a little sleep over a false positive alert than wake up to a real incident. Money can move fast, but trust moves incredibly slow.


Tech Stack Choices

The stack we chose shaped how we approached security:

GraphQL

  • Acted as an intent parser: frontend asked for exactly what it needed, and nothing more.
  • Tighter control of sensitive data and a cleaner audit trail.

gRPC

  • Fast, type-safe, schema-first.
  • Perfect for money movement flows where contracts need to be unambiguous.

Etcd

  • Our rock-solid, immutable store.
  • Every permission change, method registration, config update recorded immutably.
  • Effectively an always-on audit ledger.

TypeScript

  • More than DX. Prevented runtime surprises in fintech, where undefined isn't just annoying — it could cost someone real money.

YAML

  • One source of truth for operations and auth rules.
  • Compiled into TypeScript with RBAC baked in.

Events as Communication and Data

We made every meaningful action emit an event. That event became the source of truth and the message. It told the rest of the system what just happened.

That gave us two for the price of one: comms and data. Microservices subscribed to the stream, and it also meant we had an audit trail by default. No extra logging layer, no mystery state.

It's how we debugged things, and how we rebuilt state.


Write vs. Read Split

We split our system into a write path and a read path.

The write path employed pure event-sourcing: every change was a new event written into Etcd's append-only log. That gave us immutability, a single source of truth, and a perfect audit log.

The read path? A cache mirror in PostgreSQL, built by replaying those events. Fast, familiar, easy to query — but not the source of truth.

This let us optimise for different guarantees: strong consistency on the write side, performance on the read side. Yes, that meant eventual consistency, but for most use cases — back-office dashboards, fraud review tooling — that was a fair trade.


Immutability Everywhere

We never removed or rewrote events. Every change was appended as a new event. That gave us a perfect audit log by default.

By encapsulating user context and timestamps in the schema, we never had to guess later. The event itself was the story.

Users weren't static objects. They were event streams: logins, password changes, address updates, permission grants. Like a Git repo, HEAD is useful, but the real truth is the commit history.


Hiding Inner Workings

One of our first principles was not leaking backend internals to the outside world.

That meant no raw database IDs in URLs, no trusting clients to behave, no assumptions that internal structure should be public.

We treated every internal object as something attackers might guess or misuse.

Which brings me to one of my earliest painful lessons: an IDOR (insecure direct object reference) bug where a user could access someone else's account just by pasting their ID into the URL.

I was mortified. We'd built security into the system from day one — but missed this. The fix? Mask every ID.


Masking IDs

Instead of exposing IDs, we generated opaque, short-lived tokens.

The mask was stored in Redis with a TTL, bundled with metadata like the original ID and who owned it. When reversed, it checked against the user's JWT. If it didn't match? Hard stop. Do not pass Go, do not collect $200.

It wasn't free: tokens expired after an hour. That added some friction, but clients refreshed them automatically. Users never noticed, and we gained much tighter boundaries.


Hard Shell, Gooey Center

We designed with a hard shell. GraphQL had zero business logic. Its only job: parse intent and pass data forward.

Execution lived behind the wall in RPC, with schema validation and auth checks baked in. Developers never touched business rules directly — they were enforced centrally, consistently, invisibly.

This let us enforce logging, validation, and permissions in one place, while keeping the developer experience sane.


Declarative Auth with YAML

We defined operations in YAML, with RBAC roles attached. At build time, those were compiled into TypeScript middleware.

That gave us:

  • One source of truth.
  • Easy Git diffs and reviews.
  • Automatic scaffolding for handlers.

Developers never wrote if (isAdmin) again. Security was declarative, boilerplate vanished, and the system enforced intent consistently.


Mistrust as a Principle

We treated every input with suspicion. Every request was validated. Even internal-only endpoints got zero-trust treatment.

It's the same reason NASA applies a 1.4 factor of safety to every bolt. They don't do it because bolts always fail. They do it because the cost of failure is catastrophic.

In fintech, trust is oxygen. Squander it, and it's game over. So we borrowed the principle: not “what's the minimum that works?” but “what's the minimum that doesn't fail?”


fintech_devcon 2025

Closing Principles

To close things out, here are the principles that helped us avoid building Death Stars with exhaust ports:

  • Avoid exposing backend internals. IDs are implementation details, not API design.
  • Bake in validation everywhere. Assume input is wrong until proven otherwise.
  • Prefer events over state. Logs give you the movie, not just the still frame.
  • Prioritise security over raw speed. Users forgive milliseconds; they don't forgive breaches.

Thank You

And that's everything from me. Hopefully there was something useful here — or at least something you'll shamelessly copy-paste into your own systems.

If you want to chat more about security, systems design, or just swap war stories, you can find me online or at the coffee stand.

Thanks again.

Enjoyed this post?

Let's work together to accelerate your product development.