# Salesforce field-level security for AI agents

> Salesforce field-level security for AI agents holds only when each call runs as the employee's own account, and writes need a second layer of control.

**TL;DR** Salesforce field-level security, sharing rules and the role hierarchy still apply to an AI agent, but only when the call runs on that employee's own connected Salesforce account. In Elaichi, every call uses the credential bound to the connection it goes through, so one shared account answers every question with one person's visibility. Writes need a second layer: restrictions that block delete and bulk tools for a role, and locked-in values on a toolbox entry.

## Why does one shared Salesforce account flatten every permission?

A single shared Salesforce login is the one decision that breaks Salesforce field-level security for AI agents before anything else does. Your admin spent years on profiles, permission sets, field-level security and a role hierarchy. Then a pilot connects an assistant with one service account. Every answer reflects that account's access rather than the asker's. In Elaichi, each call runs on the connected account behind the connection it goes through, so per-person connections keep each rep's own visibility.

The mechanic underneath is plain. In Elaichi, every call through a connection uses the credentials bound to that one connection, whoever is calling. A connection its owner shares with a team runs every teammate's call as the owner. The rep who asks about a regional opportunity gets the owner's visibility. Salesforce sees the owner's account on the request.

Field-level security is not bypassed in that setup. It is answered for the wrong person. Salesforce applies its rules faithfully to the identity it was handed, and that identity is wrong by construction. The audit trail inside Salesforce goes with it. When the shared account updates a lead, the CRM records the shared account as the author, not the rep who asked.

## What is Salesforce field-level security, layer by layer?

Salesforce decides access in layers: object and field access first, then record access. This matters for any AI integration, not just Elaichi. An agent call has to clear each layer to return or change a field, and each layer fails differently.

- **Object and field access.** Salesforce limits exposure of data to the users that act on it. Admins give specific object or field access to selected groups or profiles ([developer.salesforce.com](https://developer.salesforce.com/docs/atlas.en-us.securityImplGuide.meta/securityImplGuide/admin_fls.htm), checked October 2026). A user can have access to an object and still have a field hidden or read-only: Amount, SSN__c, a custom compensation field. Field-level security is evaluated per field, per request.
- **Record access.** Which records an identity can see is decided separately. Microsoft's Salesforce connector page names the controls its default access setting enforces: Salesforce record ownership, sharing rules and the role hierarchy ([learn.microsoft.com](https://learn.microsoft.com/en-us/microsoft-365/copilot/connectors/salesforce-crm-overview), checked October 2026). A rep with access to the Opportunity object can still be blocked from a record owned by a different territory.

These layers apply on every single request. An integration that gets the identity right inherits all of them automatically. Salesforce evaluates them against whatever identity the API call carries, and it does not know whether a human or an agent started the call. An integration that gets the identity wrong bypasses none of them mechanically. A shared service account or an elevated integration user makes every layer answer for the wrong person. The practical effect is the same as bypassing them.

## What does Salesforce field-level security for AI agents depend on?

It depends on two identities lining up: who the AI client acts as inside Elaichi, and which Salesforce account the call runs on. Get both right and Salesforce does the rest.

The first is the OAuth grant, the approval a person gives when they connect their AI client. Claude, ChatGPT, Cursor and Microsoft Copilot all sign in at the same Elaichi address. MCP (Model Context Protocol) is the standard way an AI assistant calls tools in other apps. Each person connects their own client once and approves their own grant, and every call made with that grant acts as that person. Elaichi re-reads the grant on each request, so removing or suspending a member revokes every live grant in the same transaction as the membership change.

The second is the connection. Tools run on a person's own Salesforce account in three cases. Their All tools toolbox counts, as does a toolbox they built on their own connections. So does a template they stamp while picking their own connection for Salesforce. A toolbox is a named list of tools, and one shared with a team is not on that list. Its entries run on the connection pinned in them, under the person who pinned it.

So the rollout is unglamorous. Each rep connects Salesforce themselves with their own login, and reaches it through their own tools. An agent acting as each rep's own connected account inherits that rep's access. Salesforce then decides what comes back: field-level security, sharing rules, record ownership, role hierarchy. Elaichi re-implements none of it, and does not need to. The longer walkthrough for one team lives in [each rep's own Salesforce access in ChatGPT](/blog/sales-team-chatgpt-salesforce-accounts/). The general shape is in [AI agents with employee permissions](/blog/ai-agents-employee-permissions/).

## Does indexing CRM records somewhere else change the answer?

Yes, because it moves where access is decided. A live connector asks Salesforce at the moment of the question, as that person, and nothing rests in a second index. An indexing connector copies records into another system's search index first. The index then decides who sees what.

Microsoft documents its Salesforce connector for Microsoft 365 Copilot as a Microsoft 365 Copilot connector. It indexes Salesforce records into Microsoft 365 ([learn.microsoft.com](https://learn.microsoft.com/en-us/microsoft-365/copilot/connectors/salesforce-crm-overview), checked October 2026). The same page says its default access setting enforces Salesforce record ownership, sharing rules and the role hierarchy, and that fields restricted by field-level security are excluded from indexing by default. Verify current connector behavior in your own tenant before relying on it. That route is built for a company standardized on Microsoft 365 that wants CRM records surfacing in Copilot next to files and mail. If that is your requirement, it is the closer fit. The two paths are compared in [Microsoft Copilot with Salesforce](/blog/microsoft-copilot-salesforce-jira/).

The trade-off is a second copy of CRM data inside the Microsoft boundary. Your security team then has to manage and review it. A permission change made in Salesforce reaches the index only when the index catches up. Carry the same question into either evaluation: who does the call run as, and when is access evaluated, at index time or at question time.

| Mechanism | Access decided | What it guarantees | What it doesn't guarantee |
|---|---|---|---|
| Per-person live connection (Elaichi, native Salesforce API with per-user OAuth) | At call time, by Salesforce, against the real user | Correct field-level security, sharing rules, role hierarchy, audit author, per request | Nothing about bulk or destructive scope, covered below |
| Shared connection / shared service account | At call time, by Salesforce, against one fixed account for everyone | Consistent, predictable access | Correct identity per person; correct audit author |
| Indexing connector (Microsoft 365 Copilot connector) | At index time, by the connector's permission mapping | Search across indexed content, with Microsoft's default access setting enforcing record ownership, sharing rules and the role hierarchy | Evaluation at question time; the index is a second copy of the data |

## Which Salesforce writes should an agent never be able to make?

The writes that sit inside a rep's permissions but outside their job. Field-level security stops an update to a field the rep cannot edit. It does nothing about updating four hundred opportunities at once. It does nothing about deleting an account the rep owns. A correctly scoped identity is fully authorized to perform both. Salesforce's access layers never ask whether a write is destructive or wide in blast radius.

That gap is what restrictions close. A restriction says which connectors and which single tools a target may reach. In Elaichi, restriction targets are role or user only; the organization default is the absence of a rule, which means allow everything. A sales team is therefore governed through the role its members hold. The rules are read in order, from browsing a connector to the last check before a request leaves. Every path that runs a connected tool passes the same clamp: `tools/call`, `execute_tool`, `read_tool`, a toolbox execution, a synthetic tool's steps. That order is traced in [how a restriction is resolved](/blog/restriction-resolver-decision-tree/).

Four mechanics decide whether the rule you write does what you meant:

- A block list covers only the tools it names. Block two bulk tools and every other write tool on Salesforce stays reachable, including ones added later.
- A read-only shape is written as allow rules, not blocks. One allow rule turns the allowlist on for that whole layer, so the role also needs allow rules for every other app it uses. An allow rule naming nothing blocks everything for its target. That trap is described in [the allow rule that blocks all tools](/blog/empty-allow-rule-denies-everything/).
- Do not judge a tool by its name. Elaichi tiers a catalog tool from its HTTP verb and method. An HTTP DELETE counts as destructive whatever it is called, and a composite or batch call that posts counts as a write. In the console each tool carries a Read only or Makes changes label. The restriction picker offers presets for blocking deleting or blocking every change, next to a search box and a checkbox per tool.
- Blocks match a tool's name or its pinned operation. Allows match the pinned operation only, for the reason set out in [why blocks match tool names](/blog/block-matches-name-allow-matches-operation/).

Timing matters during a rollout. A restriction change reaches every surface about two minutes, not on the next call. Test after the wait, not before it.

A restricted tool is not invisible. Search names it, flagged as restricted, with no schema and no way to call it. The refusal tells the person their role is the reason, and that an admin can lift it. Choosing between a whole-app block and a single-tool rule is covered in [restrict one AI tool or the whole app](/blog/per-tool-vs-per-app-restrictions/).

## Can you lock the arguments on a Salesforce write?

Yes, per toolbox entry, with locked-in values. Elaichi calls them frozen parameters: argument values written into the entry that a caller cannot override. The keys are removed from the schema the model is shown. They are merged over the caller's arguments when the call runs, so the AI client cannot set them.

Three caveats keep that from being more than it is. The model can see what is frozen, and often the value, because short values appear in the tool description. Anyone who can open the toolbox reads every frozen value in full. A freeze holds only on calls that run through the entry carrying it. And anyone who can use the connection themselves has the same tool, unfrozen, in their All tools toolbox.

So a lock that sticks is a shape, not a setting. The connection's owner keeps the connection unshared, pins it into a toolbox entry with the frozen value, and shares the toolbox at use. The connection argument itself cannot be frozen, because it chooses the account. More on the pattern in [lock AI agent tool arguments](/blog/frozen-parameters-wire-transfer-receiver/).

The trade-off is real. Per-person connections give Salesforce the actual user and the actual field-level security. A shared toolbox with locked values gives you a fixed argument, but runs every call on one account. You cannot have both on the same call. Pick per-person for anything where Salesforce should see the human. Pick the shared, locked shape for a narrow machine-like task nobody is personally accountable for.

## Where does the approval step actually sit?

Over MCP, the approval moment is Elaichi's consent screen, not the call. Elaichi has no per-call approval on its MCP endpoint. The scopes a person grants a named client there stand as the approval for that client's calls.

Three consequences follow. "Run your connected tools" runs every tier of connected tool, writes and deletes included. "Delete data and remove access" covers Elaichi's own data and access, not Salesforce records. Leaving "Create and change data" unticked does not make a connected app read-only. To hold a client to reads, pick toolboxes of read tools at consent, or block the write and delete tools with a restriction.

Per-call prompts come from the AI client. Claude sets connector tool permissions to Always allow, Needs approval or Blocked ([support.claude.com](https://support.claude.com/en/articles/11176164-use-connectors-to-extend-claude-s-capabilities), checked October 2026). ChatGPT may show an approval card before a write action. That depends on the app permission setting and the action's context ([help.openai.com](https://help.openai.com/en/articles/20001495-managing-app-permissions-in-chatgpt), checked October 2026).

There is a limit on what those client controls can reach. Through Elaichi, connected tools are never listed one by one, however few there are. The model finds one with `search_tools` and runs it with `read_tool` (a read) or `execute_tool` (anything), or with `run_code` under Code Mode. Each search result says which of the two to use. Per-tool client permissions therefore see Elaichi's connected tools as a few tool names: `execute_tool`, `read_tool` and `run_code`. They cannot tell Salesforce from a help desk, and gating `execute_tool` alone leaves `read_tool` and `run_code`. Per-app and per-tool control is set in Elaichi, as restrictions. The layered view is in [human approval for AI agent actions](/blog/human-approval-for-ai-agent-actions/).

If you want Elaichi itself to stop and ask before each write, that is the Elaichi Agent. It comes with the Black plan and runs inside Elaichi rather than signing in to the MCP endpoint.

## What does the audit log show after a Salesforce write?

Every connected-tool call that reaches execution writes one entry: one entry for each connected-tool call that reaches execution (a call refused earlier writes none). For a list or search it also records the resource type and how many items came back.

Argument values are not recorded, with one exception. The single path argument that names the object is kept as the target id. A call refused before execution writes nothing, so a tool a restriction withheld or a missing scope leaves no entry. The log is a record of what ran.

Retention is 90 days, and for longer history export to your own Datadog comes with the Black plan. A Salesforce call made from ChatGPT sits in the assistant category of the log, not the MCP category, which holds client grants. What a log of this kind has to contain is listed in [what an AI agent audit log must capture](/blog/what-an-ai-audit-log-must-capture/).

## What happens when a rep leaves?

Removing or suspending a member revokes every MCP OAuth grant they hold in that organization. Their AI clients fail on the next call, rather than after a cache window. Reactivating them does not bring the grants back; they consent again. Their own Salesforce login is a separate matter, deprovisioned in Salesforce or through your identity provider.

The part people miss is delegation. Say the departing rep pinned a connection into a toolbox entry. That entry stops resolving for everyone once they are no longer an active member. Someone with edit on the toolbox then re-pins it to their own access. The full sequence, contractors included, is in [offboarding AI access](/blog/offboarding-when-the-agent-holds-access/).

## When you do not need any of this

Sometimes the honest answer is that per-person connections are the whole control, and nothing else is needed:

- **One person, one Salesforce login.** A single user connecting their own AI client needs no restrictions, toolbox sharing or frozen parameters. Their own Salesforce field-level security and sharing rules already apply to every call. The free Personal plan covers this: one member, up to 10 connections across 3 apps, and 1,000 connected-tool calls a calendar month. Connect Salesforce with your own login and stop there. Sharing and restrictions matter once a second person or a shared connection enters the picture, which is what the Gold plan adds.
- **Reps already on read-only Salesforce profiles.** If the underlying Salesforce profile has no write access, their own connection already carries that restriction. An Elaichi restriction then adds little beyond redundancy.
- **The requirement is search across systems, not live CRM access.** If you want CRM records showing up in Microsoft 365 search alongside files and mail, the Microsoft 365 Copilot connector route fits better than an MCP endpoint built for live, per-call access.
- **The write is fixed, validated and repeatable.** Take a process with no judgment call in it, such as syncing a status field on a schedule. Build it as an automation rather than handing it to an agent with tool access, as set out in [automation platform vs MCP access](/blog/n8n-automation-vs-mcp-access/).

For the wider model behind roles, sharing and restrictions, start at [MCP governance](/blog/mcp-governance/). See [the governance use case](/use-cases/governance/) for where Salesforce sits beside the other apps in [the connector catalog](/connectors/).

## FAQ

### Does an AI agent inherit Salesforce field-level security?

It inherits field-level security, sharing rules and the role hierarchy only when the call runs on that employee's own connected Salesforce account. In Elaichi, every call uses the credentials bound to the connection it goes through, so a connection shared with a team runs every teammate's call as the connection's owner. For per-person access, each person connects Salesforce with their own login and reaches it through their own tools: their All tools toolbox, a toolbox built on their own connections, or a template they stamp with their own connection.

### Can restrictions make a single shared Salesforce account safe?

No. Restrictions decide which connectors and tools a role or one member may reach, so they can remove delete and bulk-update tools. They cannot restore per-record or per-field visibility, because the call still runs on whichever account the connection is bound to, and Salesforce evaluates its rules against that account. Per-person record visibility comes from per-person connections, not from a restriction.

### Does Elaichi ask a human before an AI writes to Salesforce?

Not over MCP. The approval moment is Elaichi's consent screen, where a person grants scopes to a named client, and every later call runs as already approved. "Run your connected tools" covers writes and deletes in a connected app, and unticking "Create and change data" does not make that app read-only. A per-call prompt a person sees comes from their AI client, such as Claude's Needs approval setting ([support.claude.com](https://support.claude.com/en/articles/11176164-use-connectors-to-extend-claude-s-capabilities), checked October 2026). Elaichi's own per-call approval cards exist in the Elaichi Agent, which comes with the Black plan and runs inside Elaichi.

### How do you stop an AI agent from deleting Salesforce records?

Write a restriction on the role that blocks the delete tools, or hold the role to an allowlist of read tools. A block list covers only the tools it names, so any write tool the rule does not mention stays reachable. Elaichi tiers a tool by its HTTP verb and method, so an HTTP DELETE counts as destructive whatever it is labeled. The rule binds every path that runs a connected tool, including `execute_tool`, `read_tool` and `run_code`. A restriction change reaches every surface about two minutes, so test after waiting.

### How is Microsoft's Salesforce connector different from a live MCP connector?

Microsoft documents its Salesforce connector for Microsoft 365 Copilot as a Microsoft 365 Copilot connector that indexes Salesforce records into Microsoft 365 ([learn.microsoft.com](https://learn.microsoft.com/en-us/microsoft-365/copilot/connectors/salesforce-crm-overview), checked October 2026), so records are copied into an index and surfaced in Copilot. A live connector instead calls Salesforce at the moment of the question, as the person asking, so Salesforce evaluates field-level security and sharing at request time. The indexing route fits a company that wants CRM records in Microsoft 365 search alongside files and mail.

### Does an AI assistant need its own Salesforce license?

When each person connects Salesforce with their own login, calls run on that person's existing Salesforce account, so no separate identity is introduced on the Salesforce side. Whether that arrangement needs a license of its own is a question for Salesforce's own terms, not something an MCP endpoint decides. Check it with your Salesforce account team before a company-wide rollout.

## Read next

- [HubSpot MCP access for sales team, per rep](/blog/sales-team-claude-hubspot-deals/) — HubSpot MCP access for sales team, rep by rep: each rep's own HubSpot sign-in, deal deletion and pipeline edits blocked, and an audit row that names the deal.
- [MCP restriction resolver precedence, as a decision tree](/blog/restriction-resolver-decision-tree/) — How the mcp restriction resolver precedence works across Elaichi's enforcement points, traced through one real tool call from browse to outbound request.
- [Resource ACL view use edit: how Elaichi shares access](/blog/resource-acl-primitive-view-use-edit/) — How the resource ACL view use edit grant works in Elaichi, and why no org-level permission widens what a member can list.
