sf-connected-apps
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
Chinesesf-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
核心职责
- Connected App Generation: Create Connected Apps with OAuth 2.0 configuration, scopes, and callbacks
- External Client App Generation: Create ECAs with modern security model and separation of concerns
- Security Review: Analyze OAuth configurations for security best practices
- Validation & Scoring: Score apps against 6 categories (0-120 points)
- Migration Guidance: Help migrate from Connected Apps to External Client Apps
- 连接应用生成:创建带有OAuth 2.0配置、权限范围和回调地址的Connected App
- 外部客户端应用生成:采用现代安全模型与关注点分离原则创建ECA
- 安全审查:分析OAuth配置是否符合安全最佳实践
- 验证与评分:从6个维度对应用进行评分(0-120分)
- 迁移指导:协助从Connected App迁移至External Client App
Workflow (5-Phase Pattern)
工作流程(五阶段模式)
Phase 1: Requirements Gathering
阶段1:需求收集
Use AskUserQuestion to gather:
| # | 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) |
Then:
- Check existing: ,
Glob: **/*.connectedApp-meta.xmlGlob: **/*.eca-meta.xml - Create TodoWrite tasks
调用AskUserQuestion收集以下信息:
| 序号 | 问题 | 核心选项 |
|---|---|---|
| 1 | 应用类型 | Connected App / External Client App |
| 2 | OAuth流程 | Authorization Code, JWT Bearer, Device, Client Credentials |
| 3 | 使用场景 | API集成、单点登录(SSO)、移动应用、CI/CD |
| 4 | 权限范围 | api, refresh_token, full, web等 |
| 5 | 分发方式 | 本地 / 可打包(多-org) |
后续操作:
- 检查现有文件:,
Glob: **/*.connectedApp-meta.xmlGlob: **/*.eca-meta.xml - 创建TodoWrite任务
Phase 2: App Type Selection
阶段2:应用类型选择
| 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 |
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 App | External 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):
~/.claude/plugins/marketplaces/sf-skills/sf-connected-apps/templates/[template][project-root]/sf-connected-apps/templates/[template]
Template Selection:
| 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 |
Output Locations:
- Connected Apps:
force-app/main/default/connectedApps/ - External Client Apps:
force-app/main/default/externalClientApps/
模板位置(按优先级查找):
~/.claude/plugins/marketplaces/sf-skills/sf-connected-apps/templates/[template][project-root]/sf-connected-apps/templates/[template]
模板选择:
| 应用类型 | 模板文件 | 流程类型 |
|---|---|---|
| 基础Connected App | | 极简OAuth配置 |
| 完整Connected App | | Web服务器流程 |
| JWT类型Connected App | | 服务器到服务器 |
| Canvas类型Connected App | | Canvas应用 |
| External Client App | | ECA基础模板 |
| ECA全局OAuth配置 | | 全局设置 |
| ECA实例OAuth配置 | | 按-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:
| 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.
评分维度:
评分: 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 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.
| 使用场景 | 流程类型 | 是否需要PKCE | 是否需要密钥 | 模板文件 |
|---|---|---|---|---|
| Web后端 | Authorization Code | 可选 | 是 | |
| SPA/移动应用 | Authorization Code | 必填 | 否 | |
| 服务器到服务器 | JWT Bearer | 不适用 | 证书 | |
| CI/CD | JWT Bearer | 不适用 | 证书 | |
| CLI/物联网 | Device | 不适用 | 否 | |
| 服务账户 | Client Credentials | 不适用 | 是 | |
📘 详细流程说明:请查看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.xmlxml
<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.xmlxml
<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
3. Instance OAuth ():
[AppName].ecaOauth-meta.xmlxml
<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.xmlxml
<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.xmlxml
<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.xmlxml
<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 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 |
| 权限范围显示名称 | API名称 | 使用场景 |
|---|---|---|
| 访问并管理您的数据 | | REST/SOAP API访问 |
| 随时执行请求 | | 离线访问 |
| 完全访问权限 | | 完整系统访问(谨慎使用) |
| 访问您的基本信息 | | OpenID Connect认证 |
| Web访问权限 | | 浏览器端访问 |
| 访问Chatter | | Chatter REST API访问 |
| 访问自定义权限 | | 自定义权限访问 |
| 访问Einstein Analytics | | Analytics API访问 |
Security Best Practices
安全最佳实践
| 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.
| 反模式 | 风险 | 修复方案 | 评分影响 |
|---|---|---|---|
| 通配符回调地址 | 令牌劫持 | 使用具体URL | -10分 |
全局使用 | 权限过度 | 最小化权限范围 | -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
undefinedbash
undefinedList 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:
- Assess:
Glob: **/*.connectedApp-meta.xml - Create: Map OAuth settings to ECA structure
- Parallel: Deploy ECA alongside old app
- Test: Verify flows with new Consumer Key
- Cutover: Update integrations, disable old app
- 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.
快速步骤:
- 评估:
Glob: **/*.connectedApp-meta.xml - 创建:将OAuth映射到ECA结构
- 并行部署:在旧应用旁部署ECA
- 测试:使用新的Consumer Key验证流程
- 切换:更新集成配置,禁用旧应用
- 归档:30天宽限期后移除旧应用
评分优势:ECA通常比Connected App高15-20分。
📘 详细迁移步骤:请查看docs/migration-guide.md获取分步指南。
Cross-Skill Integration
跨技能集成
| Skill | Use Case | Example |
|---|---|---|
| sf-metadata | Named Credentials for callouts | |
| sf-deploy | Deploy to org | |
| sf-apex | OAuth token handling | |
| 技能 | 使用场景 | 示例 |
|---|---|---|
| sf-metadata | 用于出站请求的Named Credentials | |
| sf-deploy | 部署至org | |
| sf-apex | OAuth令牌处理 | |
Key Insights
关键要点
| 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 |
| 要点 | 说明 | 参考文档 |
|---|---|---|
| ECA vs Connected App | ECA提供更优的密钥管理和2GP打包支持 | 阶段2决策矩阵 |
| 公共客户端需启用PKCE | 移动/SPA应用必须启用PKCE | resources/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