We Built Bank-Grade Security for Immigrants. Here’s What Broke First.
Picture this: You just landed in the US. You’ve got a job, a signed lease, and your phone. But you have zero credit history. No SSN yet. And absolutely nobody is walking you through this financial maze.
A coworker swears by this finance app, so you download it. You try linking your bank. It fails. The error message is in English. There’s no clear retry path. You close the app.
You’re done. Probably for good.
That isn’t just bad UX. That is the whole architecture crumbling. And it’s exactly the failure we set out to fix at YPA Finance.
We’re building a multilingual AI finance platform for the 45 million immigrants grinding in the US — people who are financially responsible and get completely ghosted by the products that claim to serve them. When we started, I figured this would be a design and product challenge. I was wrong. It’s security and infrastructure first. Those early technical choices are what decide if someone trusts you enough to stay, or quietly bails forever.
Here’s what I figured out along the way.
Why regular fintech screws this up (and it’s not a mystery)
The industry is built for a “default” user who simply doesn’t exist for the people we’re building for.
Onboarding is almost always tied to SSNs. Identity checks are trained on US-born people with deep credit files. When the data doesn’t match? The system rejects them, usually silently, with no backup plan and no second chance. No graceful fallback. Just a wall.
Then there’s what I call the language of logic. Error handling assumes you’re a native English speaker who already knows what a routing number is. If Plaid fails, you get a code. That code maps to a message that means nothing if the financial system isn’t something you grew up inside of. For a huge chunk of our potential users, this isn’t an edge case. It is the default experience.
Nobody designed it to be cruel. But the effect is the same.
What “bank-grade” actually means for a startup
“Bank-grade” doesn’t mean having an enterprise budget. It means making the right calls on day one and refusing to negotiate on the things that can’t be undone.
We run on GCP, with everything in GKE. Secrets live in Secret Manager — no environment variables, no config files floating around in commits, nothing that can leak by accident. We use Workload Identity Federation instead of service account keys. No long-lived keys means nothing to steal, nothing to rotate at 2am when you’re half asleep.
Encryption isn’t a checkbox: it’s the starting point. We store nothing we don’t need. Before I wrote a single line of app code, I drew a hard line: no raw card numbers, no SSNs in plaintext, no bank credentials touching our system at all. Your data model is your biggest security liability. Period. If you never store it, you never have to protect it.
Least privilege is baked into IAM. Services get exactly what they need and nothing more. This isn’t about distrusting the team. It’s about moving security from “shared vibes” to enforceable policy.
Making bank-linking work for people it wasn’t built for
Plaid is a great tool. It’s also built for people who already speak the language of personal finance. Bridging that gap was one of the harder problems we’ve had to solve.
Consent. Those OAuth permission screens are jargon city. “This application will access your transaction history” sounds fine in English. In Spanish or Tagalog, to someone who already has reason to distrust financial institutions, it sounds like a trap. We localise our copy, not just translate the words, but rewrite the meaning for context. There’s a real difference between the two, and users can feel it.
Failure handling. When Plaid returns an error code: bad credentials, unsupported institution, session timeout, we translate that into a plain-language explanation with a specific next step. No “something went wrong, please try again.” That isn’t a next step, it’s a dead end. For someone already approaching this with suspicion, an unexplained failure doesn’t just lose the session. It confirms everything they feared.
We also integrated Array for credit data. Surfacing a FICO score to someone who has never had credit explained to them is a real responsibility. We treat it that way — simple language, in their language, with clear context about what the number means and what it doesn’t.
Every screen is an opportunity to either earn trust or blow it. We design for earning it.
What I got wrong: three assumptions, three stages
I over-trusted the partners.
Plaid, Stripe, Array: well-documented, well-regarded, genuinely good. I assumed that choosing the right partners would cover most of our security posture. It doesn’t work like that. They own their piece. The glue code in between your API surface, session management, cookie flags, logging, that is all on you. Nobody is auditing that for you.
I ended up reviewing our own code much harder than I expected to. Not because the partners let me down, but because I’d misunderstood what they were responsible for in the first place.
I assumed documentation was enough.
I have a great team, careful developers who take quality seriously. I documented the architecture, laid out the principles, and assumed they’d apply consistently. They did most of the time. But “most of the time” isn’t good enough in security. Security constraints that live in a doc are suggestions. A CI scan is a constraint. We moved to explicit tickets: “Fix line 76 in auth/session.ts here’s why this matters.” That shift turned shared principles into unbreakable system habits.
Microservices multiplied the surface.
We went micro for the right reasons: deployment independence, scaling, cleaner team boundaries. What I underestimated was that every service boundary is also a security boundary. One surface to harden became thirteen. The architecture is still the right call, but the security overhead needs to be planned for from the start, not retrofitted later.
Three rules for any CTO building financial infrastructure for underserved users
Rule out storage before you write a single line of product code. Your data model is your biggest security decision. The moment you store a credential or an SSN, you own that risk permanently. Design around what you refuse to hold. It limits your blast radius if something ever goes sideways and in fintech, something always eventually does.
Give your team system-level support, not just principles. Even the most careful engineers need a system that backs them up. Automated scanning, review gates, linting with teeth. “Be security-minded” produces good intentions. “Here’s the CI check that blocks the merge” produces a fix.
Move fast on infrastructure, but slow on access. Workload Identity over service account keys. Secret Manager over environment variables. IAM reviewed before deployment, not after. The friction of doing it right upfront is a fraction of the cost of rotating compromised credentials in production while customers are watching.
The bigger point
The 45 million immigrants in the US aren’t an edge case. They’re a stress test for every lazy assumption baked into financial architecture — that your user has a credit history, speaks English fluently, and already understands how the game works.
Building for them didn’t make our system more complicated. It made it more honest. The security decisions I made because of them: no long-lived credentials, explicit consent flows, localised error handling, strict data minimisation are the same decisions I’d recommend to any engineer touching financial data, for any audience.
The difference is that for the people we build for, a technical failure isn’t just an inconvenience. It’s confirmation of something they’ve already been told too many times: that this system wasn’t built for them.
We’re building the system that should have existed all along.