# Salesforce: OAuth app setup and approval
Self-serve · Partial · updated 27 Oct 2026 · https://oauth-guide.akshatsethi.com/apps/salesforce

> You can connect your own org through an External Client App (ECA) in under an hour. Letting any customer's org connect is harder. Since Spring '26 you can't create new Connected Apps by default, so you have to ship your ECA in a second-generation (2GP) managed package. Each customer org then installs that package, or its admin approves your app. Salesforce doesn't review the app unless you want an AppExchange listing.

- **Your hands-on work:** 1–3 days
- **Waiting on Salesforce:** None
- **First user can connect:** Today, in about 30–60 minutes, using a free Developer Edition org and a Local ECA
- **Why Self-serve:** No Salesforce review is needed before other orgs can connect, but you must package and distribute the ECA yourself, and each customer org's admin controls whether it can be used. The AppExchange security review applies only if you want a public listing.
- **Using Composio?** Composio has a managed Salesforce OAuth app, so you can prototype before building your own ECA. Customer orgs may still need their admin to approve or install that app, and your name won't be on the consent screen until you use your own.

## Path to launch
### Build: Your org
- Who can connect: Users of the org where you created a Local External Client App
- What users see: The standard Salesforce login, then an 'Allow Access' consent screen showing your app name and scopes
- Effort: 30–90 min · Wait: None
- Next: Create a Packaged ECA, put it in a 2GP managed package and promote a released version
- _(Community [3, 8], medium confidence)_

### Launch: Customer orgs
- Who can connect: Users in any Salesforce org that has installed your managed package and whose policies let users self-authorize
- What users see: The Salesforce login and consent screen. Before that, an admin installs your package from its install URL, or from AppExchange if you're listed.
- Effort: 1–3 days · Wait: None
- _(Community [3, 4, 5], medium confidence)_

## Before you start
- [ ] **Salesforce org with ECA permission** (You). ECAs are available in Professional, Performance, Unlimited and Developer editions. A free Developer Edition org works. Your user needs the 'Create, Edit, and Delete External Client Apps' permission. _(Community [3], medium confidence)_
- [ ] **Redirect URI** (Agent). The callback URL of your OAuth client, which you enter on the ECA. _(Community [3, 8])_
- [ ] **Dev Hub org and namespace org** (You). Packaging needs a Dev Hub plus a separate org that registers a namespace. One org can't do both. The Dev Hub must stay alive for as long as the package is used, because it holds the global OAuth settings. _(Community [3, 4], medium confidence)_
- [ ] **Salesforce CLI** (Agent). You use the Salesforce CLI to create the 2GP package and its package versions. _(Community [3], medium confidence)_
- [ ] **Customer admin cooperation** (You). Each customer org's admin has to install your package. Otherwise users need the 'Approve Uninstalled Connected Apps' or 'Use Any API Client' permission before they can authorize an app that isn't installed. _(Community [6, 12], medium confidence)_

## Steps
1. **Sign up for a Developer Edition org** (You, 10–20 min). Create a free Developer Edition org, or use an org you already have in a supported edition. Make sure your user can create External Client Apps. _(Community [3], medium confidence)_
   - Agent: A person has to sign up and verify the email address.
   - Watch out: Nango's guide reports invalid_client_id errors when the developer user's password contains special characters.
2. **Create an External Client App** (Agent, 15–30 min). In Setup, open External Client App Manager and create a new app. Choose Local for single-org testing, or Packaged if you will distribute it. Enable OAuth and enter your redirect URI. _(Community [3, 8, 2], medium confidence)_
   - Setup > Quick Find 'External Client App Manager' > New External Client App
   - Fill in the app name, API name and contact email
   - Distribution State: Local (testing) or Packaged (multi-org)
   - Enable OAuth; Callback URL = your redirect URI
   - Scopes: 'Manage user data via APIs (api)' and 'Perform requests at any time (refresh_token, offline_access)'
   - Enable the Authorization Code and Credentials flow; leave 'Require secret' and 'Require PKCE' on
   - Policies tab: Refresh Token Policy = valid until revoked
   - Agent: An agent can fill in this form once a person is signed in. A person should copy the consumer secret.
   - Watch out: New Connected Apps are disabled by default since Spring '26. Don't follow older guides that tell you to create one in App Manager.
3. **Copy consumer key and secret into your client** (You, 5–10 min). Open the app's Settings tab, reveal the Consumer Key and Consumer Secret, and store them in your OAuth client. Use https://login.salesforce.com/services/oauth2/authorize and /token, or test.salesforce.com for sandboxes. _(Community [3], medium confidence)_
   - Agent: An agent can set the key and endpoints. A person handles the secret.
   - Watch out: Every customer org has its own instance_url, which comes back in the token response. Store it for each connection.
4. **Test a connection with your own org** (Agent, 10–20 min). Run the authorization code flow, approve access, and call an API endpoint using the returned instance_url. _(Inferred, low confidence)_
   - Agent: An agent can run the test. A person signs in.
   - Watch out: Changes to ECA settings may take a few minutes to apply.
5. **Set up a Dev Hub and register a namespace** (You, 1–3 h). Enable Dev Hub in one org, register a namespace in a separate org, and link the namespace to the Dev Hub in Namespace Registries. _(Community [3], medium confidence)_
   - Agent: An agent can click through Setup once a person is signed in to both orgs.
   - Watch out: You can't enable Dev Hub and register a namespace in the same org.
6. **Package the Packaged ECA in a 2GP package** (Agent, 2–8 h). Create the ECA in the Dev Hub with Distribution State set to Packaged. Then use the CLI to create a managed package, retrieve the ECA metadata, create a package version and promote it to released. Leave the global OAuth settings out of the package and keep them in the Dev Hub. _(Community [3, 4, 5], medium confidence)_
   - sf org login web (Dev Hub)
   - sf package create --package-type Managed
   - Retrieve the ECA metadata; set the namespace and package ID in sfdx-project.json
   - sf package version create, then sf package version promote
   - Agent: An agent can run the CLI commands once a person has authenticated the CLI.
   - Watch out: One community report says a packaged ECA failed in subscriber orgs with OAUTH_AUTHORIZATION_BLOCKED 'Cross-org OAuth flows are not supported'. Check how the OAuth link is configured in an installed test org before you launch.
7. **Give customers the package install URL** (You, 30–60 min). Send customers' admins the install URL and ask them to set the app's policy so users can self-authorize. Install it in a second test org first to confirm that OAuth works across orgs. _(Community [3, 6], medium confidence)_
   - Agent: An agent can test in a second org once a person is signed in.
   - Watch out: Users in orgs that haven't installed the app are blocked unless they hold the Approve Uninstalled Connected Apps or Use Any API Client permission.
8. **Optionally submit for AppExchange security review** (You, Unknown). You need this only for a public AppExchange listing. Older Salesforce docs list a $2,550 review fee plus a $150 listing fee for paid solutions, and no fee for free ones. _(Docs [9, 10], low confidence)_
   - Agent: Joining the partner program, paying and submitting have to be done by a person.
   - Watch out: The fees above come from older doc versions, so check the current Packaging Guide.

## When you get stuck
- **You can't create a Connected App, or the option is missing in App Manager.** Since Spring '26, creating new Connected Apps is disabled by default in every org, both in the UI and through the API Fix: Use an External Client App. Salesforce Support can grant a temporary exception, but Salesforce has said it will remove that option. _(Community [2, 7, 11])_
- **Users in a customer org get blocked at authorization because the app isn't installed.** Since September 2025, users need the Approve Uninstalled Connected Apps or Use Any API Client permission to authorize apps that aren't installed Fix: Have the customer admin install your package or app, or grant that permission to the users who connect _(Community [6, 12], medium confidence)_
- **OAUTH_AUTHORIZATION_BLOCKED: Cross-org OAuth flows are not supported for this external client app.** Unclear. One community reply points to how the global OAuth settings and the OAuth link are set up on the packaged ECA. Fix: Make sure the subscriber ECA refers to the source org's global OAuth settings, and keep the source org alive. If it still fails, contact Salesforce support. _(Community [5], low confidence)_

## Not confirmed yet
- **Does a packaged ECA support cross-org web-server OAuth with one consumer key out of the box?** The only community thread on this has no confirmed fix, and the official docs returned 403 to the fetcher To resolve: Install your package in a second Developer Edition org and test, or read help.salesforce.com 'External Client Apps' packaging docs
- **Do the uninstalled-app permission rules apply to ECAs the same way they apply to Connected Apps?** The sources only discuss Connected Apps To resolve: Test with an org that hasn't installed your package, and check Salesforce help
- **What are the current AppExchange security review fees and turnaround times?** Only older doc versions were found, with no timeline To resolve: Check the latest ISVforce/Packaging Guide or ask your Partner Account Manager

## Sources
1. [Composio managed auth toolkits](https://docs.composio.dev/toolkits/managed-auth.md) (Composio docs). Checked 27 Oct 2026
2. [Salesforce connected apps and external client apps](https://striim.com/docs/en/salesforce-connected-apps-and-external-client-apps.html) (Striim docs). Checked 27 Oct 2026
3. [Salesforce API OAuth app setup](https://nango.dev/docs/api-integrations/salesforce/salesforce-api-oauth-app-setup.md) (Nango docs). Checked 27 Oct 2026
4. [Package and distribute external client apps](https://trailhead.salesforce.com/content/learn/modules/external-client-app-basics/package-and-distribute-external-client-apps) (Salesforce Trailhead). Checked 27 Oct 2026
5. [Cross-org OAuth blocked for packaged ECA](https://trailhead.salesforce.com/pt-BR/trailblazer-community/feed/0D5KX00000pNxl60AC) (Trailblazer Community). Checked 27 Oct 2026
6. [Salesforce Connected App Security Changes](https://www.soliantconsulting.com/blog/salesforce-connected-app-security-changes-sept2025/) (Soliant Consulting). Checked 27 Oct 2026
7. [New Connected Apps Can No Longer Be Created in Spring '26](https://help.salesforce.com/s/articleView?id=005228017&type=1) (Salesforce Help). Not yet checked
8. [Create an External Client App](https://developer.salesforce.com/docs/platform/mobile-sdk/guide/eca-create.html) (Salesforce Developers). Checked 27 Oct 2026
9. [Security review fees](https://developer.salesforce.com/docs/atlas.en-us.230.0.packagingGuide.meta/packagingGuide/security_review_fees.htm) (Salesforce Developers). Not yet checked
10. [How the AppExchange Security Review Submission Loop Works](https://tekunda.com/blog/How-the-AppExchange-Security-Review-Submission-Loop-Works) (Tekunda). Not yet checked
11. [Connected Apps (Packaging Guide)](https://developer.salesforce.com/docs/atlas.en-us.packagingGuide.meta/packagingGuide/connected_apps.htm) (Salesforce Developers). Checked 27 Oct 2026
12. [Salesforce connected app usage restrictions](https://docs.movedata.io/troubleshooting/connection-and-authentication/salesforce-connected-app-usage-restrictions/) (MoveData docs). Not yet checked

Wrong or out of date? POST https://oauth-guide.akshatsethi.com/api/reports with {"app": "salesforce", "step": 2, "message": "what you saw"} (step is optional), or call the report_problem MCP tool. The next research run checks it.
Followed it? Say how it went: POST https://oauth-guide.akshatsethi.com/api/reports with {"app": "salesforce", "outcome": "worked" | "waiting" | "stuck", "step": 3, "message": "what happened"}, or call the report_setup MCP tool.
