WorkOS CLI for installing AuthKit integrations and managing WorkOS resources.
# Run directly with npx (recommended)
npx workos
# Or install globally
npm install -g workos
workos- 15 Framework Support: Next.js, React Router, TanStack Start, React SPA, Vanilla JS, SvelteKit, Node.js (Express), Python (Django), Ruby (Rails), Go, .NET (ASP.NET Core), Kotlin (Spring Boot), Elixir (Phoenix), PHP (Laravel), PHP
- AI-Powered: Uses Claude to intelligently adapt to your project structure
- Security-First: Masks API keys, redacts from logs, saves to .env.local
- Smart Detection: Auto-detects framework, package manager, router type
- Live Documentation: Fetches latest SDK docs from WorkOS and GitHub
- Full Integration: Creates routes, middleware, environment vars, and UI
- Agent & CI Ready: Non-TTY auto-detection, JSON output, structured errors, headless installer with NDJSON streaming
Depending on your framework, the installer creates:
- ✅ Authentication routes (callback, sign-in, sign-out)
- ✅ Middleware for route protection
- ✅ Environment variable configuration
- ✅ SDK installation with correct package manager
- ✅ UI components showing login status
- ✅ User info display (name, email)
Get your credentials from dashboard.workos.com:
- API Key (sk_test_xxx or sk_live_xxx) - For server-side frameworks only
- Client ID (client_xxx) - Required for all frameworks
Security: API keys are masked during input and redacted in logs.
workos [command]
Commands:
install Install WorkOS AuthKit into your project
auth Manage authentication (login, logout, status)
env Manage environment configurations (add, remove, switch, list, claim)
doctor Diagnose WorkOS integration issues
skills Manage WorkOS skills for coding agents (install, uninstall, list)
Skills are automatically installed to detected coding agents when you run `workos install`. Use `workos skills list` to check status.
Resource Management:
organization (org) Manage organizations
user Manage users
role Manage roles (RBAC)
permission Manage permissions (RBAC)
membership Manage organization memberships
invitation Manage user invitations
session Manage user sessions
connection Manage SSO connections
directory Manage directory sync
event Query events
audit-log Manage audit logs
feature-flag Manage feature flags
webhook Manage webhooks
config Manage redirect URIs, CORS, homepage URL
portal Generate Admin Portal links
vault Manage encrypted secrets
api-key Manage per-org API keys
org-domain Manage organization domains
Local Development:
emulate Start a local WorkOS API emulator
dev Start emulator + your app in one command
Workflows:
seed Declarative resource provisioning from YAML
setup-org One-shot organization onboarding
onboard-user Send invitation and assign role
debug-sso Diagnose SSO connection issues
debug-sync Diagnose directory sync issuesAll management commands support --json for structured output (auto-enabled in non-TTY) and --api-key to override the active environment's key.
When you run workos install without credentials, the CLI automatically provisions a temporary WorkOS environment — no account needed. This lets you try AuthKit immediately.
# Install with zero setup — environment provisioned automatically
workos install
# Check your environment
workos env list
# Shows: unclaimed (unclaimed) ← active
# Claim the environment to link it to your WorkOS account
workos env claimManagement commands work on unclaimed environments with a warning reminding you to claim.
The compound workflow commands compose multiple API calls into common operations. These are the highest-value commands for both developers and AI agents.
Provision permissions, roles, organizations, and config from a YAML file. Tracks created resources for clean teardown.
# Apply a seed file
workos seed --file workos-seed.yml
# Tear down everything the seed created (reads .workos-seed-state.json)
workos seed --cleanExample workos-seed.yml:
permissions:
- name: Read Posts
slug: posts:read
- name: Write Posts
slug: posts:write
roles:
- name: Editor
slug: editor
permissions: [posts:read, posts:write]
- name: Viewer
slug: viewer
permissions: [posts:read]
organizations:
- name: Acme Corp
domains: [acme.com]
config:
redirect_uris:
- http://localhost:3000/callback
cors_origins:
- http://localhost:3000
homepage_url: http://localhost:3000Resources are created in dependency order (permissions → roles → organizations → config). State is tracked in .workos-seed-state.json so --clean removes exactly what was created.
Creates an organization with optional domain verification, roles, and an Admin Portal link in a single command.
# Minimal: just create the org
workos setup-org "Acme Corp"
# Full: org + domain + roles + portal link
workos setup-org "Acme Corp" --domain acme.com --roles admin,viewerSends an invitation to a user with an optional role assignment. With --wait, polls until the invitation is accepted.
# Send invitation
workos onboard-user alice@acme.com --org org_01ABC123
# Send with role and wait for acceptance
workos onboard-user alice@acme.com --org org_01ABC123 --role admin --waitInspects an SSO connection's state and recent authentication events. Flags inactive connections and surfaces auth event history for debugging.
workos debug-sso conn_01ABC123Inspects a directory's sync state, user/group counts, recent events, and detects stalled syncs.
workos debug-sync directory_01ABC123Test your WorkOS integration locally without hitting the live API. The emulator provides a full in-memory WorkOS API replacement with all major endpoints.
The fastest way to develop locally. Starts the emulator and your app together, auto-detecting your framework and injecting the right environment variables.
# Auto-detects framework (Next.js, Vite, Remix, SvelteKit, etc.) and dev command
workos dev
# Override the dev command
workos dev -- npx vite --port 5173
# Custom emulator port and seed data
workos dev --port 8080 --seed workos-emulate.config.yamlYour app receives these environment variables automatically:
WORKOS_API_BASE_URL— points to the local emulator (e.g.http://localhost:4100)WORKOS_API_KEY—sk_test_defaultWORKOS_CLIENT_ID—client_emulate
Run the emulator on its own for CI, test suites, or when you want manual control.
# Start with defaults (port 4100)
workos emulate
# CI-friendly: JSON output, custom port
workos emulate --port 9100 --json
# → {"url":"http://localhost:9100","port":9100,"apiKey":"sk_test_default","health":"http://localhost:9100/health"}
# Pre-load seed data
workos emulate --seed workos-emulate.config.yamlThe emulator supports GET /health for readiness polling and shuts down cleanly on Ctrl+C.
Create a workos-emulate.config.yaml (auto-detected) or pass --seed <path>:
users:
- email: alice@acme.com
first_name: Alice
password: test123
email_verified: true
organizations:
- name: Acme Corp
domains:
- domain: acme.com
state: verified
memberships:
- user_id: <user_id>
role: admin
connections:
- name: Acme SSO
organization: Acme Corp
connection_type: GenericSAML
domains: [acme.com]
roles:
- slug: admin
name: Admin
permissions: [posts:read, posts:write]
permissions:
- slug: posts:read
name: Read Posts
- slug: posts:write
name: Write Posts
webhookEndpoints:
- url: http://localhost:3000/webhooks
events: [user.created, organization.updated]Use the emulator directly in test suites without the CLI:
import { createEmulator } from 'workos/emulate';
const emulator = await createEmulator({
port: 0, // random available port
seed: {
users: [{ email: 'test@example.com', password: 'secret' }],
},
});
// Use emulator.url as your WORKOS_API_BASE_URL
const res = await fetch(`${emulator.url}/user_management/users`, {
headers: { Authorization: 'Bearer sk_test_default' },
});
// Reset between tests (clears data, re-applies seed)
emulator.reset();
// Clean up
await emulator.close();The emulator covers the full WorkOS API surface (~84% of OpenAPI spec endpoints). Run pnpm check:coverage <openapi-spec> to see exact coverage.
| Endpoint Group | Routes |
|---|---|
| Organizations | CRUD, external_id lookup, domain management |
| Users | CRUD, email uniqueness, password management |
| Organization memberships | CRUD, role assignment, deactivate/reactivate |
| Organization domains | CRUD, verification |
| SSO connections | CRUD, domain-based lookup |
| SSO flow | Authorize, token exchange, profile, JWKS, SSO logout |
| AuthKit | OAuth authorize (login_hint, multi-user), authenticate (7 grant types incl. refresh_token, MFA TOTP, org selection, device code), PKCE, sealed sessions, impersonation |
| Sessions | List, revoke, logout redirect, JWKS per client |
| Email verification | Send code, confirm |
| Password reset | Create token, confirm |
| Magic auth | Create code |
| Auth factors | TOTP enrollment, delete |
| MFA challenges | Create challenge, verify code |
| Invitations | CRUD, accept, revoke, resend, get by token |
| Config | Redirect URIs, CORS origins, JWT template |
| User features | Authorized apps, connected accounts, data providers |
| Widgets | Token generation |
| Authorization (RBAC) | Environment roles, org roles (priority ordering), permissions, role-permission management |
| Authorization (FGA) | Resources CRUD, permission checks, role assignments |
| Directory Sync | List/get/delete directories, users, groups |
| Audit Logs | Actions, schemas, events, exports, org config/retention |
| Feature Flags | List/get, enable/disable, targets, org/user evaluations |
| Connect | Applications CRUD, client secrets |
| Data Integrations | OAuth authorize + token exchange |
| Radar | Attempts list/get, allow/deny lists |
| API Keys | Validate, delete, list by org |
| Portal | Generate admin portal links |
| Legacy MFA | Enroll/get/delete factors, challenge/verify |
| Webhook Endpoints | CRUD with auto-generated secrets, secret masking |
| Events | Paginated event stream with type filtering |
| Event Bus | Auto-emits events on entity CRUD via collection hooks, fire-and-forget webhook delivery with HMAC signatures |
| Pipes | Connection CRUD, mock getAccessToken() |
JWT tokens include role and permissions claims for org-scoped sessions. All list endpoints support cursor pagination (before, after, limit, order). Error responses match the WorkOS format ({ message, code, errors }).
workos env add [name] [apiKey] # Add environment (interactive if no args)
workos env remove <name> # Remove an environment
workos env switch [name] # Switch active environment
workos env list # List environments with active indicatorAPI keys are stored in the system keychain via @napi-rs/keyring, with a JSON file fallback at ~/.workos/config.json.
All resource commands follow the same pattern: workos <resource> <action> [args] [--options]. API keys resolve via: WORKOS_API_KEY env var → --api-key flag → active environment's stored key.
workos organization create <name> [domain:state ...]
workos organization update <orgId> <name> [domain] [state]
workos organization get <orgId>
workos organization list [--domain] [--limit] [--before] [--after] [--order]
workos organization delete <orgId>workos user get <userId>
workos user list [--email] [--organization] [--limit]
workos user update <userId> [--first-name] [--last-name] [--email-verified] [--password] [--external-id]
workos user delete <userId>workos role list [--org <orgId>]
workos role get <slug> [--org <orgId>]
workos role create --slug <slug> --name <name> [--org <orgId>]
workos role update <slug> [--name] [--description] [--org <orgId>]
workos role delete <slug> --org <orgId>
workos role set-permissions <slug> --permissions <slugs> [--org <orgId>]
workos role add-permission <slug> <permissionSlug> [--org <orgId>]
workos role remove-permission <slug> <permissionSlug> --org <orgId>workos permission list [--limit]
workos permission get <slug>
workos permission create --slug <slug> --name <name> [--description]
workos permission update <slug> [--name] [--description]
workos permission delete <slug>workos membership list [--org] [--user] [--limit]
workos membership get <id>
workos membership create --org <orgId> --user <userId> [--role]
workos membership update <id> [--role]
workos membership delete <id>
workos membership deactivate <id>
workos membership reactivate <id>workos invitation list [--org] [--email] [--limit]
workos invitation get <id>
workos invitation send --email <email> [--org] [--role] [--expires-in-days]
workos invitation revoke <id>
workos invitation resend <id>workos session list <userId> [--limit]
workos session revoke <sessionId>workos connection list [--org] [--type] [--limit]
workos connection get <id>
workos connection delete <id> [--force]workos directory list [--org] [--limit]
workos directory get <id>
workos directory delete <id> [--force]
workos directory list-users [--directory] [--group] [--limit]
workos directory list-groups --directory <id> [--limit]workos event list --events <types> [--org] [--range-start] [--range-end] [--limit]workos audit-log create-event <orgId> --action <action> --actor-type <type> --actor-id <id> [--file <json>]
workos audit-log export --org <orgId> --range-start <date> --range-end <date> [--actions] [--actor-names]
workos audit-log list-actions
workos audit-log get-schema <action>
workos audit-log create-schema <action> --file <schema.json>
workos audit-log get-retention <orgId>workos feature-flag list [--limit]
workos feature-flag get <slug>
workos feature-flag enable <slug>
workos feature-flag disable <slug>
workos feature-flag add-target <slug> <targetId>
workos feature-flag remove-target <slug> <targetId>workos webhook list
workos webhook create --url <endpoint> --events <types>
workos webhook delete <id>workos config redirect add <uri>
workos config cors add <origin>
workos config homepage-url set <url>workos portal generate-link --intent <intent> --org <orgId> [--return-url] [--success-url]workos vault list [--limit]
workos vault get <id>
workos vault get-by-name <name>
workos vault create --name <name> --value <secret> [--org <orgId>]
workos vault update <id> --value <secret> [--version-check]
workos vault delete <id>
workos vault describe <id>
workos vault list-versions <id>workos api-key list --org <orgId> [--limit]
workos api-key create --org <orgId> --name <name> [--permissions]
workos api-key validate <value>
workos api-key delete <id>workos org-domain get <id>
workos org-domain create <domain> --org <orgId>
workos org-domain verify <id>
workos org-domain delete <id>workos install [options]
--direct, -D Use your own Anthropic API key (bypass llm-gateway)
--integration <name> Framework: nextjs, react, react-router, tanstack-start, vanilla-js, sveltekit, node, python, ruby, go, dotnet, kotlin, elixir, php-laravel, php
--api-key <key> WorkOS API key (required in non-interactive mode)
--client-id <id> WorkOS client ID (required in non-interactive mode)
--redirect-uri <uri> Custom redirect URI
--homepage-url <url> Custom homepage URL
--install-dir <path> Installation directory
--no-validate Skip post-installation validation
--no-branch Skip branch creation (use current branch)
--no-commit Skip auto-commit after installation
--create-pr Auto-create pull request after installation
--no-git-check Skip git dirty working tree check
--force-install Force install packages even if peer dependency checks fail
--debug Enable verbose logging# Interactive (recommended)
npx workos
# Specify framework
npx workos install --integration react-router
# With visual dashboard (experimental)
npx workos dashboard
# JSON output (explicit)
workos org list --json --api-key sk_test_xxx
# Pipe-friendly (auto-detects non-TTY)
workos org list --api-key sk_test_xxx | jq '.data[].name'
# Machine-readable command discovery
workos --help --json | jq '.commands[].name'The CLI auto-detects non-TTY environments (piped output, CI, coding agents) and switches to machine-friendly behavior. No flags required — just pipe it.
All commands produce structured JSON when piped or with --json:
workos org list --api-key sk_test_xxx | jq .
# → { "data": [...], "list_metadata": { "before": null, "after": "..." } }
workos env list --json
# → { "data": [{ "name": "prod", "type": "production", "active": true, ... }] }Errors go to stderr as structured JSON:
workos org list 2>&1
# → { "error": { "code": "no_api_key", "message": "No API key configured..." } }In non-TTY, the installer streams progress as NDJSON (one JSON object per line):
workos install --api-key sk_test_xxx --client-id client_xxx --no-commit 2>/dev/null
# → {"type":"detection:complete","integration":"nextjs","timestamp":"..."}
# → {"type":"agent:start","timestamp":"..."}
# → {"type":"agent:progress","message":"...","timestamp":"..."}
# → {"type":"complete","success":true,"timestamp":"..."}| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | General error |
| 2 | Cancelled |
| 4 | Authentication required |
| Variable | Effect |
|---|---|
WORKOS_API_KEY |
API key for management commands (bypasses stored config) |
WORKOS_API_BASE_URL |
Override API base URL (set automatically by workos dev) |
WORKOS_NO_PROMPT=1 |
Force non-interactive mode + JSON output |
WORKOS_FORCE_TTY=1 |
Force interactive mode even when piped |
WORKOS_TELEMETRY=false |
Disable telemetry |
Agents can introspect available commands:
workos --help --json # Full command tree
workos env --help --json # Subcommand tree
workos organization --help --json # With positionals and option typesThe CLI uses WorkOS Connect OAuth device flow for authentication:
# Login (opens browser for authentication)
workos auth login
# Check current auth status
workos auth status
# Logout (clears stored credentials)
workos auth logoutOAuth credentials are stored in the system keychain (with ~/.workos/credentials.json fallback). Access tokens are not persisted long-term for security - users re-authenticate when tokens expire.
- Detects your framework and project structure
- Resolves credentials — uses existing config, or auto-provisions an unclaimed environment if none found
- Auto-configures WorkOS dashboard (redirect URI, CORS, homepage URL)
- Fetches latest SDK documentation from workos.com
- Uses AI (Claude) to generate integration code
- Installs SDK with detected package manager
- Creates auth routes, middleware, and UI
- Configures environment variables securely
The installer collects anonymous usage telemetry to help improve the product:
- Session outcome (success/error/cancelled)
- Framework detected
- Duration and step timing
- Token usage (for capacity planning)
No code, credentials, or personal data is collected. Disable with:
WORKOS_TELEMETRY=false npx workosDetailed logs (with redacted credentials) are saved to:
~/.workos/logs/workos-{timestamp}.log
Up to 10 session log files are retained. Use --debug flag for verbose terminal output.
See DEVELOPMENT.md for development setup.
Build:
pnpm buildRun locally:
pnpm dev # Watch mode
./dist/bin.js --helpMIT © WorkOS