Documentation
Everything you need to know about using Schlussel for authentication.
📋 Formula Specification
Formulas are JSON files that describe how to authenticate with a provider. They contain everything needed: OAuth endpoints, auth methods, API definitions, and optional public clients.
Root Fields
| Field | Required | Description |
|---|---|---|
schema |
Yes | Version identifier. Must be "v2". |
id |
Yes | Unique identifier (e.g., github, stripe). Used in CLI commands and storage keys. |
label |
Yes | Human-readable name for display. |
description |
Yes | Brief description of the provider and supported auth methods. |
methods |
Yes | Object defining authentication methods (see below). |
apis |
Yes | Object defining API endpoints. |
clients |
No | Array of public OAuth clients that can be used without registration. |
identity |
No | Hints for multi-account scenarios (label and hint text). |
Methods
Each method defines an authentication flow. Common method names:
authorization_code- OAuth with browser redirect (hasendpoints.authorize+endpoints.token)device_code- OAuth device flow (hasendpoints.device+endpoints.token)mcp_oauth- MCP OAuth with dynamic registration (hasdynamic_registrationobject)api_key/personal_access_token- Manual credential (hasscriptwithcopy_key)
| Field | Description |
|---|---|
label |
Human-readable name for the method. |
endpoints |
OAuth endpoints: authorize, token, device, registration. |
scope |
Space-separated OAuth scopes. |
register |
Instructions for manual app registration (url and steps array). |
script |
Array of steps guiding the user through authentication. |
dynamic_registration |
RFC 7591 client registration parameters. |
Script Steps
| Type | Description | Value |
|---|---|---|
open_url |
User should open a URL | URL or {placeholder} |
enter_code |
User should enter a code | Code or {user_code} |
copy_key |
User should paste an API key | - |
wait_for_callback |
Wait for OAuth callback | - |
wait_for_token |
Poll for device code completion | - |
Placeholders
| Placeholder | Description |
|---|---|
{authorize_url} |
Full authorization URL with parameters |
{verification_uri} |
URL to enter device code |
{verification_uri_complete} |
URL with code pre-filled |
{user_code} |
Code user enters at verification URL |
APIs
Each API defines an endpoint that can be called with tokens from specified methods:
| Field | Required | Description |
|---|---|---|
base_url |
Yes | API base URL. |
auth_header |
Yes | How to pass the token (e.g., Authorization: Bearer {token}). |
methods |
Yes | Array of method names that produce valid tokens. |
docs_url |
No | Link to API documentation. |
spec_url |
No | Link to machine-readable spec. |
spec_type |
No | Type of spec: openapi, graphql, asyncapi. |
Public Clients
Clients bundled with the formula that users can use without registering their own OAuth app:
| Field | Required | Description |
|---|---|---|
name |
Yes | Identifier for the client. |
id |
Yes | OAuth client ID. |
secret |
No | OAuth client secret (for confidential clients). |
source |
No | URL where this client ID was found. |
methods |
No | Which methods this client supports (default: all OAuth methods). |
redirect_uri |
No | Fixed redirect URI required by this client. |
Storage Keys
Tokens are stored using a conventional key format:
{formula_id}:{method}:{identity}
Examples:
github:device_code:personal- GitHub device code token for "personal" identitylinear:authorization_code:acme- Linear OAuth token for "acme" workspacestripe:api_key- Stripe API key (no identity)
Example Formula
{
"schema": "v2",
"id": "github",
"label": "GitHub",
"description": "Authenticate with GitHub using OAuth device code flow...",
"apis": {
"rest": {
"base_url": "https://api.github.com",
"auth_header": "Authorization: Bearer {token}",
"docs_url": "https://docs.github.com/en/rest",
"spec_type": "openapi"
}
},
"clients": [
{
"name": "gh-cli",
"id": "178c6fc778ccc68e1d6a",
"secret": "34ddeff2b558a23d38fba...",
"source": "https://github.com/cli/cli",
"methods": ["device_code", "authorization_code"]
}
],
"identity": {
"label": "Account",
"hint": "e.g., personal, work"
},
"methods": {
"device_code": {
"endpoints": {
"device": "https://github.com/login/device/code",
"token": "https://github.com/login/oauth/access_token"
},
"scope": "repo read:org gist",
"script": [
{ "type": "open_url", "value": "{verification_uri}" },
{ "type": "enter_code", "value": "{user_code}" },
{ "type": "wait_for_token" }
]
},
"personal_access_token": {
"register": {
"url": "https://github.com/settings/tokens/new",
"steps": ["Generate a new token", "Copy the token"]
},
"script": [
{ "type": "copy_key", "note": "Paste your GitHub PAT" }
]
}
}
}
💻 CLI Reference
The Schlussel CLI is the primary interface for authenticating with providers and managing tokens.
Installation
# Using mise (recommended)
mise use -g github:pepicrft/schlussel
# Or build from source
git clone https://github.com/pepicrft/schlussel
cd schlussel && zig build
Commands
schlussel run <formula>
Authenticate with a provider and obtain a token.
| Option | Description |
|---|---|
-m, --method <str> |
Authentication method (required if multiple methods available). |
-c, --client <str> |
Use a public client from the formula. |
-r, --redirect-uri <str> |
Redirect URI for auth code flow (default: http://127.0.0.1:0/callback). |
-f, --formula-json <str> |
Load a custom formula JSON file. |
--client-id <str> |
Override OAuth client ID. |
--client-secret <str> |
Override OAuth client secret. |
-s, --scope <str> |
OAuth scopes (space-separated). |
--credential <str> |
Secret for non-OAuth methods (api_key). |
-i, --identity <str> |
Identity label for storage key (e.g., workspace name). |
--open-browser <true|false> |
Open the authorization URL automatically (default: true). |
-j, --json |
Emit machine-readable JSON output. |
-n, --dry-run |
Show auth steps and URLs without executing. Useful for previewing the flow. |
schlussel token <action>
Token management operations.
| Action | Description |
|---|---|
get |
Retrieve a stored token. Requires --key or --formula. |
list |
List all stored tokens. Can be filtered. |
delete |
Delete a stored token. Requires --key or --formula. |
Options:
| Option | Description |
|---|---|
-k, --key <str> |
Full token storage key (e.g., github:device_code:personal). |
--formula <str> |
Filter/query by formula ID (e.g., github). |
--method <str> |
Filter/query by auth method (e.g., device_code). |
--identity <str> |
Filter/query by identity label (e.g., personal). |
--no-refresh |
Disable auto-refresh. By default, OAuth2 tokens are refreshed if expired or expiring soon, using cross-process locking. |
-j, --json |
Output in JSON format. |
schlussel token get automatically refreshes OAuth2 tokens that are expired or expiring soon. It acquires a cross-process lock before refreshing, ensuring that if multiple processes request the same token simultaneously, only one performs the refresh while others wait and receive the updated token. Use --no-refresh to disable this behavior.
Examples
# Authenticate with GitHub (auto-selects public client and method)
schlussel run github
# Preview auth flow without executing
schlussel run github --dry-run
# Authenticate with a specific method
schlussel run github --method device_code
# Use a specific public client
schlussel run github --client gh-cli
# Authenticate with Linear for a specific workspace
schlussel run linear --method authorization_code --identity acme
# Use a custom formula file
schlussel run acme --formula-json ~/formulas/acme.json
# Get JSON output for scripting
schlussel run github --json
# List all tokens
schlussel token list
# List tokens for a specific formula
schlussel token list --formula github
# Get token using key components (auto-refreshes if expiring)
schlussel token get --formula github --method device_code
# Get token without auto-refresh
schlussel token get --formula github --method device_code --no-refresh
# Get token as JSON
schlussel token get --formula github --method device_code --json
# Delete a token
schlussel token delete --key github:device_code:personal