Authentication Flow
The complete authentication sequence involves four steps:1. Start OAuth Flow
The CLI generates a PKCE code verifier and challenge, then calls POST /v1/auth/slack/start with:- User’s email address
- PKCE code challenge (SHA-256 hash of code verifier)
- CLI callback URL (localhost listener)
2. Slack Authorization
The CLI opens the authorization URL in the user’s browser. The user authenticates with Slack and grants the requested OpenID scopes (openid, profile, email).
3. OAuth Callback
Slack redirects back to the API’s callback endpoint with an authorization code. The API:- Exchanges the code for a Slack access token
- Fetches the user’s Slack profile (email, team ID, user ID)
- Validates the email matches the requested email
- Validates the Slack team ID matches
ALLOWED_SLACK_TEAM_ID - Generates a short-lived login code
- Redirects to the CLI’s callback URL with the login code
4. Token Exchange
The CLI receives the login code and calls POST /v1/auth/exchange with:- Login code from the callback
- PKCE code verifier (original random string)
Token Types
JWT Access Token
- Type: JSON Web Token (JWT)
- Algorithm: HS256
- Default TTL: 15 minutes (configurable via
JWT_ACCESS_TTL_MINUTES) - Usage: Include in
Authorization: Bearer <token>header for all authenticated API requests - Payload:
Refresh Token
- Type: Opaque token (48-byte random base64url string)
- Default TTL: 30 days (configurable via
REFRESH_TTL_DAYS) - Storage: SHA-256 hash stored in database
- Usage: Call POST /v1/auth/refresh to obtain a new token pair
- Security: Single-use only - each refresh revokes the old token and issues a new pair
Refresh tokens are revoked and replaced on each use. Always store the new refresh token returned from the
/auth/refresh endpoint.Security Constraints
Email Domain Restriction
Only email addresses ending with the configuredALLOWED_EMAIL_DOMAIN are permitted. The API enforces this during both the start flow and Slack callback validation.
Slack Workspace Restriction
Only users from the Slack workspace matchingALLOWED_SLACK_TEAM_ID can authenticate. This is validated after fetching the Slack profile.
PKCE Protection
PKCE prevents authorization code interception attacks:- The CLI generates a random
code_verifier(43-128 characters) - Computes
code_challenge = SHA256(code_verifier)in base64url - Sends only the challenge during
/auth/start - Proves possession of the verifier during
/auth/exchange - The API rejects exchanges where
SHA256(code_verifier) != stored_code_challenge
Session Expiration
OAuth sessions expire 10 minutes after creation. Login codes must be exchanged before the session expires.Token Refresh Strategy
To maintain continuous access:- Monitor the
expiresInSecvalue returned with each token pair - Refresh tokens proactively before the access token expires (e.g., at 50-80% of TTL)
- Handle
401 INVALID_TOKENerrors by attempting a refresh - If refresh fails, re-authenticate via the full OAuth flow
Error Codes
Common authentication error codes:| Code | Description |
|---|---|
EMAIL_NOT_ALLOWED | Email domain not in ALLOWED_EMAIL_DOMAIN |
WORKSPACE_NOT_ALLOWED | Slack team ID does not match ALLOWED_SLACK_TEAM_ID |
INVALID_STATE | OAuth state parameter is invalid or expired |
OAUTH_EXPIRED | OAuth session expired (>10 minutes) |
EMAIL_MISMATCH | Authenticated email does not match requested email |
INVALID_CODE_VERIFIER | PKCE code verifier does not match challenge |
LOGIN_CODE_EXPIRED | Login code not exchanged within session TTL |
INVALID_REFRESH_TOKEN | Refresh token is invalid, revoked, or expired |
Next Steps
Start Flow
Begin the OAuth authentication flow
Token Exchange
Exchange login code for access tokens
Refresh Token
Refresh expired access tokens

