Salesforce AppExchange
This guide defines the Salesforce AppExchange path after Slack Marketplace, the Zapier public integration scaffold, Microsoft Teams Store scoping, Google Workspace Marketplace scoping, Atlassian Marketplace scoping, Zendesk Marketplace scoping, and HubSpot App Marketplace scoping. It is a design and launch-control document, not evidence that a Salesforce AppExchange app has been built, security-reviewed, or approved.
Current Status
Salesforce AppExchange is planned as a public store follow-on. Threada already
has governed Salesforce action proposal payloads for salesforce_upsert_contact
and salesforce_upsert_opportunity in the public API action model. A private
Salesforce AppExchange API integration scaffold exists at
packages/salesforce-appexchange-app. It generates External Client App
configuration metadata, AppExchange listing metadata, asset checklist, and
readiness blockers. Public setup/support guidance now lives in
Salesforce setup and support.
The shared marketplace OAuth install path now supports Salesforce as a
contact-scoped runtime integration. The install flow uses PKCE, stores the
tenant credential in Secret Manager, and persists the authorized Salesforce
instance_url on the runtime integration so actions target the installed org.
The callback and runtime adapter restrict that instance URL to Salesforce-owned
HTTPS hosts, and the runtime adapter enforces the
marketplace_allowed_action_types metadata before execution, so marketplace
Salesforce installs cannot execute opportunity actions unless a later app
version grants and documents broader scope. This is runtime implementation
evidence, not AppExchange approval or Security Review evidence.
No authenticated Salesforce Partner Console solution/listing, linked package or API integration, real External Client App or approved/existing Connected App, AppExchange install method, Security Review submission/result, listing approval, or reviewer org evidence has been observed in this repository.
Do not submit or market a public Salesforce AppExchange listing until the chosen Salesforce package or API integration is built, installable in a reviewer-safe Salesforce org, validated end to end, linked to an AppExchange listing, accepted through Salesforce Security Review, and approved for listing.
The existing Salesforce opportunity action payload remains tenant-specific governed action work. It should not be described as a capability of the public Salesforce AppExchange app until its broader setup, field allowlist, review flow, and security-review evidence exist.
Recommended V1
The enterprise-safe first package should be a Salesforce OAuth integration using
an External Client App, or an approved/existing Connected App only where
Salesforce still permits that path, for one narrow CRM workflow: create or
update a Salesforce Contact from a governed Threada WorkItem or lead record.
That surface aligns with the live salesforce_upsert_contact action proposal
payload and avoids starting with broad object, metadata, Apex, Flow, Analytics,
file, or user-directory access.
If Salesforce’s current AppExchange listing path requires an installable managed package or metadata package for this class of solution, keep the package limited to the minimum setup, launch, or configuration surface required for review. Do not package Apex, Flow, Lightning UI, custom objects, or background jobs unless the v1 user journey requires them and the security-review evidence covers them. Do not assume a new Connected App can be created; verify the current External Client App and AppExchange partner OAuth requirements in the authenticated Salesforce partner/developer account before implementation.
Opportunity upsert can follow after contact upsert is installed, reviewable, scoped, and audited. Salesforce knowledge sync, embedded Lightning UI, Flow actions, Platform Events, outbound message/webhook subscriptions, and bidirectional sync should wait until the corresponding Salesforce extension, OAuth scope set, reviewer journey, and security review path exist.
Positioning
Threada for Salesforce should let teams create or update CRM records from governed Threada work without bypassing Threada policy, approval, idempotency, and audit controls.
The narrow v1 app should stay focused:
- Install or authorize Threada through a Salesforce External Client App, or an approved/existing Connected App only where Salesforce still permits it, using a flow that is acceptable for the AppExchange listing path.
- Bind the Salesforce org to a Threada tenant, pack, queue, or workspace mapping.
- Create or update a Salesforce Contact only from an approved Threada action proposal.
- Show clear setup-required, approval-pending, succeeded, and failed states in Threada.
- Provide public setup/support documentation that explains least-privilege Salesforce scopes, data handling, disconnect, and uninstall behavior.
The v1 app must not claim that Salesforce can execute arbitrary third-party actions through Threada. Direct external execution remains inside Threada’s governed Work, Studio, MCP, A2A, or first-party runtime paths.
Source Of Truth
Do not duplicate request or response schemas in this document. Public WorkItem
shape and governed action proposal behavior are documented in
Threada Public API and its generated OpenAPI
artifact at /openapi/public-api.openapi.yaml.
The committed source copy is docs/developers/public-api.openapi.yaml.
The committed scaffold records the intended local package posture. When real
Salesforce partner state exists, the Salesforce Partner Console
solution/listing, package or External Client App/approved Connected App
configuration, OAuth settings, selected scopes, install/revocation behavior,
tenant mapping, listing metadata, Security Review result, reviewer setup notes,
and Salesforce approval result must become the source of truth for the public
listing. The public setup/support URL for the package is
https://docs.threada.ai/integrations/salesforce-setup/.
App Surface
Governed Contact Upsert
The first reviewable capability should create or update a Salesforce Contact from a Threada WorkItem or lead record. The implementation should use Salesforce OAuth through an External Client App or approved/existing Connected App for installation and token grant, then let Threada create a governed action proposal that writes a Contact only after the configured policy and approval path permits it.
Inputs should map to the live salesforce_upsert_contact payload fields for
email, first name, last name, phone, company, title, and approved custom fields.
Do not expose arbitrary field writes in the public listing until a tenant can
review, allowlist, audit, and safely roll back those fields.
Outputs must give the Threada user a clear success, setup-required, approval-pending, or failed state and preserve the Salesforce record reference when one is returned. Do not return only a generic success message; reviewers need to see the install-to-action-to-record journey.
Setup And Tenant Mapping
The app must bind an installed Salesforce org to a Threada tenant, pack, queue, or workspace mapping before claiming production readiness. If setup is incomplete, Threada should show a clear setup-required response instead of silently dropping the request or attempting an unauthenticated Salesforce write.
Reviewer setup notes must include the exact Salesforce test org, Salesforce user, Threada tenant, test pack or queue, install or authorization URL, expected Contact fields, and cleanup instructions. Credentials, refresh tokens, cookies, raw CRM exports, and customer data must stay out of repo evidence and screenshots.
Opportunity, UI, And Sync Follow-Ons
Threada already exposes a governed payload type for Salesforce opportunity upsert. An AppExchange listing can reference that capability only after the public Salesforce app proves the required scopes, tenant mapping, field allowlists, reviewer flow, and audit behavior for opportunities.
Lightning components, Flow actions, Platform Events, outbound message/webhook subscriptions, metadata writes, packaged knowledge sync, and bidirectional CRM sync are out of scope for v1 unless the corresponding Salesforce extension or API surface is built, least-privilege scoped, tested, security-reviewed, and reviewable.
Marketplace Package Requirements
Salesforce’s ISVforce and AppExchange documentation route public listings through Partner Console, solution or package linkage, listing metadata, installation behavior, listing readiness, and Security Review. Salesforce’s REST API, OAuth, External Client App, and Connected App documentation cover authorization and record upsert behavior used by a public API integration. The final submission path must be verified in an authenticated Salesforce partner/developer account before submission.
Required package work before submission:
- Salesforce Partner Console solution/listing with the chosen install method, AppExchange listing metadata, support/privacy/terms/security links, and reviewer setup notes.
- Rebuilt
packages/salesforce-appexchange-appwith the real Partner Console solution ID, AppExchange listing ID, External Client App or approved Connected App consumer key, redirect/install URLs, public setup/support/privacy/terms URLs, and production Threada API URL. - Public External Client App, approved/existing Connected App, or package configuration with OAuth client settings, redirect URLs, app metadata, logo, least-privilege scopes, production endpoints, and linked AppExchange listing or API solution.
- AppExchange partner OAuth controls for the chosen app type, including PKCE, refresh-token rotation, a maximum 30-day refresh-token idle timeout, refresh-token IP allowlisting, and explicit reviewer evidence for each enabled control. The shared Threada callback now emits PKCE for Salesforce; production launch still needs provider app configuration, reviewer-safe install testing, and token-policy evidence from the Salesforce partner/developer account.
- Least-privilege scope set for the v1 surface. For contact-only v1, start with the narrow API and refresh-token/offline-access posture required for governed Contact upsert, and avoid opportunity, metadata, Apex, Flow, Analytics, file, user-directory, broad object, or sensitive-data scopes unless the public v1 needs them.
- Server-side OAuth callback, PKCE and state validation, token exchange, token storage in Secret Manager or approved managed identity storage, refresh-token rotation posture, disconnect, and uninstall or authorization-revocation handling.
- Tenant/org install mapping, setup-required behavior, governed contact upsert proposal creation, execution, idempotency, audit trail, and failure handling.
- Contact field allowlist and safe custom-field mapping.
- Public setup documentation that is not behind a paywall or sign-in screen, is specific to the Threada Salesforce integration, and explains install, configuration, use, disconnect/revoke, and data effects.
- Public support, privacy, terms, security/data-handling, shared-data, and pricing disclosures that match the selected scopes and actual app behavior.
- AppExchange listing copy, logo/screenshots, install/start URL, test instructions, setup notes, reviewer org access, and cleanup instructions.
- Salesforce Security Review and listing approval before public-readiness claims.
Explicit Non-Goals
- No public Salesforce AppExchange claim until a first-class Salesforce package or API integration exists and Salesforce Security Review/listing approval passes.
- No username/password flow, session ID reuse, personal access token, private External Client App or connected-app secret, or manually provisioned tenant secret as the public AppExchange install path.
- No unmanaged direct Salesforce writes from the AppExchange app.
- No broad CRM, metadata, Apex, Flow, Analytics, file, user-directory, org-admin, or sensitive-data scopes unless the exact v1 capability requires them and the implementation is validated end to end.
- No packaged Salesforce knowledge sync claim until an authenticated, tenant-scoped, auditable sync path exists and is security-reviewed.
- No customer-data screenshots, raw CRM exports, Salesforce org dumps, OAuth tokens, cookies, or private tenant payloads in AppExchange screenshots or review evidence.
- No positioning as a generic “AI agent executes any Salesforce action” app. Public copy must stay anchored to governed CRM record work, setup, and review.
Review Gates
Implemented:
- Public API action types include
salesforce_upsert_contactandsalesforce_upsert_opportunity. - Public BFF mapping code converts Salesforce contact and opportunity payloads into governed action requests and proposal views.
- Public API docs and generated OpenAPI are published.
- A private Salesforce AppExchange API integration scaffold exists at
packages/salesforce-appexchange-appfor an OAuth-installed, Contact-only v1 app withapiandrefresh_tokenscopes. - Public Salesforce setup/support documentation exists at Salesforce setup and support.
Missing:
- Real Salesforce Partner Console solution/listing, linked package or API integration, install method, listing metadata, and reviewer setup path.
- Real Salesforce External Client App, approved/existing Connected App, or package configuration, OAuth consumer key, redirect URLs, app metadata, logo, and selected scopes in the authenticated Salesforce partner/developer account.
- AppExchange partner OAuth controls: PKCE, refresh-token rotation, maximum 30-day refresh-token idle timeout, refresh-token IP allowlisting, and reviewer evidence for each enabled control.
- Salesforce OAuth install, callback, token storage, refresh-token rotation, disconnect, uninstall, and authorization-revocation handling.
- Tenant/org mapping, setup-required, approval-pending, success, failure, idempotency, and audit behavior.
- Contact field allowlist and safe custom-field handling.
- AppExchange listing copy, screenshots, test instructions, setup notes, reviewer org access, cleanup instructions, and Security Review materials.
- Salesforce Security Review, listing approval evidence, and approval report.
Blocked:
- Public Salesforce AppExchange submission is blocked until the first-class Salesforce package or API integration exists, runtime behavior is implemented and testable, OAuth/scopes are least-privilege, Security Review/listing gates pass, and reviewer setup is complete.
Launch Checklist
- Choose the v1 Salesforce surface. Recommended first: OAuth-installed governed Salesforce Contact upsert from a Threada WorkItem or lead record.
- Confirm the current AppExchange listing path from an authenticated Salesforce partner/developer account, including whether the v1 is listed as an API integration, External Client App, approved/existing Connected App, managed package, or another Salesforce solution type.
- Rebuild
packages/salesforce-appexchange-appwith real Partner Console solution ID, listing ID, OAuth consumer key, redirect/install URLs, support/privacy/terms/setup URLs, and production API URL. - Create the Partner Console solution/listing and link the package or API integration required by the chosen listing path.
- Create the Salesforce External Client App, approved/existing Connected App, or package configuration with OAuth redirect URLs, app metadata, logo, production endpoints, and least-privilege scopes.
- Enable and document AppExchange partner OAuth controls: PKCE, refresh-token rotation, maximum 30-day refresh-token idle timeout, and refresh-token IP allowlisting.
- Implement server-side OAuth PKCE/state validation, token exchange, Secret Manager storage, refresh-token rotation posture, disconnect, uninstall, and authorization-revocation handling.
- Implement tenant/org mapping, setup-required behavior, governed contact upsert proposal creation, execution, idempotency, audit trail, and failure handling.
- Add a Contact field allowlist and safe custom-field mapping.
- Use the public setup/support guide and prepare AppExchange listing copy.
- Create sanitized screenshots and demo material for install, setup, proposal, approval, execution, resulting Salesforce Contact, and disconnect.
- Prepare Salesforce reviewer org access, test account, setup notes, Security Review materials, and cleanup instructions through Salesforce-approved channels.
- Submit through Salesforce Security Review/AppExchange listing review and resolve all review issues before claiming AppExchange readiness.