| name | sf-integration |
| description | Configure Salesforce integrations: Named Credentials, Connected Apps, External
Services, Platform Events, CDC, and auth flows. Use when setting up integration
infrastructure, metadata XML, or choosing architecture patterns. Activate on
.namedCredential-meta.xml, .connectedApp-meta.xml, .platformEvent-meta.xml,
mentions of "Named Credential", "Connected App", "Platform Event", "CDC",
"External Service", or "OAuth flow".
|
| license | Apache-2.0 |
| metadata | {"author":"clientell","version":"1.0.0"} |
| allowed-tools | Read,Write,Edit,Bash(sf *),Glob,Grep |
| context | fork |
Salesforce Integration Configuration & Architecture
You are a Salesforce integration architect. Configure integration infrastructure -- Named Credentials, Connected Apps, External Services, Platform Events, CDC, and auth flows. Focus on metadata setup, security configuration, and architecture decisions.
Scope boundary: This skill covers integration configuration and metadata. For Apex callout code patterns (HttpRequest, @RestResource, SOAP, mocks), see sf-apex integration patterns.
1. Named Credentials
Named Credentials abstract endpoint URLs and authentication from code. Two architectures exist.
Legacy Named Credentials
Single metadata file combining endpoint + auth. Still supported but limited.
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService</fullName>
<label>My Service</label>
<endpoint>https://api.example.com</endpoint>
<principalType>NamedUser</principalType>
<protocol>Password</protocol>
<username>api_user</username>
</NamedCredential>
Legacy protocol values: Password, Oauth, Jwt, JwtExchange, AwsSv4, NoAuthentication.
Enhanced Named Credentials (Preferred)
Separates concerns into two metadata types:
| Component | Purpose | File suffix |
|---|
| External Credential | Auth config (protocol, principal, identity) | .externalCredential-meta.xml |
| Named Credential | Endpoint URL, references an External Credential | .namedCredential-meta.xml |
Enhanced Named Credential referencing an External Credential:
<?xml version="1.0" encoding="UTF-8"?>
<NamedCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService</fullName>
<label>My Service</label>
<endpoint>https://api.example.com</endpoint>
<externalCredential>MyService_Auth</externalCredential>
<generateAuthorizationHeader>true</generateAuthorizationHeader>
<allowMergeFieldsInBody>false</allowMergeFieldsInBody>
<allowMergeFieldsInHeader>true</allowMergeFieldsInHeader>
</NamedCredential>
External Credential with OAuth Client Credentials:
<?xml version="1.0" encoding="UTF-8"?>
<ExternalCredential xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyService_Auth</fullName>
<label>My Service Auth</label>
<authenticationProtocol>Oauth</authenticationProtocol>
<externalCredentialParameters>
<parameterName>ClientId</parameterName>
<parameterType>AuthProviderUrl</parameterType>
<parameterValue>YOUR_CLIENT_ID</parameterValue>
</externalCredentialParameters>
<externalCredentialParameters>
<parameterName>Scope</parameterName>
<parameterType>AuthParameter</parameterType>
<parameterValue>api read</parameterValue>
</externalCredentialParameters>
<principals>
<principalName>MyServicePrincipal</principalName>
<principalType>NamedPrincipal</principalType>
<sequenceNumber>1</sequenceNumber>
</principals>
</ExternalCredential>
Permission Set Mapping for External Credentials
Users access External Credentials through Permission Set mappings. Without this, callouts fail with NAMED_CREDENTIAL_NOT_FOUND.
<externalCredentialPrincipalAccesses>
<enabled>true</enabled>
<externalCredentialPrincipal>MyService_Auth - MyServicePrincipal</externalCredentialPrincipal>
</externalCredentialPrincipalAccesses>
When to Use Each
| Scenario | Recommendation |
|---|
| New integration | Enhanced Named Credential + External Credential |
| Simple, single-user auth | Legacy Named Credential (acceptable) |
| Multiple endpoints, same auth | One External Credential, multiple Named Credentials |
| Per-user OAuth tokens | External Credential with Per-User principal |
| Migration from Remote Site Settings | Move to Named Credentials for auth management |
2. Connected Apps
Connected Apps define OAuth client configuration for external applications accessing Salesforce, or for Salesforce-to-Salesforce auth.
Connected App Metadata
<?xml version="1.0" encoding="UTF-8"?>
<ConnectedApp xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyConnectedApp</fullName>
<label>My Connected App</label>
<contactEmail>admin@example.com</contactEmail>
<oauthConfig>
<callbackUrl>https://myapp.example.com/callback</callbackUrl>
<certificate>MyCertificateName</certificate>
<consumerKey>WILL_BE_GENERATED</consumerKey>
<isAdminApproved>true</isAdminApproved>
<isConsumerSecretOptional>false</isConsumerSecretOptional>
<scopes>Api</scopes>
<scopes>RefreshToken</scopes>
<scopes>OfflineAccess</scopes>
</oauthConfig>
<oauthPolicy>
<ipRelaxation>ENFORCE</ipRelaxation>
<refreshTokenPolicy>SPECIFIC_LIFETIME</refreshTokenPolicy>
<refreshTokenValidityPeriod>720</refreshTokenValidityPeriod>
<refreshTokenValidityUnits>HOURS</refreshTokenValidityUnits>
</oauthPolicy>
</ConnectedApp>
OAuth Scopes Reference
| Scope value | Meaning |
|---|
Api | Access REST/SOAP APIs |
Web | Access via browser (web scope) |
Full | Full access (avoid in production) |
RefreshToken | Enable refresh tokens (offline_access) |
OfflineAccess | Same as RefreshToken |
Chatter | Chatter REST API |
CustomPermissions | Custom permission access |
OpenID | OpenID Connect identity |
Profile | User profile info |
Email | User email |
JWT Bearer Flow Setup
For server-to-server with no interactive login:
- Generate X.509 certificate and upload to Connected App
- Pre-authorize the Connected App for the integration user's profile
- Set
isAdminApproved to true
- Consumer sends JWT signed with private key to token endpoint
- Token endpoint:
https://login.salesforce.com/services/oauth2/token
Grant type: urn:ietf:params:oauth:grant-type:jwt-bearer
Web Server Flow Setup
For user-facing applications:
- Configure callback URL (must be HTTPS, exact match)
- Set appropriate scopes (avoid
Full)
- Set IP relaxation policy based on security requirements
- Configure refresh token lifetime
IP Relaxation Options
| Value | Behavior |
|---|
ENFORCE | Enforce IP restrictions from Connected App |
BYPASS | Bypass org IP restrictions |
BYPASS_WITH_VALID_BROWSER_SESSION | Bypass only if active browser session |
3. External Services
External Services let you register an OpenAPI spec and auto-generate invocable actions usable in Flow, Einstein Bots, and Apex.
Registration Steps
- Create a Named Credential for the external API endpoint
- Navigate to Setup > External Services
- Provide the OpenAPI (Swagger) spec -- URL or paste JSON/YAML
- Salesforce parses operations and generates invocable actions
Requirements and Constraints
- OpenAPI 3.0 only (2.0/Swagger not supported for new registrations)
- Spec size limit: 100 KB
- Max 50 operations per registration
- All operations use the Named Credential for auth
- Generated actions appear as Flow External Service actions
- Supported HTTP methods: GET, POST, PUT, PATCH, DELETE
Using External Service in Flow
After registration, each operation becomes an invocable action:
- In Flow Builder, add an Action element
- Filter by category "External Services"
- Select the operation (e.g.,
createOrder, getCustomer)
- Map Flow variables to input/output parameters
- The Named Credential handles authentication automatically
External Service Metadata
<?xml version="1.0" encoding="UTF-8"?>
<ExternalServiceRegistration xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>MyExternalService</fullName>
<label>My External Service</label>
<namedCredential>MyService</namedCredential>
<schema>--- OpenAPI JSON spec inlined or referenced ---</schema>
<schemaType>OpenApi3</schemaType>
<serviceBinding>
<fieldName>operationName</fieldName>
<value>createOrder</value>
</serviceBinding>
<status>Complete</status>
</ExternalServiceRegistration>
4. Platform Events
Custom event bus for decoupled, event-driven integration within Salesforce and with external systems.
Event Definition
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Order_Event__e</fullName>
<label>Order Event</label>
<pluralLabel>Order Events</pluralLabel>
<publishBehavior>PublishAfterCommit</publishBehavior>
<fields>
<fullName>Order_Id__c</fullName>
<label>Order Id</label>
<type>Text</type>
<length>18</length>
</fields>
<fields>
<fullName>Action__c</fullName>
<label>Action</label>
<type>Text</type>
<length>50</length>
</fields>
<fields>
<fullName>Payload__c</fullName>
<label>Payload</label>
<type>LongTextArea</type>
<length>131072</length>
<visibleLines>5</visibleLines>
</fields>
</CustomObject>
Publish Behavior
| Behavior | When event publishes | Use when |
|---|
PublishAfterCommit | After transaction commits successfully | Default. Event should reflect committed data |
PublishImmediately | Immediately, even if transaction rolls back | Logging, auditing, fire-and-forget notifications |
Key rule: PublishAfterCommit events do not fire if the transaction rolls back. PublishImmediately events fire regardless -- use cautiously.
Subscriber Patterns
- Apex Trigger:
trigger OrderEventTrigger on Order_Event__e (after insert) -- runs in its own execution context
- Flow: Use a Platform Event-Triggered Flow (Record-Triggered flows cannot subscribe)
- External: CometD or Pub/Sub API (gRPC) for external system subscribers
Replay and Retention
- Standard Platform Events: retained 24 hours, replayable via Replay ID
- High-Volume Platform Events: retained 72 hours, higher throughput (150K/hour)
- Use
ReplayId in CometD or Pub/Sub API to resume from a specific point after subscriber failure
- Subscribers can set replay position:
-1 (tip), -2 (all retained events), or a specific Replay ID
5. Change Data Capture (CDC)
Streams record changes (create, update, delete, undelete) as events on the event bus.
Enabling CDC
- Setup > Change Data Capture
- Select objects to track (standard or custom)
- Changes publish to channels:
/data/<ObjectName>ChangeEvent (e.g., /data/AccountChangeEvent)
For custom objects: /data/<CustomObject__c>ChangeEvent becomes /data/Custom_Object__ChangeEvent
ChangeEventHeader Fields
Every CDC event includes a header with change metadata:
| Field | Description |
|---|
entityName | SObject API name |
changeType | CREATE, UPDATE, DELETE, UNDELETE |
changedFields | List of fields that changed (UPDATE only) |
commitTimestamp | When the change was committed |
transactionKey | Groups changes from the same transaction |
sequenceNumber | Order within a transaction |
recordIds | IDs of changed records |
commitUser | User who made the change |
commitNumber | Monotonically increasing commit sequence |
CDC Subscriber Trigger
trigger AccountChangeEventTrigger on AccountChangeEvent (after insert) {
for (AccountChangeEvent event : Trigger.new) {
EventBus.ChangeEventHeader header = event.ChangeEventHeader;
String changeType = header.getChangeType();
List<String> changedFields = header.getChangedFields();
if (changeType == 'UPDATE' && changedFields.contains('Rating')) {
// React to Rating field changes
for (String recordId : header.getRecordIds()) {
// Queue processing for each changed record
}
}
}
}
CDC vs Platform Events
| Aspect | CDC | Platform Events |
|---|
| Trigger | Automatic on record DML | Explicit publish via code/flow |
| Schema | Mirrors SObject fields | Custom-defined fields |
| Use case | React to data changes | Decouple business processes |
| Retention | 72 hours | 24h (standard) / 72h (high-volume) |
| External subscribe | Pub/Sub API, CometD | Pub/Sub API, CometD |
6. Outbound Messaging (Legacy)
SOAP-based outbound notifications triggered by Workflow Rules. Legacy pattern -- prefer Platform Events for new work.
- Fires from Workflow Rules only (not Process Builder or Flow)
- SOAP format, automatic retry with exponential backoff for 24 hours
- Endpoint must respond with Ack ID; retries until acknowledged or 24h timeout
- Max 100 fields per message
- Migrate to: Platform Events (decoupled pub/sub), Flow + HTTP Callout (declarative), or Apex Callout (complex request/response)
7. Remote Site Settings vs Named Credentials
Migration Path
Remote Site Settings only whitelist an endpoint URL. Named Credentials add auth management on top.
| Feature | Remote Site Setting | Named Credential |
|---|
| URL whitelisting | Yes | Yes (implicit) |
| Auth management | No (manual in code) | Yes (automatic) |
| Credential storage | Developer responsibility | Platform-managed |
| Per-environment config | Manual | Built-in |
| Merge fields | No | Yes (headers, body, URL) |
| Deployable | Yes | Yes |
Migration steps:
- Create Named Credential with the Remote Site URL as endpoint
- Configure auth protocol (OAuth, Password, JWT, etc.)
- Update Apex code: replace hardcoded endpoint with
callout:NamedCredentialName
- Remove auth header construction from code
- Delete the Remote Site Setting
- Test in sandbox before production
8. Auth Flow Decision Guide
| Flow | Use case | Client type | User interaction |
|---|
| JWT Bearer | Server-to-server, CI/CD, backend automation | Confidential | None (pre-authorized) |
| Web Server (Auth Code) | Web apps with user login | Confidential | Browser redirect |
| Auth Code + PKCE | SPAs, mobile apps, public clients | Public | Browser redirect |
| Client Credentials | M2M, service accounts (no user context) | Confidential | None |
| Device Flow | CLI tools, headless devices, IoT | Public or confidential | Out-of-band user auth |
| Refresh Token | Maintain sessions without re-auth | Either | None (silent) |
Decision Rules
- No user context needed? Use Client Credentials (if available) or JWT Bearer
- Backend service? JWT Bearer with X.509 certificate
- User-facing web app? Web Server flow
- Public client (SPA/mobile)? Auth Code + PKCE (mandatory)
- No browser? Device Flow
- Long-lived access? Add
RefreshToken / OfflineAccess scope
9. Gotchas
Named Credentials
- Max 100 callouts per synchronous transaction (shared with all HTTP requests)
- Enhanced Named Credentials require Permission Set mapping or callout silently fails
- External Credential parameter names are case-sensitive
generateAuthorizationHeader must be true for automatic OAuth header injection
Platform Events
- 150,000 events/hour publish limit (high-volume); 50,000 for standard
PublishAfterCommit events lost if transaction rolls back -- no retry
- At-least-once delivery: subscribers must be idempotent
- Subscriber trigger failures cause automatic retry (up to 8 retries with backoff)
EventBus.publish() does not throw exceptions -- check SaveResult for errors
Change Data Capture
- 72-hour replay window -- events older than 72h are lost
- CDC events do not fire for bulk API operations by default (must enable)
- Large transaction changes may be split across multiple events (check
sequenceNumber)
- Not available for all standard objects -- check Salesforce documentation
External Services
- OpenAPI 3.0 only -- Swagger 2.0 specs must be converted
- 100 KB spec size limit
- Max 50 operations per registration
- Complex nested schemas may not parse correctly -- flatten where possible
Connected Apps
- Consumer key/secret generated on creation -- cannot be set via metadata
- Admin approval required for JWT Bearer and Client Credentials flows
- Certificate expiry causes silent auth failures -- monitor and rotate
- IP relaxation policy applies to the Connected App, not the user's IP restrictions
- Changes to Connected App take up to 10 minutes to propagate
General
- Cannot mix synchronous callouts and DML in the same transaction without careful ordering (callout before DML, or use
@future/Queueable)
- Callout timeout max: 120 seconds per request, 120 seconds total per transaction
Workflow
- Identify the integration pattern using the decision guides above
- Use Glob and Grep to find existing integration metadata in the project
- Generate or update Named Credential / External Credential / Connected App metadata
- Configure Platform Events or CDC if event-driven
- Set up External Services if spec-driven
- Verify Permission Set mappings for External Credentials
- Suggest deployment:
sf project deploy start -d force-app/main/default/namedCredentials/
References