How Do You Let AI Agents Into Regulated Data?
TL;DR: Everyone at a regulated company wants AI agents on the company’s data. Contracts with the AI vendors are step zero, and they took us the longest. But a contract only covers what the vendor does with your data. It says nothing about who on your side can pull what, or whether you can prove it later.
Then there’s the hard part. Cloud agents run on the vendor’s servers, and those servers run agents for every one of the vendor’s customers. So we had to open a door to the vendor’s cloud that only our staff can walk through, not the vendor’s other clients. Allowing the vendor’s IP addresses doesn’t do that, because every customer shares them. What does it: each AI tool gets a secret that only we issue, and each person signs in with their own company account. Anyone else on the same vendor gets nothing.
That part is architecture. Ours is one small gateway, three rules, and a BI tool I set up six years ago for a completely different reason.
The question everyone is asking
I work at a regulated fintech. We hold investor data, payment data, and records a regulator can ask to see. So when people started asking “can the AI just look at our data?”, the answer couldn’t be “sure, here’s a database password.”
And they did ask. Everyone asks now. Finance wants a daily list of failed payments. Ops wants counts. Product wants to know what happened last week. The AI agents are good enough to do this work. The question is how to let them without handing our data to anything that asks.
Step zero: the contracts
Before any code, we needed two promises from every AI vendor we use: zero data retention (ZDR), so the vendor keeps nothing after it answers, and no training on our data.
That sounds like a checkbox. It wasn’t. We contacted each vendor, one at a time. We got the agreements in writing. Then we checked that we were on a plan that actually honors them, because the consumer tier and the enterprise tier of the same product often have different rules. Compliance was involved from the first conversation, not the last. This took far longer than the engineering that came after it.
So if you’re starting down this road, start there. Nothing below matters if the vendor can keep or train on what your agent sees.
But here is what the contracts don’t answer:
- Which of our employees can pull which data through the agent?
- Can someone at another company, using the same AI vendor, reach our systems?
- Six months from now, can we prove who asked for what?
A regulator will ask all three. No vendor agreement answers them. They’re questions about our side of the wire.
The foundation I didn’t know I was building
In 2020 I introduced Metabase at the company. It was meant for dashboards. I set it up so that it connects to our databases only with read-only database users. Metabase groups decide who sees which databases and tables. Metabase logs every query under the name of the person who ran it. And it sat behind our VPN.
For about two years, that was also how our AI reached data. You ran the AI on your own laptop, you connected to the VPN, and the AI talked to Metabase’s MCP server as you. It was safe. It was also stuck on your laptop.
Then the agents moved to the cloud. You use a cloud agent so it can work while your laptop is closed. It runs on the vendor’s servers, and the vendor’s servers will never be on our VPN. The old path couldn’t reach them.
Two obvious answers, both wrong
Obvious answer one: put Metabase on the internet. Metabase has its own login and its own MCP server. Just expose it?
I didn’t trust it at the edge, and I had reasons:
- Metabase’s login would become our only wall. Metabase has had serious vulnerabilities that worked before login. When the login is the only wall, a bug like that is a bad day.
- An MCP login uses a browser page: sign in, then consent. That page must be public. A browser page cannot carry a secret header, so anyone could reach it.
- “Only allow the AI vendor’s IP addresses” sounds like a fix. It isn’t. The vendor’s servers run agents for every customer. Allowing the vendor’s IPs allows every one of them.
- I wanted our own audit trail, in storage we control, that no one can edit. Metabase’s query log is a table in its own database. Someone with enough access can change a table.
Obvious answer two: build our own. Our own query API, our own permission model, our own audit. That’s months of work to rebuild what Metabase already does well, and a second permission model that must always agree with the first. Two permission models will eventually disagree, and you’ll find out at the worst time.
One guarded door
The answer was in between. We built a small gateway. It is the only part that faces the internet. Metabase and the databases stay private. The agent never gets a path into our network. It gets answers from the gateway, and nothing else.
The gateway follows three rules:
- Register every AI client. An AI tool cannot connect until we issue it its own client ID and secret. Each tool gets its own. We can tell tools apart, and we can revoke one without touching the others.
- Every person signs in as themselves. Sign-in uses our company Google account. The gateway then opens a Metabase session as that person. There is no shared service account. The agent sees only what that person can already see in Metabase. When someone leaves the company, their access ends with their account.
- Log before you answer. The gateway writes an audit record before it returns any data. The record goes to WORM storage, which no one can edit or delete, and which we keep for six years under the SEC’s record-keeping rule. If the gateway cannot write the record, the request fails. No data leaves without a log.
A few more choices made it smaller than it sounds:
- We reuse Metabase’s own MCP tools. The gateway passes requests through to Metabase. We wrote no query engine.
- We allow only a short list of tools. Read and query tools pass. Tools that create or change Metabase content do not.
- No raw SQL. An agent cannot run SQL that you write. It builds the request with Metabase’s query builder, as you. This keeps queries inside the permissions Metabase already enforces.
- Limits live in Metabase, per user. Agents query eagerly. Metabase already sets query time limits and rate limits for each user, and it already restricts what each user can access. An agent works as its user, so it gets the same limits. We didn’t build a second set.
- There is a kill switch. Turn off the gateway, or one client’s secret, and AI access stops. People who use Metabase directly are not affected.
Yes, the gateway is new code facing the internet, so it’s the part an attacker will aim at. That’s why it’s thin. It checks the client secret, checks the sign-in, writes the log, and passes the request through. It stores no query results and makes no permission decisions of its own. Metabase still makes those. Every change went through code review before release.
How strong is each layer?
Not all controls are equal, and most writing on this topic ranks them wrong.
| Control | What it stops | Strength |
|---|---|---|
| IP allowlist | Scanners and internet noise | Weak. Other customers of the same AI vendor share those IPs. |
| Client ID + secret | Other companies’ agents | Strong. This is the real boundary between companies. |
| Per-person sign-in | Anyone who isn’t one of our employees, shared logins, people who left | Strongest. |
| Metabase permissions | Access beyond what that person already has | Strong. |
| Read-only database user | Any change to data | Strong. The database enforces it, not a prompt. |
The IP allowlist is still worth having. It removes noise. But if your design depends on it, your design lets in everyone else who uses that vendor.
What it doesn’t solve
I’d rather list these than have you find them.
- Prompt injection through the data. A read-only user stops writes. It does not stop leaks. If your data includes text that outsiders wrote, such as notes, descriptions or messages, an attacker can put instructions in that text, and the agent will read them. An agent with other tools, like web access or email, could be tricked into sending data out through one of them. A gateway cannot see this. It happens inside the agent. The best defenses I know of are keeping free-text fields out of what agents can reach, and not mixing data tools with outbound tools on the same task.
- The vendor holds sign-in tokens. After a person signs in, the AI vendor keeps a token so the agent can work as that person. If the vendor is breached, an attacker could use those tokens. We limit the damage: access tokens expire in minutes, each refresh checks the person’s company account again, everyone signs in fully again every 30 days, and changing one client’s secret ends all of that client’s sessions. The risk gets smaller. It does not go away.
- Agents are faster than people. An agent can pull only what its user can see, but it can pull it much faster than a person clicking through dashboards. Per-user limits and the audit log matter more with agents, not less.
- Every path needs the same rules. A gateway protects only the traffic that goes through it. Find every way an AI tool can reach your data, and give each one the same controls. Don’t claim “all AI access goes through the gateway” until you’ve checked.
- The answer still goes to the vendor. The results an agent reads reach the vendor’s model. That’s what the contracts in step zero are for. Architecture and contracts each cover what the other can’t.
Why it only took two days
The gateway took two days to build and ship. That isn’t because it’s simple. It’s because the hard decisions were made years ago. Read-only database users, per-group permissions, a query log under each person’s name: in 2020 those were just sensible BI hygiene. In 2026 they turned out to be most of an AI security model.
The lesson I’d take from it: choose infrastructure whose controls still hold when the user changes. Our BI tool’s users changed from people to agents, and the controls didn’t have to.
Contracts govern the vendor. Architecture governs access. You need both. If your company is working through the same problem, I’d like to hear which of these layers you kept, and which one you found you didn’t need.
Chase the sources
- SEC Rule 17a-4: the broker-dealer record-keeping rule behind “WORM, six years, no one can edit it”.
- Metabase CVE-2023-38646: a pre-authentication remote-code-execution bug from 2023. It’s why the login page was never going to be our only wall. (Also CVE-2021-41277, a pre-auth file read.)
- The MCP authorization spec: how MCP clients sign in with OAuth, and why the consent page has to be public.
- What Makes a Good MCP Tool Surface for an LLM: why a short tool allowlist is a feature, not a limitation.
- One MCP Server, All Your HubSpot Portals: the same instinct at a smaller scale. Put the safety in what the system can’t do.
Comments
Sign in with GitHub to comment. Or just say hi on GitHub.