Accueil / Blog / Governance and AI

Governance and AI

Your AI agents see exactly what the user is allowed to see

An AI agent that queries your data needs an account to connect. In most setups we see, that account is single, technical, and broad. Every agent, every user, every prompt then reads with the same rights. The question “may this user see this column?” is no longer asked of the data engine; it is delegated, silently, to the language model and its system prompt.

We think that is the wrong place to ask it. akko-mcp-trino, our MCP server for Trino, puts the question back where it has always been decided: in the engine, under the identity of the person the agent works for.

The problem, concretely

Take a customer table with an e-mail column, a country filter for analysts and a mask on e-mails for everyone but administrators. Your BI tool honours it. Your notebooks honour it. Your SQL clients honour it, because Trino asks OPA or Ranger before every read, and those engines know the user.

Now plug in an agent with a technical account. The country filter is gone. The mask is gone. What replaces them is a sentence in a system prompt telling the model not to show e-mails. One prompt injection, one insistent user, or simply a model misreading an instruction, and the whole table walks out.

This is not a model problem. It is an identity problem: the engine no longer knows who it is working for.

What akko-mcp-trino does

On every tool call, the server receives the user’s token, the one your identity provider issued when they logged in. It verifies the signature against the provider’s public keys, the issuer, the audience, the expiry. Then the query runs in Trino under that person’s identity.

MCP hostCursor, Claude, VS Code, an agentIdentity providerOIDC, JWKSakko-mcp-trinoverifies token, carries identityTrinoruns under the identityPolicy engineOPA, Ranger, built-inData sources1. login2. tool call + identityverifies the signature3. SQL under the identity4. may theyread this?5. rows filtered,columns masked6. result

From there, nothing new happens, and that is the whole point. Trino asks its policy engine as it does for any client. The country filter applies. The mask applies. The catalog scope applies. The agent receives what the user would have obtained by typing the query themselves.

The server never decides access. It does not know your rules, and does not want to. Putting policy in a middle server means duplicating it, and one day contradicting it.

Same question, two answers

We ran a Mistral model on this server, with an eighty-line agent exposing the tools to it. Same question, same server, same model, two tokens.

“Give me three customer e-mails with their country”akko-mcp-trinosame server, same SQLTrino + policy enginealice_adminadministratormarie.martin@example.com · FRthomas.devries@example.org · DElea.dubois@example.net · EScarol_analystanalyst, FR scope***@example.com · FR***@example.org · FR***@example.net · FRthe model decided nothing

The model did not know carol was restricted. There was nothing about it in its prompt. It explored the catalog, described the table, wrote the same SQL in both cases, and returned what Trino gave it.

What surrounds it

Carrying identity is not enough to make a server you can expose to agents. A few things we added because we needed them ourselves.

Read-only decided on the syntax tree. A leading-keyword check lets WITH w AS (DELETE FROM t) SELECT 1 through. The server parses the query and refuses a write wherever it sits, CTEs and subqueries included.

Bounds. A row cap, a time budget per query and per tool call; whatever runs past them is cancelled in Trino.

A request id and one audit line per call. The line says who called which tool, with which outcome and for how long. Never the token itself: the line’s structure has no field to hold it.

All of this is in the open source core. In AKKO and ARCHE, the server goes further, with other ways to carry the user’s identity, agent and access management, an audit linked to the engine’s log and the business context of the catalogue.

What the proofs taught us

We do not trust a green unit test suite. Hundreds of tests at one hundred percent coverage are necessary, not sufficient. Three replayable scripts run against a real cluster, Trino behind Keycloak and OPA, without redeploying anything.

The first checks the guards one by one and the two-account demonstration. The second is adversarial: two users on four sessions each, three calls per session, all at once, on both MCP transports; writes, stacked statements, identifier injection, tokens signed by another key, expired tokens, a user header forced by the restricted user. The third has a model drive the server.

The second found a real defect before release. The read-only guard was tested, green, and wrong: it looked at the root node of the tree, and a DELETE inside a CTE went through. Trino then refused it as a syntax error, which is not a protection. The third found another, humbler one: models end their SQL with a semicolon, Trino refuses it, and the agent retried the same query twelve times. The server now strips that semicolon.

Had we released after the unit tests, both defects would have shipped with the code.

Where it installs

Anywhere there is a Trino and an OIDC provider. Trino 351 and later. OPA, Ranger or Trino’s file-based access control to decide. Keycloak, Entra ID, Okta or any provider that publishes a JWKS. One entry in the host’s mcp.json is enough to connect an agent.

The open source core is under the Apache 2.0 licence, at github.com/AKKO-p/akko-mcp-trino. It reads either under an identity the administrator configures, or under each user’s own when Trino trusts the same identity provider: Trino then verifies the person’s token itself. Its documentation describes it.

It installs with pip install akko-mcp-trino.

The documentation gives the guarantees and the details of the proofs.

Why this brick

AKKO builds governed-access bricks for agents, on the engines and directories enterprises already run. This one is the first, and the simplest to explain: the agent brings the identity, the engine decides. The next ones will carry identity from one directory to another, synchronise policies from the catalog, and measure, each with its proofs.

If you run Trino behind Ranger or OPA and want an identity in front of your agents, the server is ready.

Try the open source core

pip install akko-mcp-trino · Core documentation · Source code