Supported providers
| Provider | PKCE | Revoke endpoint | Default scopes |
|---|---|---|---|
| GitHub | No | No | repo, read:user |
| Yes (S256) | Yes | gmail.modify, calendar, drive.readonly | |
| Slack | No | No | channels:read, chat:write, groups:read |
| Linear | Yes (S256) | Yes | read, write |
Required environment variables
Each provider requires a client ID and secret:| Variable | Description |
|---|---|
GITHUB_CLIENT_ID | GitHub OAuth app client ID |
GITHUB_CLIENT_SECRET | GitHub OAuth app client secret |
GOOGLE_CLIENT_ID | Google OAuth client ID |
GOOGLE_CLIENT_SECRET | Google OAuth client secret |
SLACK_CLIENT_ID | Slack app client ID |
SLACK_CLIENT_SECRET | Slack app client secret |
LINEAR_CLIENT_ID | Linear OAuth app client ID |
LINEAR_CLIENT_SECRET | Linear OAuth app client secret |
| Variable | Description |
|---|---|
AUTH_REDIRECT_BASE | Base URL for OAuth callbacks (e.g., https://toolshed.example.com/api/auth) |
ENCRYPTION_KEY | AES encryption key (base64) for encrypting stored tokens |
OAuth flow
- Initiate: Client calls
GET /api/auth/:provider/login?userId=X - Redirect: Server redirects to provider’s authorization URL with scopes and state parameter
- Authorize: User grants permission in the provider’s UI
- Callback: Provider redirects to
GET /api/auth/:provider/callbackwith authorization code - Exchange: Server exchanges code for access/refresh tokens
- Store: Tokens are encrypted with AES and stored in the token store
Provider-specific behavior
Google:- Uses
access_type=offlineto get a refresh token - Uses
prompt=consentto ensure refresh token is always returned - PKCE with S256 code challenge
- PKCE with S256 code challenge
- Scope separator is comma (not space)
- Scope separator is comma
- Token response uses
authed_user.access_token(not top-levelaccess_token)
Token vending
Plugins don’t handle OAuth directly. Instead, they callctx.auth.getToken(provider) in their handlers, which:
- Calls
POST /api/tokens/vendwith the user’s ID and provider - The server decrypts the stored token
- If expired, attempts automatic refresh
- Returns a usable access token
Connecting from the CLI
Oncetoolshed login is implemented, it will:
- Open a browser to the server’s auth page
- User authorizes each provider they want to use
- Session token is stored in
~/.toolshed/config.json