Skip to main content

I have developed a Slack app that integrates with Salesforce. The app's Request URL currently points to my Salesforce Site endpoint, which processes Slack events using Apex. 

 

I plan to distribute this app to multiple customers. Each customer has their own Salesforce org and therefore their own Site URL. 

 

Since a Slack app supports only a single Request URL, how can a multi-tenant architecture be implemented?     What is the recommended approach for routing requests to the correct customer's Salesforce org after they install the app? 

1 answer
  1. Sep 17, 10:27 AM

    This is a standard multi-tenant integration problem, and the fix is to decouple "receiving the Slack event" from "which customer org owns it":

    1. One shared gateway endpoint, not tied to any single customer's org — this can be a lightweight middleware/integration layer (or even a Salesforce org dedicated to this purpose) that owns the single Slack Request URL and does nothing except receive and route events.
    2. A mapping table (Slack team_id → customer org connection details: instance URL, auth credentials/Named Credential reference) that the gateway looks up on every incoming event. Slack always sends team_id in the payload, so this is your routing key.
    3. Outbound callout to the correct org, authenticated per customer — typically via a Named Credential (or OAuth JWT flow) configured per tenant, so the gateway calls each customer's org as an external system rather than the customer's org receiving Slack traffic directly.
    4. Verify the Slack signature per request against the shared signing secret before you even look at the payload — since one endpoint now serves multiple tenants, this check is what prevents cross-tenant spoofing.

    If you don't want to stand up separate middleware, you can implement the gateway as a small Salesforce org (or a lightweight Apex REST service in whichever org you already control) whose only job is to receive, authenticate, look up the tenant, and forward — keeping the actual business logic entirely inside each customer's own org. The two things that matter most in this shape (a single inbound entry point fanning out to multiple external systems based on a routing key) are keeping the routing/credential mapping data out of code (custom metadata or a protected custom object) and validating the source signature before any routing decision. 

0/9000