sf-connected-apps

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

sf-connected-apps: Salesforce Connected Apps & External Client Apps

sf-connected-apps: Salesforce Connected App与External Client App

Expert in creating and managing Salesforce Connected Apps and External Client Apps (ECAs) with OAuth configuration, security best practices, and metadata compliance.
专注于创建和管理Salesforce Connected App与External Client App(ECA),涵盖OAuth配置、安全最佳实践及元数据合规性。

Core Responsibilities

核心职责

  1. Connected App Generation: Create Connected Apps with OAuth 2.0 configuration, scopes, and callbacks
  2. External Client App Generation: Create ECAs with modern security model and separation of concerns
  3. Security Review: Analyze OAuth configurations for security best practices
  4. Validation & Scoring: Score apps against 6 categories (0-120 points)
  5. Migration Guidance: Help migrate from Connected Apps to External Client Apps

  1. 连接应用生成:创建带有OAuth 2.0配置、权限范围和回调地址的Connected App
  2. 外部客户端应用生成:采用现代安全模型与关注点分离原则创建ECA
  3. 安全审查:分析OAuth配置是否符合安全最佳实践
  4. 验证与评分:从6个维度对应用进行评分(0-120分)
  5. 迁移指导:协助从Connected App迁移至External Client App

Workflow (5-Phase Pattern)

工作流程(五阶段模式)

Phase 1: Requirements Gathering

阶段1:需求收集

Use AskUserQuestion to gather:
#QuestionKey Options
1App TypeConnected App / External Client App
2OAuth FlowAuthorization Code, JWT Bearer, Device, Client Credentials
3Use CaseAPI Integration, SSO, Mobile, CI/CD
4Scopesapi, refresh_token, full, web, etc.
5DistributionLocal / Packageable (multi-org)
Then:
  1. Check existing:
    Glob: **/*.connectedApp-meta.xml
    ,
    Glob: **/*.eca-meta.xml
  2. Create TodoWrite tasks
调用AskUserQuestion收集以下信息:
序号问题核心选项
1应用类型Connected App / External Client App
2OAuth流程Authorization Code, JWT Bearer, Device, Client Credentials
3使用场景API集成、单点登录(SSO)、移动应用、CI/CD
4权限范围api, refresh_token, full, web等
5分发方式本地 / 可打包(多-org)
后续操作
  1. 检查现有文件:
    Glob: **/*.connectedApp-meta.xml
    ,
    Glob: **/*.eca-meta.xml
  2. 创建TodoWrite任务

Phase 2: App Type Selection

阶段2:应用类型选择

CriteriaConnected AppExternal 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 VersionAny61.0+ required
Quick Decision:
  • Multi-org or ISV → External Client App
  • Regulated industry → External Client App (audit requirements)
  • Simple single-org → Connected App sufficient
  • Automated DevOps → External Client App (key rotation)
评估标准Connected AppExternal Client App
单-org场景✓ 适用✓ 适用
多-org场景⚠️ 需手动配置✓ 支持2GP打包
密钥管理⚠️ 密钥可见✓ 沙箱中隐藏密钥
密钥轮换⚠️ 手动操作✓ 支持API驱动
审计追踪⚠️ 功能有限✓ 支持MFA+审计
API版本任意版本需61.0+
快速决策指南
  • 多-org或ISV场景 → 选择External Client App
  • 合规行业场景 → 选择External Client App(满足审计要求)
  • 简单单-org场景 → Connected App足够使用
  • 自动化DevOps场景 → 选择External Client App(支持密钥轮换)

Phase 3: Template Selection & Generation

阶段3:模板选择与生成

Template Locations (try in order):
  1. ~/.claude/plugins/marketplaces/sf-skills/sf-connected-apps/templates/[template]
  2. [project-root]/sf-connected-apps/templates/[template]
Template Selection:
App TypeTemplate FileFlow Type
Connected App (Basic)
connected-app-basic.xml
Minimal OAuth
Connected App (Full)
connected-app-oauth.xml
Web Server Flow
Connected App (JWT)
connected-app-jwt.xml
Server-to-Server
Connected App (Canvas)
connected-app-canvas.xml
Canvas Apps
External Client App
external-client-app.xml
Base ECA
ECA OAuth (Global)
eca-global-oauth.xml
Global settings
ECA OAuth (Instance)
eca-oauth-settings.xml
Per-org settings
Output Locations:
  • Connected Apps:
    force-app/main/default/connectedApps/
  • External Client Apps:
    force-app/main/default/externalClientApps/
模板位置(按优先级查找):
  1. ~/.claude/plugins/marketplaces/sf-skills/sf-connected-apps/templates/[template]
  2. [project-root]/sf-connected-apps/templates/[template]
模板选择
应用类型模板文件流程类型
基础Connected App
connected-app-basic.xml
极简OAuth配置
完整Connected App
connected-app-oauth.xml
Web服务器流程
JWT类型Connected App
connected-app-jwt.xml
服务器到服务器
Canvas类型Connected App
connected-app-canvas.xml
Canvas应用
External Client App
external-client-app.xml
ECA基础模板
ECA全局OAuth配置
eca-global-oauth.xml
全局设置
ECA实例OAuth配置
eca-oauth-settings.xml
按-org设置
输出位置
  • Connected App:
    force-app/main/default/connectedApps/
  • External Client App:
    force-app/main/default/externalClientApps/

Phase 4: Security Validation & Scoring

阶段4:安全验证与评分

Scoring Categories:
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)
Thresholds:
ScoreActionMeaning
80-120✅ DeployProduction-ready
54-79⚠️ ReviewMay need hardening
<54❌ BlockSecurity risk - fix first
📋 Detailed scoring: See Phase 4 in previous version for point breakdown per criteria.
评分维度
评分: XX/120 ⭐⭐⭐⭐
├─ 安全性: XX/30 (PKCE、令牌轮换、IP限制、证书)
├─ OAuth配置: XX/25 (回调地址、流程、令牌过期、OIDC)
├─ 元数据: XX/20 (必填字段、API版本、命名规范)
├─ 最佳实践: XX/20 (最小权限范围、命名主体、预认证)
├─ 权限范围: XX/15 (最小权限、无已弃用范围)
└─ 文档: XX/10 (描述、联系邮箱)
评分阈值
分数区间操作建议含义
80-120✅ 可部署符合生产环境要求
54-79⚠️ 需要审查可能需要加固
<54❌ 阻止部署存在安全风险 - 需先修复
📋 详细评分规则:请参考旧版本中的阶段4获取各标准的分数细分。

Phase 5: Deployment & Documentation

阶段5:部署与文档

Deploy:
Skill(skill="sf-deploy", args="Deploy connected apps to [target-org] with --dry-run")
Completion Output:
✓ 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

部署命令
Skill(skill="sf-deploy", args="Deploy connected apps to [target-org] with --dry-run")
完成输出示例
✓ 应用已创建: [AppName]
  类型: [Connected App | External Client App]
  位置: force-app/main/default/[connectedApps|externalClientApps]/
  OAuth流程: [flow]
  权限范围: [list]
  评分: XX/120

后续步骤:
- 从Setup > App Manager获取Consumer Key
- 测试OAuth流程(Postman/curl)
- 若为ECA:在订阅org中配置策略

Quick Reference: OAuth Flow Selection

OAuth流程选择速查

Use CaseFlowPKCESecretTemplate
Web BackendAuthorization CodeOptionalYes
connected-app-oauth.xml
SPA/MobileAuthorization CodeRequiredNo
external-client-app.xml
Server-to-ServerJWT BearerN/ACertificate
connected-app-jwt.xml
CI/CDJWT BearerN/ACertificate
connected-app-jwt.xml
CLI/IoTDeviceN/ANo
connected-app-basic.xml
Service AccountClient CredentialsN/AYes
eca-oauth-settings.xml
(ECA only)
📘 Detailed flows: See resources/oauth-flows-reference.md for implementation patterns, security checklists, and code examples.

使用场景流程类型是否需要PKCE是否需要密钥模板文件
Web后端Authorization Code可选
connected-app-oauth.xml
SPA/移动应用Authorization Code必填
external-client-app.xml
服务器到服务器JWT Bearer不适用证书
connected-app-jwt.xml
CI/CDJWT Bearer不适用证书
connected-app-jwt.xml
CLI/物联网Device不适用
connected-app-basic.xml
服务账户Client Credentials不适用
eca-oauth-settings.xml
(仅ECA支持)
📘 详细流程说明:请查看resources/oauth-flows-reference.md获取实现模式、安全检查清单及代码示例。

Metadata Structure Essentials

元数据结构要点

Connected App XML

Connected App XML示例

xml
<?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>
xml
<?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>

External Client App Files

External Client App文件示例

1. Header File (
[AppName].eca-meta.xml
):
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>
2. Global OAuth (
[AppName].ecaGlblOauth-meta.xml
):
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
.ecaGlblOauth
(abbreviated), NOT
.ecaGlobalOauth
3. Instance OAuth (
[AppName].ecaOauth-meta.xml
):
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>

1. 头文件 (
[AppName].eca-meta.xml
):
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>
2. 全局OAuth配置 (
[AppName].ecaGlblOauth-meta.xml
):
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>
⚠️ 重要提示:文件后缀为
.ecaGlblOauth
(缩写形式),而非
.ecaGlobalOauth
3. 实例OAuth配置 (
[AppName].ecaOauth-meta.xml
):
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>

OAuth Scopes Reference

OAuth权限范围参考

Scope Display NameAPI NameUse Case
Access and manage your data
Api
REST/SOAP API access
Perform requests at any time
RefreshToken
Offline access
Full access
Full
Complete access (use sparingly)
Access your basic information
OpenID
OpenID Connect
Web access
Web
Web browser access
Access Chatter
ChatterApi
Chatter REST API
Access custom permissions
CustomPermissions
Custom permissions
Access Einstein Analytics
Wave
Analytics API

权限范围显示名称API名称使用场景
访问并管理您的数据
Api
REST/SOAP API访问
随时执行请求
RefreshToken
离线访问
完全访问权限
Full
完整系统访问(谨慎使用)
访问您的基本信息
OpenID
OpenID Connect认证
Web访问权限
Web
浏览器端访问
访问Chatter
ChatterApi
Chatter REST API访问
访问自定义权限
CustomPermissions
自定义权限访问
访问Einstein Analytics
Wave
Analytics API访问

Security Best Practices

安全最佳实践

Anti-PatternRiskFixScore Impact
Wildcard callbackToken hijackingSpecific URLs-10 points
Full
scope everywhere
Over-privilegedMinimal scopes-15 points
No token expirationLong-term compromiseSet expiration-5 points
Secret in codeCredential leakNamed Credentials-15 points
PKCE disabled (mobile)Code interceptionEnable PKCE-10 points
No IP restrictionsUnauthorized accessConfigure IP ranges-5 points
🔒 Security details: See docs/security-checklist.md for comprehensive security review.

反模式风险修复方案评分影响
通配符回调地址令牌劫持使用具体URL-10分
全局使用
Full
权限范围
权限过度最小化权限范围-15分
无令牌过期设置长期权限泄露设置令牌过期时间-5分
代码中硬编码密钥凭证泄露使用Named Credentials-15分
移动应用禁用PKCE代码拦截启用PKCE-10分
无IP限制未授权访问配置IP范围-5分
🔒 安全详情:请查看docs/security-checklist.md获取全面的安全审查清单。

Scratch Org Setup (External Client Apps)

Scratch Org配置(External Client App)

json
{
  "orgName": "ECA Development Org",
  "edition": "Developer",
  "features": [
    "ExternalClientApps",
    "ExtlClntAppSecretExposeCtl"
  ]
}

json
{
  "orgName": "ECA Development Org",
  "edition": "Developer",
  "features": [
    "ExternalClientApps",
    "ExtlClntAppSecretExposeCtl"
  ]
}

Common CLI Commands

常用CLI命令

bash
undefined
bash
undefined

List Connected Apps in org

列出org中的Connected App

sf org list metadata --metadata-type ConnectedApp --target-org [alias]
sf org list metadata --metadata-type ConnectedApp --target-org [alias]

Retrieve Connected App

拉取Connected App

sf project retrieve start --metadata ConnectedApp:[AppName] --target-org [alias]
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]
sf project deploy start --source-dir force-app/main/default/connectedApps --target-org [alias]

Retrieve Consumer Key (after deployment)

获取Consumer Key(部署后)

Go to Setup > App Manager > [App] > View

前往Setup > App Manager > [App] > View


---

---

Migration: Connected App → External Client App

迁移指南:Connected App → External Client App

Quick Steps:
  1. Assess:
    Glob: **/*.connectedApp-meta.xml
  2. Create: Map OAuth settings to ECA structure
  3. Parallel: Deploy ECA alongside old app
  4. Test: Verify flows with new Consumer Key
  5. Cutover: Update integrations, disable old app
  6. Archive: Remove after 30-day grace period
Scoring Benefit: ECAs typically score 15-20 points higher.
📘 Detailed migration: See docs/migration-guide.md for step-by-step process.

快速步骤:
  1. 评估
    Glob: **/*.connectedApp-meta.xml
  2. 创建:将OAuth映射到ECA结构
  3. 并行部署:在旧应用旁部署ECA
  4. 测试:使用新的Consumer Key验证流程
  5. 切换:更新集成配置,禁用旧应用
  6. 归档:30天宽限期后移除旧应用
评分优势:ECA通常比Connected App高15-20分。
📘 详细迁移步骤:请查看docs/migration-guide.md获取分步指南。

Cross-Skill Integration

跨技能集成

SkillUse CaseExample
sf-metadataNamed Credentials for callouts
Skill(skill="sf-metadata")
→ "Create Named Credential"
sf-deployDeploy to org
Skill(skill="sf-deploy", args="Deploy to [org]")
sf-apexOAuth token handling
Skill(skill="sf-apex")
→ "Create token refresh service"

技能使用场景示例
sf-metadata用于出站请求的Named Credentials
Skill(skill="sf-metadata")
→ "创建Named Credential"
sf-deploy部署至org
Skill(skill="sf-deploy", args="Deploy to [org]")
sf-apexOAuth令牌处理
Skill(skill="sf-apex")
→ "创建令牌刷新服务"

Key Insights

关键要点

InsightDescriptionReference
ECA vs Connected AppECAs provide better secret management and 2GP packagingPhase 2 Decision Matrix
PKCE for Public ClientsAlways required for mobile/SPA appsresources/oauth-flows-reference.md
JWT Bearer for CI/CDServer-to-server auth without user interactionresources/oauth-flows-reference.md
Token RotationEnable for SPAs to prevent token reuseresources/oauth-flows-reference.md
Named CredentialsStore secrets securely, automatic refreshresources/oauth-flows-reference.md
Minimal ScopesUse least privilege (api instead of full)Phase 4 Scoring
IP RestrictionsAdd when integration has known IP rangesPhase 4 Scoring
Certificate AuthStronger than username/password for JWTresources/oauth-flows-reference.md

要点说明参考文档
ECA vs Connected AppECA提供更优的密钥管理和2GP打包支持阶段2决策矩阵
公共客户端需启用PKCE移动/SPA应用必须启用PKCEresources/oauth-flows-reference.md
CI/CD场景使用JWT Bearer无需用户交互的服务器到服务器认证resources/oauth-flows-reference.md
令牌轮换SPA应用启用令牌轮换可防止令牌复用resources/oauth-flows-reference.md
Named Credentials安全存储凭证,自动刷新令牌resources/oauth-flows-reference.md
最小权限范围遵循最小权限原则(使用api而非full)阶段4评分标准
IP限制当集成有已知IP范围时添加限制阶段4评分标准
证书认证比用户名密码更安全的JWT认证方式resources/oauth-flows-reference.md

Notes

注意事项

  • API Version: 62.0+ recommended, 61.0+ required for External Client Apps
  • Scoring: Block deployment if score < 54 (54% threshold)
  • Consumer Secret: Never commit to version control - use environment variables
  • External Client Apps: Preferred for new development (modern security model)
  • Testing: Use Postman for OAuth flow testing before production

  • API版本:推荐使用62.0+,External Client App需61.0+版本
  • 评分规则:分数<54(54%阈值)时阻止部署
  • Consumer Secret:切勿提交至版本控制 - 使用环境变量存储
  • External Client App:新开发项目优先选择(现代安全模型)
  • 测试:生产前使用Postman测试OAuth流程

Additional Resources

额外资源

Detailed References

详细参考

  • OAuth Flow Patterns: resources/oauth-flows-reference.md
    • Implementation examples (Node.js, Python, JavaScript)
    • Security checklists per flow
    • Error handling patterns
    • Named Credentials integration
  • OAuth流程模式resources/oauth-flows-reference.md
    • 实现示例(Node.js、Python、JavaScript)
    • 各流程安全检查清单
    • 错误处理模式
    • Named Credentials集成

Documentation

文档

  • OAuth Flow Diagrams: docs/oauth-flows.md
  • Security Review: docs/security-checklist.md
  • Migration Guide: docs/migration-guide.md
  • Testing & Validation: docs/testing-validation-guide.md
  • OAuth流程图docs/oauth-flows.md
  • 安全审查清单docs/security-checklist.md
  • 迁移指南docs/migration-guide.md
  • 测试与验证指南docs/testing-validation-guide.md

Examples

示例

  • Usage Examples: examples/example-usage.md

  • 使用示例examples/example-usage.md

License

许可证

MIT License. See LICENSE file. Copyright (c) 2024-2025 Jag Valaiyapathy
MIT许可证。详见LICENSE文件。 版权所有 (c) 2024-2025 Jag Valaiyapathy