Documentation

SSO

Slack

Add Sign in with Slack to VitNode using OpenID Connect. Create a Slack app without a bot, register the redirect URL and optionally restrict sign-in to one workspace.

Add a Continue with Slack button using Sign in with Slack (OpenID Connect). No bot is installed and no workspace data is read. VitNode only learns who the person is and which workspace they signed in from.

Before you begin

Set up the app

Create a Slack app

Open api.slack.com/apps, create a new app from scratch, name it and pick a development workspace.

Add the redirect URL

Open OAuth & Permissions, add a URL under Redirect URLs and save:

EnvironmentRedirect URL
Productionhttps://your-domain.com/login/sso/slack
Developmenthttps://forum-dev.example.com/login/sso/slack (an HTTPS tunnel)

Slack expects HTTPS redirect URLs, so develop through a tunnel and set VITNODE_WEB_URL to its address. VitNode builds the URL as {VITNODE_WEB_URL}/login/sso/slack.

Add the OpenID scopes

Still on OAuth & Permissions, under User Token Scopes, add openid, profile and email. Leave Bot Token Scopes empty, because Sign in with Slack does not install a bot.

Copy the credentials

Open Basic Information → App Credentials and copy the Client ID and Client Secret into server-side variables:

.env
SLACK_CLIENT_ID=1234567890.1234567890123
SLACK_CLIENT_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Add the adapter

Add SlackSSOApiPlugin to authorization.ssoAdapters in the API's vitnode.api.config.ts (where it lives), next to any adapters you already have. Keep the rest of the config as it is:

src/vitnode.api.config.ts (excerpt)
import { SlackSSOApiPlugin } from '@vitnode/core/api/adapters/sso/slack'
import { buildApiConfig } from '@vitnode/core/vitnode.config'

export const vitNodeApiConfig = buildApiConfig({
  // ...
  authorization: {
    ssoAdapters: [
      // ...
      SlackSSOApiPlugin({
        clientId: process.env.SLACK_CLIENT_ID,
        clientSecret: process.env.SLACK_CLIENT_SECRET,
        teamId: process.env.SLACK_TEAM_ID,
      }),
    ],
  },
})

No authorization block yet? Create one with just ssoAdapters, as in the SSO setup. Then restart the dev server, since .env and the API config are only read at start-up.

Check the result

Open /login, press the Slack button under Continue with, choose the workspace and allow. You return to /login/sso/slack signed in.

Restrict sign-in to one workspace

Set teamId to the workspace ID (starts with T, or E for an Enterprise organization; it is in the workspace URL app.slack.com/client/T0123ABCD). VitNode then:

  1. sends team=T0123ABCD so Slack preselects the workspace, and
  2. checks the https://slack.com/team_id claim of the validated ID token and answers 403 for any other workspace.

The second check is what makes the restriction real. Anyone can edit the authorize URL, but nobody can change the signed token.

To let people outside your workspace sign in, turn on Manage Distribution → Activate Public Distribution for the app.

Scopes and profile fields

SettingValue
Scopesopenid profile email (user scopes)
ID tokenRS256 signature, issuer https://slack.com, audience, expiry, nonce
Account ID{team_id}:{user_id}, since Slack user IDs are per workspace
Email trustedonly with email_verified: true
Profile fieldsavatar, first name, last name

The adapter reads the avatar from the ID token's picture claim. Slack documents picture on its UserInfo method but not in its ID token example, so a token may arrive without it, and the avatar then has nothing to import. First and last name come from given_name and family_name.

Troubleshooting

  • A bad_redirect_uri or redirect mismatch error. Add {VITNODE_WEB_URL}/login/sso/slack under OAuth & Permissions.
  • Slack asks to install a bot. The app has Bot Token Scopes. Remove them; sign-in needs only the user scopes above.
  • 403 after signing in. The person signed in from a workspace other than teamId.
  • Only your workspace can sign in. Public distribution is off.