Giving an AI agent access to your business apps: four options, ranked by blast radius
Four ways to connect an agent to a business application, ranked by how much damage each one permits when the agent is wrong or the credential leaks.
Last updated
9 minute read · Written by the team that builds UtilitySpaces. More about UtilitySpaces.
An AI agent cannot work in your business applications without access to them. There are four ways to grant it, and they are not equivalent. Ranked from most damage to least: sharing your own password, a shared API key, a scoped OAuth grant, and a scoped OAuth grant with a write gate in front of it.
Blast radius is the honest question: when the agent is wrong, or a copy of the credential leaks, how much can be changed, deleted or sent before anyone notices, and how long does stopping it take? All four are easy to set up; they differ in what the bad day costs.
What actually goes wrong when an agent uses my own password?
Everything the agent does is recorded as you. The vendor’s own audit trail shows your account moving the money, deleting the record or messaging the customer, and no later investigation separates your actions from the agent’s. That destroys the evidence you would need to diagnose the failures below.
- No revocation short of a password change, which breaks every other session, device and integration sharing it — so people hesitate during an incident, when hesitating is expensive.
- The agent inherits your admin rights. If you can change billing, remove a user or export the customer table, so can it. Nothing lets it hold less than the account it is signed into.
- It defeats multi-factor authentication. Somebody has to park a long-lived session, share the seed or forward the codes. All three turn a second factor into a first one.
- The credential ends up in text — in prompts, automation scripts, environment files and debug logs, and prompts are the least controlled of those.
The browser-driving variant, where the agent clicks through the vendor’s interface as you instead of calling an API, is the same option with worse failure modes: your full session, and no structured record of what it attempted when a click lands on the wrong row.
Is a shared API key good enough?
For a one-off internal script, yes. A key is separable from your identity, revocable on its own without locking you out, and attributable to the key rather than to a person. As a standing grant to an agent that decides for itself what to do next, it is weaker than it looks, for four reasons.
- Most keys carry the full rights of whoever minted them. Some vendors offer restricted keys; many issue one with the account’s complete permissions. Stripe, for instance, documents what its secret keys reach and that they must never leave a server.
- They rarely expire. A key minted for a two-week experiment is still valid two years later, granting rights to a system nobody remembers connecting.
- They are bearer tokens. Possession is the whole authentication, so anyone holding a copy is indistinguishable from the legitimate caller.
- A key pasted into a config file is permanent. It survives in backups, shell history, the image layer and the chat message where it was shared. Rotation is the only real cleanup, and rotation is the step teams skip.
Does scoped OAuth fix it?
It fixes identity and revocation properly. You get a per-application, per-scope grant with a refresh mechanism, a consent record naming what was agreed, and a control that kills one integration without touching anything else. It is the minimum bar for a standing grant, and it is not a control on behaviour.
The framework is RFC 6749 and the current security guidance is RFC 9700. Three limits matter here.
The vendor decides the granularity, not you. Some platforms are generous: Slack publishes a long list of narrow scopes and you can ask for exactly one. Others offer one coarse read scope and one coarse write scope across an entire product, and no care on your side subdivides them.
A correct scope still permits a wrong action. A token holding a legitimate write scope can write the wrong value, to the wrong record, a thousand times in a minute.
Scopes say nothing about volume, timing or reversibility. They describe a surface, not a rate and not a consequence. Deleting one record and deleting every record use the same scope.
What does a write gate add on top of scoped OAuth?
The token constrains what is reachable; the gate constrains what is done with it. Scopes are evaluated once, at grant time, by a vendor who knows nothing about your business. A gate is evaluated per action, in your workspace, against a policy that is not the vendor’s. That division of labour is why the fourth option exists.
In UtilitySpaces the write gate applies to connector writes only; reads are never gated. The reasoning is written into the code: a wrong read is recoverable and a wrong write is durable, so gating reads buys nothing. The gate applies to every caller, automations included, so a flow cannot write anywhere an agent could not: a write waits for a person unless an admin has set that connection to run without asking, and a delete always waits for a person.
A connector write that waits becomes a request in Approvals: approved, it runs exactly once; rejected, it never runs and the reason goes back to the agent. Eight approval kinds exist — task output, document update, message draft, tool permission, knowledge proposal, external data operation (the connector write), skill import and model marketplace — and every decision path funnels through one review function, so there is a single place to grant an approval and a single place to audit. The design trade-offs are covered separately in how to design the moment an agent stops and asks, and the mechanics are on the approvals page.
How do I stop a connector from reaching my own network?
By forcing every outbound request through one guarded function that validates the destination, and by re-validating on every redirect hop rather than once at the start. A connector that accepts a URL is a server-side request forgery primitive by default; the OWASP SSRF prevention cheat sheet explains why name and address checks belong together.
In UtilitySpaces every connector request leaves through that one function, which:
- refuses any scheme that is not http or https;
- refuses hostnames that are
localhost,*.localhost,*.internal,*.local, or a bare label with no dot, which is what an internal service name looks like; - resolves the hostname and refuses if any resolved address is private, link-local, loopback, multicast or carrier-grade NAT — so a name answering with one public and one private record, the DNS-rebinding shape, is refused outright;
- re-checks every redirect hop itself rather than letting the HTTP client follow redirects, because a public host answering
302with an internal address turns a checked-once fetch straight back into the primitive; - strips the
Authorization,CookieandProxy-Authorizationheaders on a cross-origin redirect, so a public host cannot bounce a connector’s API key to itself; - has a deployment setting for deliberately pointing connectors at a private LAN, which the embedded-browser feature refuses to honour, so loosening connectors cannot silently reopen the hole on a different feature.
One gap remains, written in the code as a comment rather than left to be found. The guard resolves the name, then the HTTP client resolves it again to open the socket, so a record with a one-second time-to-live alternating public and private answers still has a narrow window between those lookups. Closing it means owning the socket, which costs automatic decompression, and it has not been done because no rebind has been observed.
What happens when two connected apps could both do the same write?
The action is refused. Each write capability resolves to exactly one destination per workspace through a binding row. If two connected applications could both service a write and no binding has been chosen, UtilitySpaces refuses it as an unbound capability rather than guessing. There is no tie-break and no fallback.
The characteristic agent failure is not a break-in, it is a plausible action against the wrong system: the message posted to the wrong channel, the invoice raised in the ledger you migrated away from. A silent default makes that invisible; a refusal makes it a five-second decision. The connector catalog holds more than seventy application definitions plus two generic ones, an MCP server connector and a raw HTTP connector, and each connection is its own permission boundary with its own declared tools and, for OAuth, its own scope list.
Afterwards you have to prove what happened. The audit log is append-only with one sequence number per workspace, and every entry stores the previous entry’s hash alongside its own SHA-256 hash, so an edit or a deletion breaks the chain at a known sequence number.
Which option should I pick for which job?
Pick by how long the grant lives and who holds it. A one-off script you run yourself and delete the same afternoon does not need OAuth. A standing grant to something that decides on its own what to do next needs both a scope and a gate. The table is the short version.
| Option | What it is | What a copy gives an attacker | How you revoke it | Setup cost | Where it genuinely wins |
|---|---|---|---|---|---|
| Your password | The agent signs in and acts as you | Your whole account, and your name on all of it | Password change, breaking every other session at once | Minutes | Nothing. No job needs this. |
| Shared API key | One bearer secret, usually with the minter’s rights | Everything the key reaches, indefinitely, with no second factor | Rotate it; anything else using it breaks | Minutes | A five-minute internal script for a one-off job, deleted afterwards |
| Scoped OAuth | Per-application, per-scope grant with refresh and consent record | Only what the scopes cover, until revoked or expired | Revoke that one grant; nothing else is affected | An hour per application, once | Standing integrations where the vendor offers usable scopes |
| Scoped OAuth plus write gate | The same grant, with writes waiting for a person unless an admin lets the connection run | The scope surface, minus every write the gate holds or refuses | Revoke the grant, or set the connection to refuse writes while you investigate | The OAuth setup, plus deciding which connectors may write | Anything an agent decides on its own, especially irreversible writes |
Setup cost is why teams end up on option one or two. It is also the smallest number here.
Where does this still not protect you?
In four places worth stating plainly. The gate constrains actions inside a workspace; it does not improve a vendor’s permission model, it does not cover every application you use, it is not audited by a third party, and it does not protect the workspace account itself as well as it should.
- Where the vendor offers no usable scopes, none of this conjures them. If an application issues one all-or-nothing key, the token you hold is all-or-nothing. The gate can only hold, refuse or allow writes through it, which is worth having and is not least privilege.
- The catalog is a fraction of Zapier’s or Make’s. For a long-tail niche application they will have a connector and UtilitySpaces will not. The generic MCP and HTTP connectors narrow that gap; they do not close it.
- There is no SOC 2, no ISO 27001 and no third-party certification. If procurement requires any of those, the answer today is no.
- The DNS-rebinding window above is real and unclosed. It is the narrow gap between the guard’s lookup and the client’s, described in full above rather than left to be found, and it stays open until the socket is owned.
What should I do this week if I am on option one or two today?
Three things, in order, none of which require adopting a particular product. Inventory what holds a credential, revoke what nothing depends on, and convert the highest-risk remaining grant to a scoped one. That is a couple of hours of work, and it removes most of the blast radius described above.
- List every place an agent or script holds a credential, including browser profiles with a parked session, and write down what each one can delete. That column is your risk register.
- Revoke anything nothing depends on. Most inventories contain a key from an experiment that ended.
- Convert the grant with the largest delete surface first — usually billing, the CRM or the mailbox, not the analytics tool people start with. Take the narrowest scopes that keep the job working, then put a gate in front of the writes.
For why a workspace, rather than a pile of point integrations, is the useful shape for this, start with the definition of an agentic workspace. UtilitySpaces is a managed service, and support@utilityspaces.com replies within one business day.