The dashboard runs on a small box in my house. I can open it from my phone at a coffee shop, and that same home network has zero open ports. No port forwarding, nothing for a scanner to find. Those two facts sound contradictory. Reconciling them is most of the security story.
The tunnel only dials out
The server is a small Flask app, and it listens on 127.0.0.1 only. It is not exposed to my home network, let alone the internet. So how does a request from your browser reach it?
A Cloudflare Tunnel. A process on my box makes an outbound connection to Cloudflare and holds it open, and Cloudflare forwards requests back down that pipe. The tunnel never accepts an inbound connection. There is no port to forward, no inbound rule on my router, nothing to scan. The dashboard exists at quidxy.com, on Cloudflare's IPs, and never at my home IP.
In front of that sits Cloudflare Access. No Google session, you get redirected to Google to log in. Only one email is on the allowlist, mine. Everyone else bounces at the edge before a request ever reaches the tunnel.
Then the part I care about most: my Flask app does not trust the edge. On every request it re-verifies Cloudflare's signed token against Cloudflare's public keys, checking the audience, the issuer, the expiry, and that the email is mine. If I ever fat-finger an Access policy in Cloudflare's dashboard, the check at my own layer still returns 403. The edge is configured through a web UI. I don't want my data's security resting on me never misclicking a checkbox.
Three keys, three jobs
Most "is it secure" talk is about one wall. The more interesting thing here is that there isn't one key. There are three, and each does exactly one job.
Splitting them is the point, because no single leak is game over. Steal the master key alone and you can decrypt the stored tokens, but you still need my Plaid keys to use them. Steal the Plaid keys alone and you can call Plaid as my app, but you cannot read my accounts without a valid access token, and those are encrypted with a key you don't have. You need two separate secrets, from two separate places, to do real damage.
Where my bank password actually goes
The one place real bank credentials enter the system is not my code. When I connect a bank, Plaid Link opens an iframe hosted on plaid.com, not on quidxy.com. I type my bank username and password into Plaid's iframe. Those credentials never touch my Flask server and never touch Cloudflare.
Plaid authenticates with the bank and hands my browser a short-lived public_token, which is useless to anyone without my client ID and secret. My browser posts that token to the server, the server trades it for a long-lived access token, encrypts it, and stores it. The plaintext token exists in one local variable for the length of that request, then it is garbage-collected. It is never logged, and it never appears in any API response. The browser only ever receives display data: an institution name, an account name, a last-four mask, a balance.
A tripwire for my own mistakes
One small detail I am fond of. Everything at rest depends on that master key. If I ever rotated it without re-encrypting the existing rows, every stored token would silently fail to decrypt, and I might not notice until the dashboard quietly broke.
So the database keeps a fingerprint of the master key. Not the key, a short hash of it. On startup the app compares the running key's fingerprint to the stored one:
Mismatch, and it refuses to start rather than limp along corrupting reads. It is a tripwire, not a lock. It does nothing to an attacker. It stops me from quietly breaking my own data, which, honestly, is the more likely incident.
The weakest link is me
So what is the weakest link? Not the code. The app has a small surface and leans on well-trodden libraries for the hard parts. The weak point is never the math. It is the handling: a secret that has to stay secret, an account that has to stay mine.
That is the uncomfortable truth in most security. The cryptography is rarely the problem. The discipline around the things that unlock it is. So that is where my attention goes, not the strong wall I am proud of, but the boring habits that keep its keys where they belong.
There is more to write about how this thing is built, and I will, just not on a fixed schedule. This was the field note I most wanted to get right.