Agent-First Salesforce Architecture: Designing Orgs for AI Agents
The new architectural mandate: before your org can support AI agents, it has to be agent-readable.
We went through "mobile-first." Then "API-first." Each shift forced architects to rethink how they structured systems — not because the underlying data changed, but because the consumers of that data changed. Mobile-first meant responsive layouts and offline-capable APIs. API-first meant clean contracts, versioning, and treating integrations as first-class citizens.
Now the consumer is an AI agent. And the architectural question has shifted from "can a developer call this?" to "can an autonomous agent reason about this?"
This isn't about Agentforce specifically, though Salesforce's agent platform is the most concrete example in the ecosystem. It's about a design philosophy: every object, every field, every API surface, and every permission boundary in your org should be structured so that an agent can discover it, understand it, and act on it — without a human writing glue code for every interaction.
What Agents Actually Need From Your Org
Before diving into patterns, it helps to understand what an AI agent does when it interacts with your Salesforce org. The Atlas Reasoning Engine — the brain behind Agentforce — goes through a cycle: it reads available metadata to understand what tools and data exist, it reasons about which actions to take, it executes those actions, and it evaluates the result.
This means your org needs four properties:
- Discoverability — Agents use metadata descriptions to know what exists and what it means. If a field has no description, it's invisible to the agent's reasoning.
- Accessibility — Clean API surfaces. If data is only reachable through a specific Apex class with hardcoded logic, agents can't get to it.
- Predictability — Consistent naming, standard relationships, no spaghetti configuration. Agents need patterns they can generalize across.
- Security — Well-scoped permissions with least-privilege access. Not admin-equivalent Connected Apps.
Every pattern below maps back to one or more of these four properties.
Pattern 1: The Agent-Readable Data Model
Field Descriptions Are Runtime Documentation
Here's the thing most architects miss: field descriptions in Salesforce aren't just for humans browsing Setup. The Atlas Reasoning Engine ingests them to decide which fields are relevant to a given task. A blank description means the agent has to guess — or ignore the field entirely.
Compare these two approaches:
Agent-blind:
Cust_T__c — no description, no help text.
Agent-readable:
Customer_Tier__c — Description: "Loyalty classification: Bronze, Silver, Gold, Platinum. Used for discount eligibility, support routing priority, and SLA threshold calculations."
The second version gives the agent enough context to know when this field matters. If a customer asks "am I eligible for a discount?", the agent can reason that Customer_Tier__c is relevant without being explicitly programmed to check it.
Audit your org: Run a describe call on your key objects. Any field with a blank description is a field agents can't reason about. This is the single highest-ROI cleanup task for agent readiness.
Custom Metadata Types for Agent Configuration
Hardcoded values in Apex are invisible to agents. Custom Metadata Types are queryable, deployable, and readable — making them the right surface for agent behavior configuration.
<!-- AgentConfig__mdt — agent behavior configuration -->
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Agent Configuration</label>
<pluralLabel>Agent Configurations</pluralLabel>
<fields>
<fullName>Agent_Name__c</fullName>
<fieldManageability>DeveloperControlled</fieldManageability>
<label>Agent Name</label>
<type>Text</type>
<length>80</length>
<description>Identifies which Agentforce agent this configuration applies to</description>
</fields>
<fields>
<fullName>Max_Records_Per_Action__c</fullName>
<fieldManageability>DeveloperControlled</fieldManageability>
<label>Max Records Per Action</label>
<type>Number</type>
<precision>5</precision>
<scale>0</scale>
<description>Governor limit guardrail: maximum records the agent may process per action invocation</description>
</fields>
<fields>
<fullName>Escalation_Threshold_Hours__c</fullName>
<fieldManageability>DeveloperControlled</fieldManageability>
<label>Escalation Threshold (Hours)</label>
<type>Number</type>
<precision>5</precision>
<scale>0</scale>
<description>Hours before the agent escalates an unresolved case to a human queue</description>
</fields>
</CustomObject>
An agent can query SELECT Agent_Name__c, Max_Records_Per_Action__c, Escalation_Threshold_Hours__c FROM AgentConfig__mdt to understand its own operating parameters. No Apex required. No hardcoded magic numbers. Configuration that's both human-manageable in Setup and agent-readable at runtime.
Pattern 2: API-First Exposure
Named Credentials: The Agent's Authentication Layer
Agents making outbound callouts should never handle raw credentials. Named Credentials centralize authentication and let you swap providers, rotate secrets, or change OAuth flows without touching agent logic.
<!-- External Credential — authentication configuration (API v56.0+) -->
<ExternalCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Inventory System Credential</label>
<authenticationProtocol>Oauth</authenticationProtocol>
<oauthFlowType>ClientCredentials</oauthFlowType>
<principals>
<principalName>InventoryPrincipal</principalName>
<principalType>NamedPrincipal</principalType>
<sequenceNumber>1</sequenceNumber>
</principals>
</ExternalCredential>
<!-- Named Credential — endpoint definition referencing the External Credential -->
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Inventory System API</label>
<url>https://api.inventory.example.com/v2</url>
<externalCredential>Inventory_System_Credential</externalCredential>
<generateAuthorizationHeader>true</generateAuthorizationHeader>
<allowMergeFieldsInBody>false</allowMergeFieldsInBody>
<allowMergeFieldsInHeader>false</allowMergeFieldsInHeader>
</NamedCredential>
The modern Named Credential architecture (API v56.0+) splits authentication into an External Credential and endpoint routing into a Named Credential. This separation means one authentication configuration can serve multiple endpoints — and you can swap OAuth providers without touching agent logic.
External Services and OpenAPI Specs
External Services let you register an OpenAPI specification in Salesforce, which auto-generates typed Invocable Actions. Agents can invoke these actions without custom Apex — the platform handles serialization, deserialization, and error mapping.
openapi: "3.0.0"
info:
title: Customer Loyalty API
version: "1.0"
description: >
External loyalty platform API. Registered as a Salesforce External Service
so Agentforce can check and redeem loyalty points without custom Apex.
paths:
/customers/{customerId}/points:
get:
operationId: getLoyaltyPoints
summary: Get customer loyalty point balance
description: >
Returns current point balance and tier status.
Agents use this to determine discount eligibility during service interactions.
parameters:
- name: customerId
in: path
required: true
schema:
type: string
description: Salesforce Contact ID or external CRM identifier
responses:
"200":
description: Point balance and tier
content:
application/json:
schema:
type: object
properties:
points:
type: integer
description: Current redeemable point balance
tier:
type: string
enum: [Bronze, Silver, Gold, Platinum]
description: Customer loyalty tier
The key insight: every description field in that OpenAPI spec becomes context the agent uses for reasoning. Sparse descriptions produce confused agents.
Named Query API
Winter '26 introduced Named Queries (Beta) — define a SOQL query in Setup, get a REST endpoint, point an Agentforce action at it. Zero Apex for standard data reads. This is the purest form of API-first: declarative query definition with automatic REST exposure.
Pattern 3: Event-Driven Agent Triggers
Platform Events as the Signal Layer
Rather than polling or building trigger-based Apex, use Platform Events as the communication backbone between your business processes and agent actions. An event fires, a Flow subscribes, and the Flow invokes an agent action.
<!-- Case_Escalated__e — fires when a case breaches SLA -->
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Case Escalated</label>
<fullName>Case_Escalated__e</fullName>
<description>Fired when a case breaches SLA. Agents subscribe via Flow to trigger outreach or reassignment.</description>
<deploymentStatus>Deployed</deploymentStatus>
<eventType>HighVolume</eventType>
<fields>
<fullName>Case_Id__c</fullName>
<label>Case ID</label>
<type>Text</type>
<length>18</length>
<description>Salesforce record ID of the escalated case</description>
</fields>
<fields>
<fullName>Customer_Tier__c</fullName>
<label>Customer Tier</label>
<type>Text</type>
<length>20</length>
<description>Customer loyalty tier at escalation time — agents use this to select response priority</description>
</fields>
<fields>
<fullName>Hours_Open__c</fullName>
<label>Hours Open</label>
<type>Number</type>
<precision>5</precision>
<scale>1</scale>
<description>Hours the case has been open without resolution</description>
</fields>
</CustomObject>
This decouples the trigger from the response. The business process says "something happened." The agent decides what to do about it.
Change Data Capture works similarly — agents can subscribe to record changes and react without polling. The pattern is the same: the org signals, the agent reasons.
Pattern 4: Permission Architecture for Agents
Scoped Permission Sets, Not Admin Access
The most common anti-pattern I see: a Connected App with system administrator permissions because "the agent needs to access everything." This violates least privilege and creates an audit nightmare.
Instead, create agent-specific Permission Sets that grant exactly the objects and fields the agent needs:
<!-- AgentServiceAccess — minimum viable access for the Service Agent -->
<PermissionSet xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Agent Service Access</label>
<description>Scoped permissions for the Service Agent. Read on Account/Contact, read-write on Case.</description>
<hasActivationRequired>false</hasActivationRequired>
<objectPermissions>
<object>Account</object>
<allowCreate>false</allowCreate>
<allowDelete>false</allowDelete>
<allowEdit>false</allowEdit>
<allowRead>true</allowRead>
<modifyAllRecords>false</modifyAllRecords>
<viewAllRecords>false</viewAllRecords>
</objectPermissions>
<objectPermissions>
<object>Case</object>
<allowCreate>true</allowCreate>
<allowDelete>false</allowDelete>
<allowEdit>true</allowEdit>
<allowRead>true</allowRead>
<modifyAllRecords>false</modifyAllRecords>
<viewAllRecords>false</viewAllRecords>
</objectPermissions>
<fieldPermissions>
<field>Case.Status</field>
<editable>true</editable>
<readable>true</readable>
</fieldPermissions>
<fieldPermissions>
<field>Case.Priority</field>
<editable>false</editable>
<readable>true</readable>
</fieldPermissions>
</PermissionSet>
One critical gotcha: field-level security for agents fails silently. If an agent queries a field it doesn't have access to, it gets null — not an error. This means the agent might make decisions based on missing data without knowing the data is missing. Test your permission boundaries by verifying the agent receives the data you expect, not just that it doesn't throw errors.
Use the OAuth 2.0 client credentials flow for the Connected App. This is the correct pattern for non-human callers — no interactive login, no session hijacking risk, clean audit trail.
Anti-Patterns to Avoid
| Anti-Pattern | Why It Breaks Agent Readiness |
|---|---|
| Apex-only data access | Agent can't reach data without custom integration code |
| Admin-scoped Connected Apps | Violates least privilege; audit and security risk |
| Blank field descriptions | Agent can't reason about fields it doesn't understand |
| Undescribed Platform Events | Agent receives events it can't interpret |
| Hardcoded config in Apex | Agent can't read or adapt behavior dynamically |
| Inconsistent naming conventions | Agent can't generalize patterns across objects |
Agent-Readiness Checklist
| Area | Check | Agent-Ready | Failure Mode |
|---|---|---|---|
| Data Model | Field descriptions populated | All key fields have descriptions explaining purpose and valid values | Agent ignores fields it can't understand |
| Data Model | Custom Metadata for config | Agent behavior driven by queryable __mdt records | Config buried in Apex, invisible to agents |
| API Surface | Named Credentials for outbound | All external callouts centralized through Named Credentials | Credentials hardcoded or in custom settings |
| API Surface | External Services registered | OpenAPI-backed services with typed Invocable Actions | Custom Apex wrappers as the only callout path |
| Events | Platform Events defined | Events have schema descriptions; agents subscribe via Flow | No event layer — agents rely on polling or triggers |
| Permissions | Agent-scoped Permission Set | Dedicated PS with minimum required access | Shared Connected App with admin profile |
| Permissions | Client Credentials OAuth | Non-interactive flow for agent authentication | Username-password flow or session ID reuse |
| Metadata | Object descriptions populated | Describe calls return meaningful context | Objects have no descriptions — agents guess at purpose |
Where This Is Going
Salesforce is betting heavily on agents. Agent Builder is now a first-class platform tool. The Agentforce Partner Network lets ISVs ship pre-built agent skills. Industry-specific agent templates are rolling out for financial services, healthcare, and manufacturing.
The orgs that are agent-ready today have a compounding advantage: every new agent capability Salesforce ships plugs in without rework. The orgs that aren't will face the same retrofit pain that "mobile-first" laggards faced a decade ago — except the timeline is compressed.
The cost of building agent-readiness in now is low. It's metadata descriptions, clean permissions, declarative APIs, and event-driven architecture. These are things you should be doing anyway. The cost of retrofitting later — when you have 50 custom objects with no descriptions and an Apex monolith that agents can't penetrate — is high.
Start with the checklist. Audit your field descriptions. Scope your permissions. Register your external services. The agents are coming whether your org is ready or not.