Loading...
Loading...
Creates and manages Salesforce Connected Apps and External Client Apps with 120-point scoring. Use when configuring OAuth flows, creating connected apps, setting up JWT bearer auth, or managing API access policies.
npx skill4agent add jaganpro/claude-code-sfskills sf-connected-apps| # | Question | Key Options |
|---|---|---|
| 1 | App Type | Connected App / External Client App |
| 2 | OAuth Flow | Authorization Code, JWT Bearer, Device, Client Credentials |
| 3 | Use Case | API Integration, SSO, Mobile, CI/CD |
| 4 | Scopes | api, refresh_token, full, web, etc. |
| 5 | Distribution | Local / Packageable (multi-org) |
Glob: **/*.connectedApp-meta.xmlGlob: **/*.eca-meta.xml| Criteria | Connected App | External Client App |
|---|---|---|
| Single Org | ✓ Good | ✓ Good |
| Multi-Org | ⚠️ Manual | ✓ 2GP Packaging |
| Secret Mgmt | ⚠️ Visible | ✓ Hidden in sandboxes |
| Key Rotation | ⚠️ Manual | ✓ API-driven |
| Audit Trail | ⚠️ Limited | ✓ MFA + audit |
| API Version | Any | 61.0+ required |
~/.claude/plugins/marketplaces/sf-skills/sf-connected-apps/templates/[template][project-root]/sf-connected-apps/templates/[template]| App Type | Template File | Flow Type |
|---|---|---|
| Connected App (Basic) | | Minimal OAuth |
| Connected App (Full) | | Web Server Flow |
| Connected App (JWT) | | Server-to-Server |
| Connected App (Canvas) | | Canvas Apps |
| External Client App | | Base ECA |
| ECA OAuth (Global) | | Global settings |
| ECA OAuth (Instance) | | Per-org settings |
force-app/main/default/connectedApps/force-app/main/default/externalClientApps/Score: XX/120 ⭐⭐⭐⭐
├─ Security: XX/30 (PKCE, token rotation, IP restrictions, certificates)
├─ OAuth Config: XX/25 (callbacks, flows, token expiration, OIDC)
├─ Metadata: XX/20 (required fields, API version, naming)
├─ Best Practices: XX/20 (minimal scopes, named principal, pre-auth)
├─ Scopes: XX/15 (least privilege, no deprecated)
└─ Documentation: XX/10 (description, contact email)| Score | Action | Meaning |
|---|---|---|
| 80-120 | ✅ Deploy | Production-ready |
| 54-79 | ⚠️ Review | May need hardening |
| <54 | ❌ Block | Security risk - fix first |
📋 Detailed scoring: See Phase 4 in previous version for point breakdown per criteria.
Skill(skill="sf-deploy", args="Deploy connected apps to [target-org] with --dry-run")✓ App Created: [AppName]
Type: [Connected App | External Client App]
Location: force-app/main/default/[connectedApps|externalClientApps]/
OAuth Flow: [flow]
Scopes: [list]
Score: XX/120
Next Steps:
- Retrieve Consumer Key from Setup > App Manager
- Test OAuth flow (Postman/curl)
- For ECA: Configure policies in subscriber org| Use Case | Flow | PKCE | Secret | Template |
|---|---|---|---|---|
| Web Backend | Authorization Code | Optional | Yes | |
| SPA/Mobile | Authorization Code | Required | No | |
| Server-to-Server | JWT Bearer | N/A | Certificate | |
| CI/CD | JWT Bearer | N/A | Certificate | |
| CLI/IoT | Device | N/A | No | |
| Service Account | Client Credentials | N/A | Yes | |
📘 Detailed flows: See resources/oauth-flows-reference.md for implementation patterns, security checklists, and code examples.
<?xml version="1.0" encoding="UTF-8"?>
<ConnectedApp xmlns="http://soap.sforce.com/2006/04/metadata">
<label>My Integration App</label>
<contactEmail>admin@company.com</contactEmail>
<description>Integration description</description>
<!-- OAuth Configuration -->
<oauthConfig>
<callbackUrl>https://app.example.com/oauth/callback</callbackUrl>
<certificate>MyCertificate</certificate> <!-- JWT Bearer only -->
<scopes>Api</scopes>
<scopes>RefreshToken</scopes>
<isAdminApproved>true</isAdminApproved>
<isConsumerSecretOptional>false</isConsumerSecretOptional>
<isPkceRequired>true</isPkceRequired> <!-- Public clients -->
</oauthConfig>
<!-- OAuth Policy -->
<oauthPolicy>
<ipRelaxation>ENFORCE</ipRelaxation>
<refreshTokenPolicy>infinite</refreshTokenPolicy>
<isRefreshTokenRotationEnabled>true</isRefreshTokenRotationEnabled>
</oauthPolicy>
</ConnectedApp>[AppName].eca-meta.xml<ExternalClientApplication xmlns="http://soap.sforce.com/2006/04/metadata">
<label>My External Client App</label>
<contactEmail>admin@company.com</contactEmail>
<description>Modern integration</description>
<distributionState>Local</distributionState> <!-- or Packageable -->
</ExternalClientApplication>[AppName].ecaGlblOauth-meta.xml<ExtlClntAppGlobalOauthSettings xmlns="http://soap.sforce.com/2006/04/metadata">
<callbackUrl>https://app.example.com/oauth/callback</callbackUrl>
<externalClientApplication>My_App_Name</externalClientApplication>
<label>Global OAuth Settings</label>
<isPkceRequired>true</isPkceRequired>
<isConsumerSecretOptional>true</isConsumerSecretOptional>
</ExtlClntAppGlobalOauthSettings>⚠️ Important: File suffix is(abbreviated), NOT.ecaGlblOauth.ecaGlobalOauth
[AppName].ecaOauth-meta.xml<ExtlClntAppOauthSettings xmlns="http://soap.sforce.com/2006/04/metadata">
<externalClientApplication>My_App_Name</externalClientApplication>
<commaSeparatedOauthScopes>api,refresh_token</commaSeparatedOauthScopes>
<label>Instance OAuth Settings</label>
<isClientCredentialsEnabled>false</isClientCredentialsEnabled>
</ExtlClntAppOauthSettings>| Scope Display Name | API Name | Use Case |
|---|---|---|
| Access and manage your data | | REST/SOAP API access |
| Perform requests at any time | | Offline access |
| Full access | | Complete access (use sparingly) |
| Access your basic information | | OpenID Connect |
| Web access | | Web browser access |
| Access Chatter | | Chatter REST API |
| Access custom permissions | | Custom permissions |
| Access Einstein Analytics | | Analytics API |
| Anti-Pattern | Risk | Fix | Score Impact |
|---|---|---|---|
| Wildcard callback | Token hijacking | Specific URLs | -10 points |
| Over-privileged | Minimal scopes | -15 points |
| No token expiration | Long-term compromise | Set expiration | -5 points |
| Secret in code | Credential leak | Named Credentials | -15 points |
| PKCE disabled (mobile) | Code interception | Enable PKCE | -10 points |
| No IP restrictions | Unauthorized access | Configure IP ranges | -5 points |
🔒 Security details: See docs/security-checklist.md for comprehensive security review.
{
"orgName": "ECA Development Org",
"edition": "Developer",
"features": [
"ExternalClientApps",
"ExtlClntAppSecretExposeCtl"
]
}# List Connected Apps in org
sf org list metadata --metadata-type ConnectedApp --target-org [alias]
# Retrieve Connected App
sf project retrieve start --metadata ConnectedApp:[AppName] --target-org [alias]
# Deploy
sf project deploy start --source-dir force-app/main/default/connectedApps --target-org [alias]
# Retrieve Consumer Key (after deployment)
# Go to Setup > App Manager > [App] > ViewGlob: **/*.connectedApp-meta.xml📘 Detailed migration: See docs/migration-guide.md for step-by-step process.
| Skill | Use Case | Example |
|---|---|---|
| sf-metadata | Named Credentials for callouts | |
| sf-deploy | Deploy to org | |
| sf-apex | OAuth token handling | |
| Insight | Description | Reference |
|---|---|---|
| ECA vs Connected App | ECAs provide better secret management and 2GP packaging | Phase 2 Decision Matrix |
| PKCE for Public Clients | Always required for mobile/SPA apps | resources/oauth-flows-reference.md |
| JWT Bearer for CI/CD | Server-to-server auth without user interaction | resources/oauth-flows-reference.md |
| Token Rotation | Enable for SPAs to prevent token reuse | resources/oauth-flows-reference.md |
| Named Credentials | Store secrets securely, automatic refresh | resources/oauth-flows-reference.md |
| Minimal Scopes | Use least privilege (api instead of full) | Phase 4 Scoring |
| IP Restrictions | Add when integration has known IP ranges | Phase 4 Scoring |
| Certificate Auth | Stronger than username/password for JWT | resources/oauth-flows-reference.md |