Enforcing each user's Salesforce profile permissions on AI agents using the Salesforce MCP server
An agent only respects a user's Salesforce profile permissions if the request reaches Salesforce under that user's identity, through a token scoped to the task. Where the MCP server uses a shared integration identity, Salesforce evaluates that identity instead. Carry per-user delegation through the server, then authorize each tool call at runtime with a decision (allow, redact, block or escalate) that is recorded with the acting user.
A per-call authorization sequence
- 1
1. Validate the token
Confirm validity, scope, source and integrity before the call proceeds. Reject tokens not issued for this service.
- 2
2. Bind the user
Resolve the user principal from the token and record it alongside the agent and server workload identities.
- 3
3. Evaluate policy
Combine the user's assigned permissions with context: tool, object, operation, data sensitivity and request attributes.
- 4
4. Apply the outcome
Allow, redact, block, or hold for human approval. Salesforce still enforces its own controls on any call that passes.
- 5
5. Inspect the response
Apply redaction to returned data and keep credentials out of tool responses, prompts and memory.
Audit-ready evidence for each tool call
- Acting user principal and the agent and server workload identities
- Token validation result, including scope and source checks
- Tool invoked, target object and operation requested
- Permissions and context attributes evaluated
- Policy decision (allow, redact, block or escalate), the policy version, and any approver
- Data returned after redaction, with a retention period matching your obligations
How agent access diverges from the requesting user's permissions
Salesforce evaluates access for whichever identity presents the credential. Profiles and permission sets grant object-level and field-level access, and sharing rules extend record visibility. All of that is tied to a user. If the agent's request arrives under a different identity, the user's permissions are not the ones being applied.
The common divergence paths are straightforward. The MCP server may authenticate with a single integration user, so every requester inherits that user's access. That integration user may have been granted broad permissions during setup to make the agent work, and never narrowed. Permission drift adds a slower path: the user's access is reduced, but the integration identity or a long-lived token keeps the earlier, wider access.
A less visible path is credential reuse. Agents can reuse user or service credentials that appear in context, memory or tool responses, even when those credentials were not meant to be forwarded. A token placed in a prompt or returned by a tool can be replayed against a service it was never issued for.
A gateway can also substitute identities. A service account credential can be attached in place of the end-user credential, so the downstream system sees only the service. That keeps the request working while removing the user from the decision.
Choosing an authentication and delegation pattern
Three identities are usually in play on the path from agent to Salesforce: the workload identity of the agent or gateway, the identity of the MCP server, and the end user. Authorization guidance for APIs expects two levels of checks, service authorization and end-user-to-resource authorization, and notes that even both together can leave APIs exposed. The pattern you choose determines whether the second level exists at all.
Per-user delegation is the pattern that keeps the user in the decision. It relies on a standardized scheme such as OAuth 2.0 or JWT, issued through an identity system that represents the user principal and ideally backed by phishing-resistant multi-factor authentication. Scopes then limit what the token can do. Scopes constrain actions, but they do not by themselves express record-level or field-level limits, so they complement the platform's permission model rather than replace it.
- Shared integration identity: Simple to operate. Every user receives the integration user's access, attribution to the individual is weak, and permissions rarely track the requester.
- Per-user delegated token: Salesforce evaluates the requesting user's own permissions. Requires token issuance, refresh and revocation per user, and the server must not pass tokens through to services they were not issued for.
- Delegated token plus runtime policy: Adds per-call decisions on context, data returned and action sensitivity. More components, but it covers cases the platform's access model does not address.
Where native enforcement stops and runtime enforcement starts
Native controls answer one question well: may this identity read or change this object, field or record. When the request carries the right user identity, those controls apply without extra work, which is the strongest reason to prefer per-user delegation over a shared account.
They do not decide whether a specific agent action, in a specific context, should proceed. Access decisions should rely on assigned permissions plus contextual information about each request, and an attribute-based model evaluates attributes of the subject, the object, the operation and sometimes the environment against policy. A runtime layer on MCP tool calls is the practical place to apply that model.
Examples include allowing a read but redacting selected fields before the result reaches the model, blocking a bulk export that the user could technically perform, and escalating a record deletion for human approval. Escalation fits the principle of just-in-time approval with no standing privilege for sensitive operations.
Trussed enforces policy in the execution path on MCP server tool calls, with allow, redact, block and escalate-for-approval outcomes, so the decision is enforced at runtime, not reviewed after the fact.
Operating the control: ownership, drift and tradeoffs
Assign explicit owners for the integration identity, the MCP server configuration and the policy layer. Without that, permission changes in Salesforce and policy changes at runtime move independently, and drift follows. Review the permissions an agent can actually exercise against the requesting user's intended access on a fixed cadence, and revoke anything that exists only because it was convenient at setup.
The tradeoffs are real. Per-user delegation adds token lifecycle work and can break unattended jobs that have no user to represent. For those jobs, use a separate, narrowly scoped service identity, label it as such in the evidence, and do not let interactive requests fall back to it. A runtime policy layer adds latency and another component to operate, so its value depends on whether your tool calls involve data or actions that native controls alone cannot bound.
Trussed runs as a self-managed deployment in the customer cloud, with configurable retention and data residency, and generates continuous audit-ready evidence from enforcement, mapped to frameworks including HIPAA, NAIC, NYDFS, the EU AI Act and NIST.
Path of a single agent tool call
Requesting user
Authenticated principal whose permissions should bound the action.
Agent and MCP server
Workload identities that must not replace the user identity.
Runtime policy decision
Per-call evaluation: allow, redact, block or escalate.
Salesforce
Native enforcement of profiles, permission sets, field-level security and sharing.
Review how tool-call enforcement and evidence work in practice
Walk through runtime policy on MCP tool calls and the audit-ready evidence it produces for a regulated enterprise.
See How Evidence Is ProducedHow does your AI governance program compare?
See where your program has gaps in less than 2 minutes.