Personal Access Tokens
Personal access tokens (PATs) let scripts, CI/CD pipelines, and integrations authenticate with WarmHub without interactive login.
Overview
Section titled “Overview”| Property | Detail |
|---|---|
| Format | Signed JWT |
| Default expiry | 30 days |
| Maximum expiry | 1 year (set via --expires) |
| Management | CLI (wh token) or HTTP API (/api/pats) |
| Management auth | Interactive login only — PATs cannot create or revoke other PATs |
Token Lifecycle
Section titled “Token Lifecycle”Create → Use → [Expire] → Revoke- Create — Generate a named token via
wh token create(requires interactive login). The token value is displayed once — save it immediately. - Use — Set the
WH_TOKENenvironment variable or pass the token in theAuthorization: Bearerheader. WarmHub validates the token on every request. - Expire — Tokens expire after 30 days by default. Use
--expiresto set a custom duration (max 1 year). Expired tokens are rejected immediately. - Revoke — Revoke a token by name via
wh token revoke. Takes effect immediately.
Expired and revoked tokens are preserved for audit visibility.
Scopes
Section titled “Scopes”Scopes limit what a token can do. They are optional — a token created without scopes has the full permissions of its owning user.
Each scope entry binds a resource to a set of permissions:
| Tier | Resource format | Example | Meaning |
|---|---|---|---|
| Repo-scoped | org/repo | myorg/myrepo | Specific repo only |
| Org-level | org | myorg | All repos in org, capped by role |
| Global wildcard | (omitted) | All resources, capped by role |
More specific entries take precedence. Scopes can only narrow access, never escalate beyond the user’s role.
Available permissions
Section titled “Available permissions”| Permission | Grants |
|---|---|
repo:read | Read repositories, queries, shapes |
repo:write | Commits, shape mutations |
repo:configure | Subscriptions, credentials, repo settings |
repo:admin | Delete, archive, visibility |
org:read | Read org profiles |
org:configure | Create repos, manage members |
org:admin | Rename, archive org |
Scopes are independent — repo:write does not include repo:read. Request the specific permissions your token needs.
CLI Usage
Section titled “CLI Usage”All wh token commands require interactive login — you cannot manage tokens using a PAT.
Create a token
Section titled “Create a token”The --scope flag accepts three forms:
| Form | Meaning | Example |
|---|---|---|
org/repo=perms | Repo-scoped | --scope myorg/myrepo=repo:read,repo:write |
org=perms | Org-level (all repos in org) | --scope myorg=repo:read |
perms | Global wildcard (all resources) | --scope repo:read,repo:write |
Separate multiple permissions with commas. Repeat --scope for multiple entries.
# Full user access, default 30-day expirywh token create --name ci-bot
# Repo-scoped tokenwh token create --name ci-bot --scope myorg/myrepo=repo:read,repo:write
# Org-level wildcard (all repos in org, capped by role)wh token create --name org-reader --scope myorg=repo:read
# Global wildcard with description and custom expirywh token create -n deploy --scope repo:write -d "Deploy pipeline" --expires 90d
# Multiple scopes — repeat --scope for each entrywh token create --name ci-bot \ --scope myorg/private-repo=repo:read,repo:write \ --scope myorg=repo:read \ --expires 90dName-restricted tokens with --scopes-json
Section titled “Name-restricted tokens with --scopes-json”For advanced use cases, the --scopes-json flag accepts a JSON array of scope entries with optional allowedMatches patterns that restrict which thing names the token can access. A thing name is the WarmHub object name portion of a wref, such as Signal/temp-1 or Config/settings.
--scopes-json is mutually exclusive with --scope — you cannot use both in the same command.
Each entry in the JSON array has:
| Field | Type | Required | Description |
|---|---|---|---|
resource | string | No | Resource name: "org/repo", "org", or omitted (global wildcard) |
permissions | string[] | Yes | Permissions for this resource |
allowedMatches | string[] | No | Glob patterns restricting which thing names this entry can access. Repo-scoped entries only ("org/repo"). Ignored on org-level and global entries. |
allowedMatches behavior:
- Repo-scoped entries only.
allowedMatcheson org-level or global wildcard entries is stripped with a warning — name restrictions require a specific repo target. - Patterns use glob syntax, for example
Signal/*orConfig/**. - When present, the token can only read or write thing names that match at least one pattern.
- Omitting
allowedMatchesmeans no name restriction for that entry. - An empty array (
[]) is valid and means deny-all for that entry.
With --scopes-json, you can assign different allowedMatches to different permissions on the same resource by using multiple entries. Each (resource, permission) pair must be unique — duplicate pairs are rejected with a validation error.
# Read Signal/* and Config/*, but only write Signal/*wh token create --name scoped-bot --scopes-json '[ {"resource":"myorg/myrepo","permissions":["repo:read"],"allowedMatches":["Signal/*","Config/*"]}, {"resource":"myorg/myrepo","permissions":["repo:write"],"allowedMatches":["Signal/*"]}]'
# Simple name restriction — read-only for Signal/*wh token create --name reader --scopes-json '[ {"resource":"myorg/myrepo","permissions":["repo:read"],"allowedMatches":["Signal/*"]}]'
# No allowedMatches — same as --scope shorthandwh token create --name full --scopes-json '[ {"resource":"myorg/myrepo","permissions":["repo:read","repo:write"]}]'The token is printed once. Save it to a secret store or environment variable immediately.
List tokens
Section titled “List tokens”wh token listwh token list --jsonShows all your tokens with their status (active, expired, or revoked) and scopes.
View a token
Section titled “View a token”wh token get --name ci-botShows token details: name, description, scopes, status, creation date, and expiry.
Revoke a token
Section titled “Revoke a token”wh token revoke --name ci-botRevocation is immediate. The token is rejected on the next API request.
Using PATs with the HTTP API
Section titled “Using PATs with the HTTP API”Pass the token in the Authorization header:
curl -H "Authorization: Bearer eyJhbGciOi..." \ https://api.warmhub.ai/api/repos/myorg/myrepo/headOr with the CLI via WH_TOKEN:
export WH_TOKEN=eyJhbGciOi...wh commit create --add cave --shape Location \ --data '{"x":3,"y":7}' -m "Add cave"Using PATs with MCP Clients
Section titled “Using PATs with MCP Clients”MCP clients like Claude and Cursor normally authenticate via OAuth automatically. However, PATs are useful when:
- Your organization restricts custom MCP connectors
- You’re on WSL2, where the OAuth callback can’t reach the browser
- You want to authenticate a dev instance without configuring OAuth
Use mcp-remote as a stdio bridge with your PAT:
{ "mcpServers": { "warmhub": { "command": "npx", "args": [ "-y", "mcp-remote@latest", "https://api.warmhub.ai/mcp", "--header", "Authorization:${WH_TOKEN}", "--transport", "http-only" ], "env": { "WH_TOKEN": "Bearer eyJhbGciOi..." } } }}This works in both Claude Desktop (claude_desktop_config.json) and Claude Code (.mcp.json). The --transport http-only flag ensures HTTP Streamable transport.
See the MCP Quickstart for standard OAuth-based setup.
Security Model
Section titled “Security Model”- No escalation. PAT management (create, list, revoke) requires interactive login. A PAT cannot create or manage other tokens.
- Scope enforcement. Each API endpoint checks the token’s scopes. A
repo:readtoken cannot push commits. - Immediate revocation. Revoking a token takes effect on the next request — there is no grace period.
- Name restrictions. Token names must be alphanumeric, hyphens, and underscores only (URL-safe).
Limitations
Section titled “Limitations”- No token rotation. To rotate, revoke the old token and create a new one.
- No web UI. Tokens are managed via the CLI or HTTP API only.
- No SDK surface. The SDK does not yet have a
client.token.*API for token management.
Next Steps
Section titled “Next Steps”- Getting Access — interactive login and account creation
- HTTP API Authentication — PAT management endpoint reference
- CLI Commands — full
tokencommand reference