If your 2GP managed package needs to call the Salesforce REST API in the subscriber's own org — a same-org callout — and you want to minimize what the subscriber has to configure after install, this FAQ documents what actually survived validation.
This is a narrow, evidence-driven FAQ about same-org API callout authentication inside a 2GP managed package, aimed at ISV developers building for AppExchange or private distribution. It focuses on scenarios where External Client App (the successor to Connected App for new integrations), ExternalClientApplication, ExtlClntAppOauthSettings, External Credential, Named Credential, and related metadata are part of the design.
The goal is practical: explain what survived deploy, package, install, and runtime validation in this scenario while keeping subscriber (customer org) setup as light as possible without pretending it can be truly zero-touch.
This is not a general Salesforce OAuth guide, not a blanket endorsement of the External Client App stack, and not a recommendation that the "newest" platform path is automatically the right one. Several obvious "modern" approaches — including the Named Credential / External Credential chain — were tested and failed for this exact narrow scenario. The rest of this document explains which ones, why, and what actually survived.
Last validated: March 2026
Salesforce behavior in this area changes frequently. Revalidate before treating any pattern here as current platform truth
How To Read Claims In This FAQ
This FAQ uses explicit confidence labels for key claims. The labels reflect how the underlying evidence was obtained, not how confident the author feels.
Label
Meaning
Proven
Validated through the full gate chain — deploy, package, install, subscriber setup, and runtime — in this scenario. For narrower claims (e.g. a specific error string), proven at the relevant gate.
Historical dead end
Tested and failed for this scenario; not a claim that Salesforce has since fixed the path or that it is broken in all contexts
External source
Documented by public sources; still secondary to hands-on validation
Inference
Plausible explanation supported by evidence but not directly proven
Unsafe to generalize
True only for this narrow scenario; do not extend to other contexts without revalidation
When no label appears, the claim is contextual guidance derived from the scenario experience.
What This Guide Covers
This FAQ covers a narrow packaged same-org authentication scenario where:
- the app needs Salesforce-to-Salesforce API access inside the subscriber org
- the package must survive real 2GP managed package creation and install
- subscriber setup should be as light as possible without pretending it can be truly zero-touch
- packaging behavior and subscriber runtime behavior both matter
What This Guide Does Not Cover
This FAQ does not try to answer:
- generic third-party outbound integrations
- every Connected App pattern
- every JWT or OAuth flow
- every Named Credential use case
- every packaging model outside this same-org 2GP scenario
- future Salesforce behavior that has not been revalidated
If you are looking for general Salesforce authentication guidance, this page is intentionally not that.
Common Questions This Guide Answers
- Which External Client App metadata types are actually packageable in a 2GP managed package?
- Why does the External Client App have to be created in the publisher org or Dev Hub?
- How does the ECA reference mechanism work between publisher and subscriber orgs?
- What publisher-side configuration has to exist before subscriber token exchange works?
- Where do you retrieve ECA metadata from?
- Why can a Named Credential work in the packaging org and still fail in the subscriber org?
- Why can an External Credential or Named Credential survive packaging-org tests and still fail after install?
- Why does a packaged Url become effectively immutable after install?
- Why did the expected Named Credential / External Credential / ExternalAuthIdentityProvider chain fail in this case?
- What same-org API authentication architecture actually worked in this 2GP scenario?
- What is the minimum honest subscriber setup for same-org auth in a 2GP managed package?
- What has to pass before you can say a Salesforce auth design really works?
Validated Architecture For This Narrow Scenario
Confidence: Proven. Unsafe to generalize.
Before the detailed FAQ, here is the high-level answer that survived full validation in this exact same-org 2GP managed package scenario.
What was packaged:
- ExternalClientApplication metadata
- ExtlClntAppOauthSettings metadata
- A Protected Custom Metadata Type record for sensitive values (protected=true)
- Apex code for direct OAuth 2.0 client_credentials token exchange (HttpRequest to the token endpoint) and same-org REST API calls
What remained publisher-side only:
- ExtlClntAppGlobalOauthSettings (not packageable; holds publisher-side global OAuth configuration)
- Client Credentials enablement for the External Client App in the publisher org Setup UI
What still required subscriber setup:
- A one-time guided admin action to enable the Client Credentials policy and bind the Run As user (execution user)
- This could not be pre-shipped in the package because the relevant policy metadata (ExtlClntAppOauthConfigurablePolicies) was not packageable in 2GP
Why "minimal setup" was honest but not zero-touch:
- The policy metadata auto-generated on install with isClientCredentialsFlowEnabled=false
- Without the one-time admin action, subscriber access token requests failed
- The admin step was a legitimate platform boundary, not a packaging workaround
This architecture bypassed the Named Credential / External Credential / ExternalAuthIdentityProvider declarative auth chain entirely at runtime — using direct Apex HttpRequest calls instead — because that chain did not survive the full packaging-and-subscriber validation cycle for this scenario.
The rest of this FAQ explains why, documents the dead ends, and provides the supporting evidence.
Why Same-Org Packaged Auth Fails At Different Stages Than You Expect
Same-org packaged auth is an edge case because Salesforce exposes different failure modes at different stages:
- setup UI behavior
- metadata deploy behavior
- package version creation
- installed subscriber behavior
- runtime token exchange and API calls
That means a design can look valid for a long time before the real blocker appears. A packaging-org (publisher org / Dev Hub) success is not the same thing as a subscriber-org (customer org / installed org) success. That gap is the central difficulty of same-org API authentication in 2GP managed packages.
1. Scope And Scenario Framing
What exact Salesforce problem does this FAQ cover?
It covers same-org Salesforce REST API access from a 2GP managed package — the scenario where your Apex code (typically an HttpRequest to the org's own REST API) needs an OAuth access token for the subscriber's org, and subscriber setup must be minimized. The design has to survive deploy, package, install, and runtime validation.
Why is same-org packaged authentication an edge case?
Because the common tutorials and docs are usually aimed at more standard outbound integration cases, not a loopback-style packaged same-org flow (sometimes called a Salesforce-to-Salesforce callout within the same org) where 2GP packaging and subscriber runtime constraints can invalidate a seemingly correct design.
The documentation gap is real: Salesforce docs cover Named Credential, External Client App, and Connected App features individually, but rarely address the intersection of same-org REST API callouts, 2GP packaging, ISV distribution, and subscriber-org runtime behavior in one place. This gap is especially painful for developers preparing for AppExchange security review, where authentication architecture is scrutinized.
2. External Client App Packaging Limits
Which External Client App metadata types are actually packageable in a 2GP managed package?
"I can't figure out which ECA metadata types actually go into the package — some deploy fine but fail at package version creation."
Confidence: Proven, with external source support. Unsafe to generalize beyond this scenario and current platform behavior.
For this same-org 2GP managed package scenario, the most useful working breakdown is:
- OauthConsumer: internal and not something you package directly
- ExtlClntAppOauthConfigurablePolicies: subscriber-side policy metadata, deployable via Metadata API but not packageable in 2GP
- ExtlClntAppConfigurablePolicies: configurable plugin-policy metadata
- ExtlClntAppGlobalOauthSettings: publisher-side global OAuth settings, not packageable
- ExtlClntAppOauthSettings: packageable
- ExternalClientApplication: packageable
The narrow packageable answer for this scenario: ExternalClientApplication and ExtlClntAppOauthSettings.
This breakdown is stronger than a single-project guess because it aligns with two independent public references as well as project testing: Justus van den Berg's Medium article and the Reddit walkthrough on packaging ECAs in 2GP (Reddit).
Do not turn it into a timeless universal matrix. Treat it as scenario-specific and revalidate against current platform behavior.
External client apps that are created in ephemeral orgs can't be packaged — Why does the External Client App have to be created in the publisher org or Dev Hub?
"My External Client App works in a scratch org but won't package."
Confidence: Proven.
Because this pattern depends on the app originating in the publisher-controlled source org, not a transient org.
When the app originates in an ephemeral org (scratch org, Partner Developer Edition org), the platform can break the packageability or subscriber resolution path. The practical failure strings here are:
- External client apps that are created in ephemeral orgs can't be packaged
- OAUTH_EC_APP_NOT_FOUND
For this scenario, the safe rule is: create the External Client App in the publisher org or Dev Hub, not in a scratch org or Partner Developer Edition org.
In practice, the publisher-side app also needs to be the packaged app of record for distribution, with distributionState=Packaged, and to have Client Credentials enabled there before the subscriber flow will behave like the validated pattern.
How does the ECA reference mechanism work between publisher and subscriber orgs?
Confidence: Inference, supported by external sources.
Current best read for this same-org 2GP scenario: the subscriber gets a reference, not a full local copy of the publisher's OAuth configuration.
In practical terms:
- the publisher org holds the master global OAuth configuration
- the subscriber installs a packaged External Client App
- the subscriber can work with installed policies, but not the hidden publisher-side OAuth settings
- server-side flows such as client_credentials can still work because the platform resolves the installed app against the publisher-side configuration
This explanation is supported by project behavior plus public ISV and Salesforce-employee sources. It is the most useful explanation for why a subscriber token exchange can succeed even though the subscriber never manually enters the Consumer Key or Consumer Secret.
The same public references also describe central key rotation and sandbox replication preserving this behavior, but those points should be treated as externally supported guidance for this narrow scenario rather than timeless platform law.
What publisher-side configuration has to exist before the subscriber flow works?
Confidence: Proven.
The critical publisher-side step is enabling Client Credentials for the External Client App in the publisher org Setup UI.
Current best read: that publisher-side action creates or updates ExtlClntAppGlobalOauthSettings, which holds the global flow state and related OAuth configuration for this scenario. That metadata is not packageable. It remains publisher-side and is then resolved or replicated through the platform's reference model.
If that step never happened, subscriber-side token exchange is likely to fail even if the package contents themselves look correct.
Why is ExtlClntAppGlobalOauthSettings not packageable here?
Confidence: External source, aligned with project testing.
Current best read for this same-org 2GP scenario: it behaves more like global or source-org configuration than package-distributed metadata. That interpretation matches observed project behavior and external references, but it should still be treated as an external-source-backed explanation, not a universal platform rule.
If you need a broader platform statement than that, treat it as an external-source-backed claim that still needs current validation.
Why are OAuth settings hidden for installed apps?
Confidence: Proven.
Because the installed app behaves like packaged reference configuration, not a normal fully editable local app. That is why messages like These Settings are hidden for Installed Apps. matter in this scenario.
The practical implication: do not design around the assumption that a subscriber will be able to open the installed app and manually complete an OAuth authorization code flow (browser-based credential flow) there.
How do you discover the correct ECA metadata member names?
Confidence: Proven.
Do not guess them.
Create or update the configuration through the Salesforce UI, retrieve the canonical metadata, and use the retrieved member names and XML shape. Some related names are auto-generated and do not match the visible app name in an obvious way.
Where do you retrieve ECA metadata from?
Confidence: Proven.
Not from just one org.
In practice, this is a dual-source retrieval workflow for same-org 2GP packaging:
- retrieve ECA metadata from the publisher org or Dev Hub
- retrieve your package source, Apex, LWCs, and the rest of the app from the development org
That split is easy to miss and is one reason External Client App packaging in 2GP can feel inconsistent if you assume everything comes from the same source org.
3. Why Named Credential, External Credential, And ExternalAuthIdentityProvider Failed For Same-Org 2GP
Can a 2GP managed package use a SecuredEndpoint Named Credential for same-org Salesforce REST API calls?
"I packaged a Named Credential and it worked in my dev org but fails after the subscriber installs it."
Confidence: Proven for this scenario. Unsafe to generalize.
Not in the expected straightforward way for this exact scenario.
That is not a claim that Named Credential never works in Salesforce. It is a narrower claim: the obvious SecuredEndpoint package-and-install path did not survive the same-org 2GP managed package constraints involved here.
Why can a SecuredEndpoint Named Credential work in the packaging org but fail in the subscriber org?
Confidence: Proven.
Because packaging validation and subscriber behavior are different gates.
A design may deploy and even package successfully while still depending on mutability, visible credentials, or runtime assumptions that do not survive in the installed subscriber org. This is the classic problem: works in packaging org fails after install, or more specifically, Named Credential works in dev org fails in subscriber org after 2GP install.
Cannot modify managed object: entity=NamedCredentialParameter — Why does the Named Credential URL become immutable after 2GP install?
"I need my subscriber to change the Named Credential URL to their own org's domain, but it's locked / read-only after install."
Confidence: Proven.
Because the Url may be required in order to ship the metadata, but once packaged it behaves like a managed parameter in the subscriber org (customer org). In plain English: required to ship, locked after install.
The failure string:
Cannot modify managed object: entity=NamedCredentialParameter, field=ParameterValue, state=installed
That makes it a trap for same-org designs that quietly depend on per-subscriber URL editing after 2GP install.
Why did Authorization Code plus ExternalAuthIdentityProvider fail after packaging?
Confidence: Historical dead end.
In this scenario, the installed subscriber org (customer org) did not retain a usable OAuth authorization code credential path. The approach looked plausible in theory, but it did not fit the low-friction packaged same-org flow that actually had to work after install. In practical search terms, this looked like a packaged ExternalAuthIdentityProvider path where usable credentials were effectively stripped or unavailable after install.
This is a dead end for this scenario, not a general critique of Authorization Code.
The specified Standard External Identity Provider doesn't exist — Why did StandardExternalIdentityProvider=Salesforce become a dead end here?
Confidence: Historical dead end for this scenario. Unsafe to generalize.
Because repeated testing did not produce a stable supported path for this same-org 2GP scenario.
The failure string:
The specified Standard External Identity Provider doesn't exist or you don't have access to it
Keep that statement narrow. It is not a global claim about every Salesforce context where StandardExternalIdentityProvider might appear.
The namespace of the named credential and external credential don't match — Why can't an unmanaged Named Credential reference a managed External Credential?
"I tried splitting managed and unmanaged components to work around the immutability problem, but namespace mismatch blocked it."
Confidence: Proven.
Ruled out for this constraint set.
Because the split-chain workaround still ran into packaging-model boundaries. In practice, it did not provide a viable escape hatch for the subscriber mutability problem in this same-org 2GP scenario.
The failure string:
The namespace of the named credential and external credential don't match
4. What Ultimately Worked In This Scenario
What same-org API authentication architecture actually worked in this 2GP scenario?
"I need my 2GP managed package to call the Salesforce REST API in the subscriber's own org — what architecture actually survived packaging and install?"
Confidence: Proven. Unsafe to generalize.
For this same-org 2GP managed package scenario, a narrow validated pattern was built around:
- packaged ExternalClientApplication
- packaged ExtlClntAppOauthSettings
- a Protected Custom Metadata Type record for sensitive values, with record-level protected=true in the managed package
- direct OAuth 2.0 client_credentials token exchange to obtain an access token
- same-org REST API calls via Apex HttpRequest against the org domain
What was packaged:
Component
Packageable in 2GP
Role
ExternalClientApplication
Yes
App identity and distribution
ExtlClntAppOauthSettings
Yes
OAuth settings for the packaged app
Protected Custom Metadata Type record
Yes
Sensitive value storage (protected=true)
Apex code (HttpRequest)
Yes
OAuth token exchange and REST API call logic
What remained publisher-side:
Component
Why
ExtlClntAppGlobalOauthSettings
Not packageable; global/publisher-side config
Client Credentials enablement in Setup UI
Publisher action; creates/updates the global settings
What still required subscriber admin action:
Step
Why
One-time guided setup action
Enables Client Credentials policy and binds Run As user (the admin who runs setup becomes the execution user)
Admin permission required
Platform security boundary; cannot be bypassed
That pattern is worth discussing because it survived real validation. It is not the only possible Salesforce auth design, and it should not be generalized beyond this use case.
Why did direct client_credentials via Apex HttpRequest work better than the Named Credential / External Credential / ExternalAuthIdentityProvider chain here?
Confidence: Proven.
For this same-org 2GP scenario, this was the first approach that cleared the full validation chain: deploy → package → install → setup → runtime.
Because it avoided the exact packaged-runtime traps that kept breaking the declarative Named Credential / External Credential chain:
- subscriber-side Url mutability problems (Named Credential URL locked / read-only / immutable after 2GP install)
- packaged credential behavior that did not survive install cleanly
- OAuth authorization code flow (browser-based) setup assumptions that were a poor fit for the intended subscriber experience
It was not "better" in every abstract sense. It was better against this specific validated constraint set.
Why was protected package storage used for sensitive values?
Confidence: Proven.
Because this flow still needed sensitive values (such as those used in the OAuth 2.0 client_credentials token exchange) while avoiding subscriber-visible configuration wherever possible. A Protected Custom Metadata Type record fit that goal better than pushing those values into editable subscriber-facing setup.
The practical detail that matters is record-level protected=true: the values are readable by package-namespace code in subscriber orgs (customer orgs), not exposed to subscriber admins, should never be logged, and can be rotated through package patch delivery.
That is a practical packaging answer for storing secrets in a 2GP managed package, not a blanket statement about Salesforce security review approval for every variant of this pattern.
5. What Subscribers Must Configure After Installing The Package
What is the minimum honest subscriber setup for same-org auth in this 2GP pattern?
"I want to avoid making my subscribers manually configure OAuth just to use my package."
Confidence: Proven.
Minimal is not zero-touch.
The honest answer is a guided one-time admin step in the subscriber org (customer org) that completes the remaining subscriber-specific setup, rather than multiple brittle manual visits across Setup pages.
Why does one-click setup still require an admin?
Confidence: Proven.
Because some setup actions depend on permission and execution context that cannot be safely or legitimately bypassed. If the platform requires an admin boundary, pretending otherwise just creates a more fragile design.
These entities are not supported: [ExtlClntAppOauthConfigurablePolicies] — Why did the setup flow need a post-install configuration step?
Confidence: Proven.
Because the required policy metadata was not packageable in its final subscriber-ready state.
The concrete pattern was:
- ExtlClntAppOauthConfigurablePolicies auto-generated on install
- it defaulted with isClientCredentialsFlowEnabled=false
- if left unchanged, token exchange failed with no client credentials user enabled
- the setup action updated the generated policy metadata to enable Client Credentials and set the Run As user (the current admin becomes the execution user)
- the policy could be deployed to the subscriber org (customer org) through Metadata API, but it could not be included in the 2GP package itself
The packaging failure string was:
These entities are not supported: [ExtlClntAppOauthConfigurablePolicies]
There was also a second constraint: enabling Client Credentials requires a valid Run As user, so the setup flow had to bind a subscriber-specific admin as the execution user at setup time.
Why can't the setup Metadata API call run from an @AuraEnabled Lightning session?
Confidence: Proven.
Because the setup action needed a Metadata API-capable session, and @AuraEnabled Apex does not provide one with sufficient scope.
In this scenario, a Lightning @AuraEnabled session did not have enough scope for the Metadata API SOAP updateMetadata call used to update the generated policy metadata. The practical workaround was to obtain an API-scoped session through a Visualforce-backed path for that one setup action.
That is implementation detail, but it matters because it explains why a seemingly simple "one button from Lightning" flow often turns into a hybrid Visualforce + Lightning setup pattern in managed packages that need to deploy metadata at install time.
6. Validation And Testing Discipline
What has to pass before you can say a Salesforce auth design actually works?
Confidence: Proven.
All of these, in order:
- deploy validation
- actual deploy
- package version creation
- install in a fresh subscriber-like org
- runtime token exchange and API behavior in the subscriber org
If you have not tested all five stages (deploy → package → install → setup → runtime), the design is still partial. Same-org auth patterns in 2GP managed packages are especially hostile to skipping steps 4 and 5.
Why does packaging-org success not prove subscriber-org success?
Confidence: Proven.
Because the packaging org (Dev Hub / publisher org) does not fully represent installed managed behavior. Subscriber install and runtime in the customer org expose different failure modes, especially when auth metadata, hidden settings, managed parameters, or packaged reference behavior are involved.
If your same-org authentication pattern only works in the packaging org, it does not work yet.
Why is "create in UI, then retrieve canonical metadata" safer than hand-writing XML?
Confidence: Proven.
Because auth metadata in this area is easy to get syntactically close while still being behaviorally wrong.
UI-created configuration gave the canonical shape, names, casing, and member values that guesswork kept missing. If you are stuck on External Client App packaging or Named Credential metadata issues, retrieve first and hand-edit second.
Why do namespace-safe object names matter for Tooling API payloads?
Confidence: Proven.
Because subscriber orgs add the managed-package namespace and packaging orgs do not.
If your Tooling payload hardcodes object API names, it can pass in one context and fail in another. The validated safe pattern was to resolve names at runtime, for example:
- Flow__c.SObjectType.getDescribe().getName() in the packaging org returns Flow__c
- the same expression in a subscriber org returns the namespaced API name
That kind of runtime resolution is especially important when building Tooling payloads dynamically in a 2GP managed package.
What packaging hygiene issues can invalidate auth conclusions?
Confidence: Proven.
Do not assume every failure proves the auth design is wrong.
Orphaned metadata, stray files on disk, or metadata unintentionally included in packaging can create misleading results. Clean packaging hygiene matters before drawing architectural conclusions about same-org auth in 2GP.
7. Documentation Gaps And Escalation Guidance
Why is this area so easy to get wrong from docs alone?
Confidence: Proven, with external source support.
Because the relevant Salesforce documentation is fragmented across multiple features and often does not answer the same-org 2GP managed package scenario directly. A doc can be real and still not cover the failure mode you are actually hitting. That is the Salesforce documentation gap problem for this edge case.
That is a coverage-gap complaint, not a generic anti-docs rant.
Should failed paths be included in a public FAQ?
Confidence: Inference, supported by project experience.
Yes, if they are labeled correctly.
Searchers often arrive through the same dead ends. The useful pattern is: name the tempting path, explain why it failed in this scenario, and clearly mark it as a stop sign rather than an alternative recommendation.
What did AI guidance get right versus wrong in this scenario?
The useful answer is mixed.
Helpful:
- identifying the create-in-UI-then-retrieve workflow
- pointing toward the publisher-side ECA reference model
- surfacing the packageability split between ExternalClientApplication, ExtlClntAppOauthSettings, and non-packageable global or configurable policy metadata
Wrong or misleading:
- that a Named Credential could be shipped without a usable Url problem
- that an unmanaged Named Credential could safely reference a managed External Credential
- that ExtlClntAppOauthConfigurablePolicies was packageable in 2GP
- that the straightforward SalesforceDefined path was a stable supported answer for this exact scenario
So the right way to use AI here is as a hypothesis generator, not as an authority or source of final architecture.
When should a developer stop guessing and escalate?
Confidence: Proven.
When the same problem keeps repeating and the signals disagree:
- docs say one thing
- setup UI suggests another
- package behavior suggests another
- subscriber runtime contradicts all of them
That is the point to stop inventing new theories and escalate the research approach. In this domain, confident guessing without validation is more expensive than admitting uncertainty early.
How should Agentforce be used when this guide does not answer the question?
Confidence: Proven experience, with caveats.
Use Agentforce as a Salesforce-specific escalation path, not as an authority.
What many developers do not realize about Agentforce:
- It is not a separate product you have to buy or a support tier you have to engage. It is available through the Salesforce Help portal and as an IDE extension.
- The barrier to trying it is much lower than most developers assume. You can pose a question and get an interactive response in minutes, not days.
- It can be significantly more interactive and context-aware than static documentation. You can ask follow-up questions, describe your specific scenario, and get narrower answers than a general doc page provides.
What Agentforce still cannot do:
- It is not authoritative. It can still be wrong, especially in narrow edge cases like same-org 2GP managed package authentication.
- It can suggest configurations that sound plausible but fail at packaging or subscriber runtime.
- Anything it suggests must still be validated through deploy, package, install, and runtime testing before you treat it as proven.
The practical recommendation: when you are stuck on a same-org auth or 2GP packaging problem that this FAQ does not answer, try Agentforce at Salesforce Help or through the IDE extension. Treat its answers as hypotheses to validate, not conclusions to ship.
Adjacent Patterns Not Validated Here
Readers may be comparing this scenario against older or more common Salesforce authentication fallbacks. This is especially common for developers migrating from Connected App to External Client App, since External Client App is the newer platform direction and Salesforce is steering ISVs toward it.
- Connected App with JWT bearer flow: a well-documented pattern for server-to-server auth in Salesforce, but not specifically validated for this same-org 2GP managed package scenario with the subscriber-friction constraints described here.
- Legacy Connected App with OAuth 2.0 Web Server flow: common for user-facing integrations, but not evaluated for this same-org packaging case.
- Session ID passthrough from Visualforce or Lightning context: sometimes used in managed packages but carries its own security and session-scope limitations.
- External Client App vs Connected App: if you are evaluating whether to use External Client App or stay with Connected App for a 2GP managed package, this FAQ only covers the External Client App path. The comparison itself is outside scope.
These approaches were not fully evaluated in this scenario. Their omission does not mean they are invalid in all contexts. It means this FAQ cannot make evidence-backed claims about them for this specific 2GP same-org use case.
If you are considering one of these alternatives, apply the same validation discipline described in this FAQ: deploy, package, install, and runtime test before treating any of them as proven for your scenario.
What We Ruled Out Definitively
Confidence: Historical dead end or Proven, depending on the path.
- A managed SecuredEndpoint Named Credential that depends on a per-subscriber URL was not viable in this 2GP scenario because the required URL became immutable after install.
- An unmanaged Named Credential referencing a managed External Credential was blocked by namespace mismatch.
- The SalesforceDefined / StandardExternalIdentityProvider same-org path was not viable in the tested 2GP path.
- The Connect REST named-credentials/named-credentials root update path was not available in the tested orgs and versions, so it was not a reliable solution path.
These are dead ends for this scenario. They are not alternative recommendations.
Public References
Official Salesforce Documentation
- Named Credentials Packaging Guide
- NC Packaging Guide: Populate External Credential Principals
- Connected App & External Client App Security Requirements for AppExchange
Community And Third-Party References
- Justus van den Berg: Rethinking Salesforce Integration Architecture: The Leap to External Client Apps
- Reddit: Packaging External Client Apps (ECA) in 2GP – avoid the ephemeral org & Global OAuth errors
- StackExchange: Client Org setup experience for Managed Package with External Client App using Client Credentials
Search Phrases This FAQ Intentionally Covers
These are realistic searches this page is meant to help with. They reflect observed failure modes and common developer questions in this domain.
Scenario framing:
- Salesforce same-org API callout 2GP
- same-org OAuth managed package
- same-org authentication 2GP managed package
- External Client App 2GP packaging
- Salesforce callout to same org
- Salesforce API call to itself managed package
- Salesforce loopback callout 2GP
- managed package calling REST API same org
- ISV managed package authentication Salesforce
- AppExchange package same-org auth
- Salesforce managed package OAuth
- 2GP managed package REST API callout
Packaging and metadata:
- which External Client App metadata types are packageable in 2GP
- ExternalClientApplication packageable
- ExtlClntAppOauthSettings packageable
- ExtlClntAppGlobalOauthSettings not packageable
- ExtlClntAppOauthConfigurablePolicies not packageable 2GP
- sf package version create auth error
- sfdx 2GP External Client App
- scratch org External Client App error
- External Client App vs Connected App 2GP
- store secrets in Salesforce managed package
- Protected Custom Metadata Type 2GP secret storage
Failure modes:
- Named Credential works in packaging org fails in subscriber org
- Named Credential works in dev org fails in subscriber org after 2GP install
- Named Credential URL immutable after 2GP install
- Named Credential URL locked read-only after install
- Cannot modify managed object entity=NamedCredentialParameter
- External client apps that are created in ephemeral orgs can't be packaged
- OAUTH_EC_APP_NOT_FOUND
- The specified Standard External Identity Provider doesn't exist
- The namespace of the named credential and external credential don't match
- no client credentials user enabled
- These entities are not supported: [ExtlClntAppOauthConfigurablePolicies]
- External Client App works in dev org fails in subscriber org
- External Credential packaging 2GP failure
- NamedCredential ExternalCredential namespace mismatch
Architecture and subscriber setup:
- same-org API access what actually worked 2GP
- minimum subscriber setup same-org auth managed package
- client_credentials same-org 2GP managed package
- OAuth 2.0 client credentials Salesforce managed package
- External Credential subscriber install failure
- managed package subscriber setup steps Salesforce
- customer org setup managed package auth
- access token same org Salesforce
- token endpoint External Client App
- HttpRequest managed package Salesforce REST API
- Run As user client credentials External Client App
Security review and validation:
- AppExchange security review authentication requirements
- Salesforce security review Named Credential requirement
- Salesforce security review callout authentication
Session and Metadata API:
- Metadata API deploy from managed package Apex
- AuraEnabled session Metadata API insufficient scope
- Visualforce session scope Metadata API
Escalation:
- Salesforce docs vs actual package behavior
- when to escalate Salesforce packaging auth problem
- Agentforce Salesforce packaging help
Validation Checklist
Before trusting any same-org packaged auth answer, check:
- Was it tested only in the packaging org, or after install too?
- Did the External Client App originate in the publisher org or Dev Hub rather than a transient org?
- Does it depend on subscriber editing of packaged auth metadata?
- Were canonical metadata names retrieved instead of guessed?
- Was ECA metadata retrieved from the publisher org while the rest of the package source came from the development org?
- Does "minimal setup" still hide a real admin dependency?
- Is the claim proven, a dead end, an inference, or just an external-source hint?
Bottom Line
The main lesson is not that one Salesforce auth feature is always good or always bad. It is not that the "newest" platform path is automatically the right choice.
The real lesson is that same-org authentication inside a 2GP managed package has to survive five distinct validation stages — deploy, package, install, subscriber setup, and runtime — and a design that clears the first three can still fail at the last two. In this domain, the gap between "this looks like it should work" and "this actually works end-to-end in the customer org" consumed hundreds of hours and over a hundred failed configurations.
Treat this area as evidence-driven, scenario-specific, and hostile to confident guessing. If your design has not been tested through all five gates in a subscriber-like org, it is still a hypothesis.

