Conversation
Signed-off-by: yosrixp <yosrixp@yahoo.com>
MartinTrojans
approved these changes
Apr 14, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This work integrates the Slack MCP surface with the MCP OAuth Proxy (MoP) using Slack's OAuth v2 authorization code flow with PKCE. The user authenticates directly with Slack's consent screen — scoped to a specific Yahoo workspace (
teamparameter) — and MoP stores the resulting access and refresh tokens as-is (pass-through). Token refresh against Slack's/api/oauth.v2.user.accessendpoint is handled by a dedicatedTokenExchangeServiceSlackImplusing the Nimbus OAuth 2.0 SDK. Resource mapping andas: slackfollow the same patterns as other OAuth consent providers (e.g. GitHub, Google Workspace).Architecture (high level)
flowchart LR subgraph Client_side MCP_Client[MCP client] end subgraph MoP Token_EP[MoP token endpoint] Authz[AuthorizerService] SlackRes[SlackResource /slack/authorize] SlackEx[TokenExchangeServiceSlackImpl] end subgraph Slack Consent[Slack OAuth v2 consent screen] TokenEP[Slack token endpoint /api/oauth.v2.user.access] AuthTest[Slack auth.test UserInfo] MCP_Srv[Slack MCP server] end MCP_Client -->|OAuth / token grant + resource URI| Token_EP Token_EP --> Authz Authz -->|No stored token for slack| SlackRes SlackRes -->|Redirect with user_scope + team + PKCE| Consent Consent -->|Authorization code callback| SlackRes SlackRes -->|Exchange code for tokens| TokenEP TokenEP -->|access_token + refresh_token| SlackRes SlackRes -->|Verify user identity| AuthTest SlackRes -->|Store tokens| Authz Authz -->|Pass-through: return stored token| MCP_Client MCP_Client -->|Slack access_token| MCP_Srv Authz -.->|Token expired| SlackEx SlackEx -->|Refresh grant + client credentials| TokenEP TokenEP -.->|New access_token + refresh_token| SlackExKey design decisions:
access_tokenis returned directly to the MCP client.code_challenge/code_verifierautomatically; no S256 plumbing in application code.user_scopeinstead ofscope— Slack's OAuth v2 uses a non-standarduser_scopeparameter for user-level permissions, passed as anextra-paramin the OIDC tenant config.teamextra-param restricts the consent screen to the configured Yahoo Slack workspace (OurOathTestfor dev/staging,ouryahoofor production).TokenExchangeServiceSlackImpl.refreshWithUpstreamToken()builds aRefreshTokenGrantagainst Slack's token endpoint usingClientSecretBasicauthentication.auth.test— Slack has no standard OIDC UserInfo endpoint. The OIDC tenant is configured withuser-info-path: https://slack.com/api/auth.testandid-token-required: falseso Quarkus validates the user via Slack's bearer-authenticated API instead.OAuth consent and token storage flow
sequenceDiagram participant Client participant MoP participant Slack as Slack OAuth v2 Client->>MoP: Request token for Slack resource MoP->>MoP: No stored Slack token for user MoP->>Slack: Redirect to consent screen (user_scope + team + PKCE) Slack-->>MoP: Authorization code callback MoP->>Slack: Exchange code for tokens (/api/oauth.v2.user.access) Slack-->>MoP: access_token + refresh_token (12h TTL) MoP->>Slack: Verify user via /api/auth.test Slack-->>MoP: user_id, team, enterprise MoP->>MoP: Store tokens keyed by user_id MoP-->>Client: Return stored Slack access_tokenToken refresh flow
sequenceDiagram participant MoP participant SlackEx as TokenExchangeServiceSlackImpl participant Slack as Slack /api/oauth.v2.user.access MoP->>SlackEx: Upstream refresh token expired access_token SlackEx->>Slack: POST refresh_token grant + client credentials Slack-->>SlackEx: New access_token + refresh_token SlackEx->>MoP: Updated TokenWrapper MoP->>MoP: Store refreshed tokensSlack user scopes
users:read.emailusers:readsearch:read.userssearch:read.publicsearch:read.privategroups:historychannels:historycanvases:read