Headless Doesn’t Mean Ungoverned: How Trust Works When Agents Call Salesforce

Understand how Salesforce authenticates, authorizes, and audits agents connecting through Salesforce Headless 360, and how to apply the right trust model for your agentic architecture.
When a user logs into Salesforce and clicks a button, trust is familiar. You know who they are, you decide what they’re allowed to do, and there’s an audit trail with their name on it. When an external agent connects to your org, it feels different. Yet, the same principles apply, even if the session is established and scoped differently.
For a human user, we manage scope and security through login and user permissions with profiles and permission sets. For an external agent, what it can access and do is governed through OAuth and the external client app configuration.
Architects designing agentic systems often focus on the capabilities of the agent. The new question for the Salesforce Architect designing for Salesforce Headless 360 is: what should agents be allowed to do, and how does Salesforce know whether to trust them in the first place?
This blog answers that question across five dimensions:
- how authentication works without an interactive login,
- how authorization scopes what the agent can access,
- how you trace what it actually did
- how you manage the token lifecycle, and
- how the Well-Architected Framework fits into the decisions you make along the way.
Understand why Headless 360 changes the trust equation
In a traditional Salesforce integration, an external client app authenticates on behalf of a named user or as a service account and interacts with a defined API. That API contract sets the scope: the integration can only do what the API exposes, and you know precisely what that is.
With an external agent connecting via Headless 360, there is no traditional API contract. The agent gets whatever CRUD access the authenticated user holds and determines how to use it. You don’t control who built the agent, what model it is running, or what its internal guardrails allow. You can’t rely on those guardrails to keep the agent within your boundaries.
That means your permission design has to do the work the API contract used to do. Object permissions, field-level security (FLS), and sharing rules are your primary controls. Design them specifically for the agent, not as a byproduct of a human user’s access needs. If a field has no business being visible to the agent, restrict it. If an object is outside the agent’s scope, remove access entirely.
When an external agent connects to Headless 360 via Model Context Protocol (MCP), every call runs under the authenticated user’s identity. The platform security model applies automatically: object permissions, FLS, and sharing rules all work exactly as they would in the browser.
Per-user authentication scopes every agent call to that individual’s exact permissions, preserving the per-user permission boundary throughout. For governance at the MCP tool call level, Agent Fabric adds least-privilege enforcement on top.
Introducing Salesforce Headless 360. No Browser Required.
Everything on Salesforce is now an API, MCP tool, or CLI command, and agents can use all of it.
Understand how Headless 360 authenticates external agents
For external agents connecting via Headless 360, there is one prescribed authentication flow: OAuth 2.0 Authorization Code with PKCE (Proof Key for Code Exchange). PKCE replaces the client secret used in traditional OAuth flows. This is the OAuth flow for Headless 360 for a reason, as Headless 360 is designed for public clients (for example, desktop apps, CLI tools, and AI clients like Claude Desktop), where storing a client secret securely is not practical. The agent presents a Consumer Key and a PKCE code verifier. No secret is shared or stored.
Other OAuth flows are ruled out for specific reasons. The client credentials flow would create a service account pattern where all calls run as one identity, losing per-user permissions and the audit trail. Implicit flow is deprecated and does not support refresh tokens. And, the username-password flow is not appropriate for agentic contexts.
In the prescribed Authorization Code with PKCE flow, every connection running under the authenticated user’s identity preserves per-user permissions and the audit trail. The agent can only access what that user can access, and every action is attributable to that user, not to a generic bot or service account.
Two scopes matter for configuration: mcp_api, which grants access to MCP servers, and refresh_token, which allows the agent to operate without re-prompting the user on every call. Without refresh_token, the agent cannot sustain a session across multiple interactions.
Scope what the agent can access
Authentication answers “who are you.” Authorization answers “what are you allowed to do.” For external agents connecting via Headless 360, the answer to that second question lives in the permission set and FLS configuration of the authenticated user. Design it deliberately.
Consider an organization that has standardized on Claude as their enterprise AI platform. Claude connects to Salesforce via Headless 360 to access customer data as part of a broader workflow. The agent needs to read account and contact records to identify the customer, and read case history to understand context. That is the full extent of what it needs to do in Salesforce.
If you assign that agent a permission set built for a customer service rep, it inherits everything that rep can see, including opportunities in the pipeline, billing data, financial records, internal notes, and fields that have no bearing on the agent’s task. The agent may never use that access intentionally. But if the permission is granted, you cannot rely on the agent’s internal guardrails to ensure it never uses it.
Build the permission set from scratch against the agent’s documented action list. Start with what the agent needs to do, derive the minimum object and field access required to do it, and build to that. Grant read access on Account and Contact. Grant read access on Case and the specific fields relevant to case history. Nothing else. Again, if a field is not on the action list, restrict it. And if an object is outside the agent’s scope, remove access entirely.
The same principle applies to FLS. Go field-by-field on the objects the agent touches. A customer’s billing address, payment method, or internal account tier may sit on the same object as the fields the agent legitimately needs. FLS lets you expose the fields the agent requires without exposing the ones it doesn’t. This granularity is what makes the permission set auditable: you can read it and know exactly what the agent can see.
Design the audit trail before you need it
With a human user, you can investigate an incident by talking to the person. With an agent, the audit trail is your only witness. That shifts it from a compliance checkbox to a core architectural concern, and the Well-Architected Framework Trusted pillar treats it as one.
Event Monitoring captures the external client app name, the authenticated user, the object, the operation, and timestamps for every API call the agent makes. That data tells you what happened. To know what changed, enable field history tracking on every object the agent can modify. Together, these two layers give you the audit depth to reconstruct an incident, support a rollback, and satisfy the traceability requirements the Well-Architected Framework recommends for any production agentic deployment.
For retention, stream Event Monitoring data to Salesforce Shield or an external log management tool.
Manage the token lifecycle deliberately
The refresh_token scope is not optional. Without it, the OAuth session cannot re-authenticate on its own and the agent will fail to operate across multiple interactions. Include it alongside mcp_api when you configure the external client app.
The refresh token is tied to the individual authenticated user’s OAuth session. There is no pooling and no shared service account. This is by design: it preserves the per-user permission boundary and the audit trail. It also means that revoking a user’s token immediately removes the agent’s ability to act on their behalf. That matters when access changes due to role changes, departures, or security incidents.
One operational consideration worth building into your deployment plan: in some client environments, tokens stored locally can go stale without triggering automatic re-authentication on session restart. This is not specific to Headless 360, but a function of how the OAuth lifecycle is managed on the client side. Design your agent deployment to handle token refresh explicitly rather than assuming the client will manage it. Test re-authentication behavior in a non-production environment before go-live.
Govern the integration, not just the agent
The question this post started with was how Salesforce knows whether to trust an external agent. The answer is that it doesn’t decide at runtime. You decide at design time, through the external client app configuration, the authenticated user’s permission set and FLS, and the audit trail you put in place before anything goes to production.
The mechanisms are the same ones you already use. OAuth 2.0 Authorization Code with PKCE establishes the session. The authenticated user’s profile and permission sets scope what the agent can access. Event Monitoring and field history tracking tell you what it did. None of this requires new tooling. It requires deliberate design.
The shift from traditional integrations to agentic ones is not a shift in platform capability. It is a shift in design responsibility. A traditional integration is bounded by its API contract. An external agent is bound by the permissions you give it and nothing else. That makes the permission design, the FLS configuration, and the audit trail more consequential than they would be for a known, deterministic integration.
Headless doesn’t mean ungoverned. It means that the governance is yours to build, using the tools already provided by the Agentforce 360 Platform.









