For business For enterprise Solutions Apps Pricing Developers Blog Docs Launch a workspace
Blog / AI agents for operations

How to give an AI agent access to business data safely

For technical founders and the finance leads who sign off on them. The architecture that makes agent access safe, the five controls and where each lives, what the protocol and the major agent vendors require, and a checklist to run against any system.

8 min readUpdated September 4, 2026Sois engineering, the team that builds the platform

A small server room seen through a glass door: one rack with tidy cabling, a key safe on the wall, a clipboard on a hook, cool blue light
Short answer

The safe way to give AI agent access to business data is to make the agent a client of the business system rather than a user with a password. The agent connects as a named person over a standard sign-in, is offered only the tools that person's role allows, has every call checked again by the system when it runs, is capped on what it can spend, and leaves a log of every action attributed to that person. When any of those checks cannot be made, access is denied rather than assumed.

None of that lives in the prompt. Instructions to the model are useful for behaviour and useless for security, because the model can be argued out of them by a document it reads. The controls have to be enforced by the system holding the data, on every call, regardless of what the agent believes it has been told.

The architecture: the agent is a client, the system is the authority

Start with the shape, because most of the mistakes are shape mistakes. A person asks their agent for something. The agent decides which tools to call. Every call passes through a permission layer that belongs to the business system, not to the agent, and only then reaches a module such as finance or CRM. The agent never touches the database, never holds a database credential, and never sees a tool its person could not use.

You
Your agent
Sois permission layer
FinanceCRMHRDocuments

The request passes from the person to their agent, then through the permission layer, before it reaches any module. The layer filters what the agent is offered and checks what it calls. The agent can only use the tools its person is allowed to use, on the records its person can see.

The principle underneath the picture is one sentence: the agent acts with the authority of the person it represents, and never more. Everything else in this article is a way of making that sentence true under pressure, when the model is wrong, when a document it reads contains instructions, or when a token leaks.

The OWASP Top 10 for LLM applications names the failure this architecture prevents: excessive agency, which it breaks down into excessive functionality (tools beyond what the job needs), excessive permissions (more access downstream than necessary) and excessive autonomy (no independent check before a high-impact action). Its mitigations read like a specification for the permission layer: execute in the user's context, minimise the tools and their permissions, enforce authorisation in the downstream system rather than relying on the model, and require a person's approval for high-impact actions.

Five controls, and where each one lives

The controls are not new; they are the controls you already apply to a person with system access, applied to a client that acts for that person. The table says what each answers, where it is enforced, and what failure looks like when it is missing. The location column is the important one. A control enforced in the prompt is a suggestion.

ControlWhat it settlesEnforced whereFailure when missing
IdentityWho the agent is acting forSign-in over OAuth; a token issued for this system and bound to a named userShared service accounts; actions with no owner; a leaked key that works for everyone
ScopeWhat it is allowed to doTools filtered by the person's role before they are offered, and checked again on every callAn agent that can read payroll because its person once needed a contact's phone number
BudgetHow much it can consumeA spend cap per integration on the system's own AI; rate limits on tool callsA badly stated task that runs all night; an unbounded bill
LogsWhat it did, with what, and what happenedEvery call recorded with inputs and result, attributed to the personNo way to review, reverse or explain an action after the fact
Fail closedWhat happens when a check cannot be madeDeny, with an error the agent can reportAmbiguity resolved in the agent's favour; the model deciding its own authority
Confirmation on writesWhether a person sees it before it happensThe client asks before consequential actions; the system marks which tools are consequentialMoney sent, records deleted or messages posted on the strength of a misread instruction

Six rows for five controls plus the one the agent clients themselves provide. Five of the six are enforced by the business system or the client, and none by the model.

Identity: connect as a person, over OAuth, never with a shared key

The Model Context Protocol's authorisation specification is precise about this. A remote server acts as an OAuth 2.1 resource server; the client obtains a token through a standard authorisation flow with PKCE; the client must state which server the token is for using the resource parameter; and the server must validate that each token was issued for it specifically, rejecting anything else. The specification explicitly forbids token passthrough, where a server accepts a token it did not issue and forwards it downstream, because it destroys both the audit trail and the trust boundary.

In practice this is what "sign in once, no token to paste" means. The person adds the workspace address to their agent, is sent to a normal sign-in page, approves the connection, and the agent receives a token that names them and works only against that workspace. Anthropic's guidance for custom connectors in Claude is to review the scopes a server requests, limit them where possible, and connect only to servers you trust. A vendor that instead asks you to paste a company-wide API key into an agent configuration has skipped the first control and made the other four much harder.

Scope: filter before offering, check again when running

An agent discovers what it can do by asking the server for its tool list. The right design answers that question per person: the list a bookkeeper's agent receives is different from the list a director's agent receives, and neither includes tools for modules their role cannot see. This is the OWASP advice to minimise functionality made concrete, and it has a second benefit: a model that is never shown a tool cannot be argued into calling it.

Filtering the list is not enough on its own, because roles change, sessions persist, and clients cache. The same check has to run again when each call arrives, against the person's permissions at that moment. Below is a tools list in the shape the protocol defines, for a role that can read invoices but not record payments. The absent tool is the point.

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "tools": [
      { "name": "searchInvoices",
        "description": "Search invoices by number, reference, contact, amount, status, date range.",
        "inputSchema": { "type": "object", "properties": { "query": { "type": "string" }, "outstanding_only": { "type": "boolean" } } },
        "annotations": { "readOnlyHint": true } },
      { "name": "getInvoice",
        "description": "Read one invoice in full: status, totals, dates, contact and lines.",
        "inputSchema": { "type": "object", "properties": { "invoice_id": { "type": "string" } }, "required": ["invoice_id"] },
        "annotations": { "readOnlyHint": true } }
    ]
  }
}

// recordPayment, sendInvoiceReminders and deleteInvoice exist in the system.
// They are not in this list because this person's role cannot use them.
// If the agent calls one anyway, the server answers with a permission error.

A tools/list response in the shape the MCP specification defines, with tool names from the Sois accounting module. The specification also says clients must treat annotations such as readOnlyHint as untrusted unless the server is trusted, which is one more reason the server, not the annotation, has to be the thing that enforces the rule.

Prompt injection: the data can talk back

The threat specific to agents is that the data they read can contain instructions. An email from a customer that ends with a line telling the agent to forward the supplier list to an outside address; a document that tells it to mark every invoice paid. The model may or may not comply, and no prompt can guarantee it will not, which is why prompt injection is first on the OWASP list and why both Anthropic and OpenAI warn about it in their connector guidance.

The defence is the architecture, not the model. An agent that is only offered the tools its person can use cannot forward what its person cannot see. A call to mark invoices paid is checked by the system against the person's permissions, not against the model's belief that it was asked to. Consequential tools are marked so that the client asks a person first: ChatGPT currently requires manual confirmation in a conversation before write actions, and OpenAI's guidance is to keep approval on for tools that modify data; Claude asks for approval per tool and advises reserving "allow always" for trusted servers. And the log records the attempt, so an injection that was blocked is visible afterwards rather than silent.

Budget and logs: make the agent's work as reviewable as a person's

Budget matters for two reasons. The obvious one is cost: an agent given a vague outcome will keep calling tools until something stops it, and OWASP lists unbounded consumption as a risk in its own right. The subtler one is blast radius: a cap per integration limits how much a compromised or confused agent can do before a person notices. Where the person's own agent does the reasoning the AI cost sits with them; where the system's own agent does it, the cap should be set per integration and visible per action.

Logs turn all of this from a promise into something you can audit. Each call should record who the agent acted for, which tool, the inputs, the result and the time, in the same place the system records what people did. The test is whether a finance lead can find out what the agent did to a customer's account last month as easily as they can for a colleague. The MCP specification asks clients to log tool usage for audit; a business system should not rely on the client for that, because the client is not the system of record.

A checklist you can run against any system

Take these to any vendor, including us. Each is a yes or no, and each has a test rather than a question to ask.

  1. The agent connects as a named person over OAuth, with no company-wide key to paste. Test: connect from an external MCP client and look at what the sign-in page asks for.
  2. The tool list differs by role. Test: connect as a restricted user and as an administrator and compare what the agent is offered.
  3. The check is repeated when the tool runs. Test: remove a permission from a connected user mid-session and try the action again.
  4. Access fails closed. Test: call a tool the role should not have and confirm you get a refusal, not a result.
  5. Spend can be capped per integration and seen per action. Test: set a small cap and watch it bind.
  6. Every action is logged against the person, with inputs and result, where the system logs everything else. Test: read the log for a run you just did.
  7. Consequential tools are marked for confirmation so the client asks a person. Test: ask the agent to send money or delete a record and confirm you are asked first.

Sois is one system built to pass this list, and the shape at the top of the article is its shape. A workspace is an MCP server; any MCP client connects by adding the workspace address and signing in once over OAuth; tools are filtered by role before they are offered and checked again when they run; access fails closed; spend can be capped per integration; every action is logged; and networks built on the platform have their own database, storage, domains and keys. Run the checklist against it anyway. The value of a checklist is that it takes nobody's word.

Questions people ask

Is it safe to connect Claude or ChatGPT to my accounting data?

It is safe when the system holding the data enforces the controls: the agent signs in as you over OAuth, is offered only the tools your role allows, is checked again on every call, and every action is logged. Both vendors also ask for confirmation before consequential actions. If the system only offers a shared API key, the answer is no.

Can a system prompt stop an agent from leaking data?

No. A prompt shapes behaviour; it does not enforce anything. Data the agent reads can contain instructions that override it. The action has to be one the system would refuse regardless of what the model believes it was asked.

What is the difference between filtering tools and checking permissions?

Filtering decides what the agent is shown when it asks for the tool list. Checking decides whether a specific call is allowed at the moment it arrives. You need both: filtering reduces what the model can be talked into, checking catches everything filtering missed.

Who pays for the AI when my own agent does the reasoning?

You do, through your agent subscription. A system built this way performs no AI on your behalf in that case and should charge nothing for it. Spend caps apply to the system's own agent when you use that instead.

Sources
  1. Model Context Protocol specification: authorization OAuth 2.1, PKCE, the resource parameter, token audience validation, and the prohibition on token passthrough
  2. OWASP Top 10 for LLM Applications: LLM06 Excessive Agency excessive functionality, permissions and autonomy, and the mitigations the permission layer implements
  3. Anthropic: getting started with custom connectors using remote MCP OAuth sign-in, limiting requested scopes, per-tool approval, connecting only to trusted servers, prompt injection warning
  4. Sois: security and the permission layer the five controls as the platform implements them: role filtering, checks at run time, fail closed, spend limits, logging, tenant isolation

This article is reviewed when the products it describes change. Next scheduled review: December 4, 2026.

Start

Connect your agent to Sois.

Your workspace is an MCP server. Point Claude, ChatGPT, Cursor or any MCP client at it and work within your permissions.

  • Free to start
  • Bring your own agent
  • No vendor lock-in