How OmniRoute Remote Mode Works: Controlling Remote Instances with Scoped Access Tokens

OmniRoute remote mode enables you to run the CLI on your local machine while authenticating to a remote server via HTTP-based management APIs using hierarchical scoped access tokens.

OmniRoute's remote mode separates the CLI client from the server architecture, allowing you to execute commands from your laptop against an OmniRoute instance running on a VPS, home server, or Tailscale-connected device. According to the diegosouzapw/OmniRoute source code, this system authenticates each request using scoped access tokens (prefixed with oma_…) that carry one of three privilege levels: read, write, or admin. The design isolates administrative actions from read-only operations, significantly reducing the attack surface if a token is compromised.

How Remote Mode Authentication Works

The Bootstrap Process

Remote mode initialization begins with the omniroute connect command. In src/app/api/cli/connect/route.ts, the server receives a POST request containing the management password at /api/cli/connect. The server verifies this password against stored credentials while applying brute-force protection from src/server/auth/loginGuard.ts, which tracks per-IP failure counters and returns 429 Too Many Requests on repeated attempts.

Upon successful verification, the server mints a new scoped token with the admin scope, stores only its SHA-256 hash in the SQLite access_tokens table, and returns the plaintext token exactly once. The CLI then stores this token alongside the server's base URL in ~/.omniroute/config.json with chmod 600 permissions.

Token Storage and Context Management

The local context file managed by helpers in src/lib/context/... records the active server URL, token hash prefix, and scope. All subsequent CLI commands automatically inject the Authorization: Bearer oma_… header and route requests to the configured remote endpoint. This context persists until you switch using omniroute contexts use <name>.

Scoped Access Tokens and Permissions

The Three Hierarchical Scopes

OmniRoute implements hierarchical scope levels that determine API access rights:

  • read – Permits inspection commands: listing models, viewing logs, checking usage statistics (omniroute models list, omniroute logs)
  • write – Inherits read permissions and allows configuration changes: creating combos, setting configuration values (omniroute setup-codex, omniroute config set)
  • admin – Full access including write permissions plus token lifecycle management, provider configuration, and OAuth connections

Scope Enforcement in the API

The enforcement logic resides in src/app/api/v1/_helpers/apiKeyScope.ts. The server determines required scopes by examining the HTTP method and an admin allow-list. GET requests typically require read, while POST/PUT/DELETE require write. Sensitive endpoints such as /api/cli/tokens, /api/providers/* mutations, and /api/oauth require admin scope regardless of method.

Loopback-only routes (services spawning subprocesses) force admin scope plus loopback network verification, ensuring remote tokens cannot access them even with valid credentials.

CLI Workflow for Remote Management

Connecting to a Remote Server

Initialize remote mode by connecting to your server with the management password:


# Bootstrap connection - creates admin token automatically

omniroute connect 192.168.0.15

# Verify active context

omniroute contexts current

This creates a new context in ~/.omniroute/config.json containing the server URL and access token.

Creating Scoped Tokens for CI/CD

For automated workflows, create limited-scope tokens rather than using admin credentials:


# Create read-only token for CI runners

omniroute tokens create --name ci-runner --scope read

# List all tokens (requires admin scope)

omniroute tokens list

Managing Multiple Contexts

Switch between local and remote instances using the context system:


# Add manual context for staging environment

omniroute contexts add staging --url https://staging.example.com:20128 \
  --access-token oma_live_abcdef --scope write \
  --description "Staging box"

# List saved contexts

omniroute contexts list

# Switch to local server

omniroute contexts use default
omniroute models list  # Now hits local instance

# Remove local credential (does not revoke server-side)

omniroute contexts remove staging --yes

Security Architecture

Brute-Force Protection

The token bootstrap process shares protection mechanisms with the dashboard login flow. The loginGuard.ts module implements per-IP rate limiting that triggers after repeated authentication failures, preventing credential stuffing attacks against the /api/cli/connect endpoint.

Token Hashing and One-Time Secrets

Security-critical implementation details in src/lib/db/accessTokens.ts ensure that:

  1. One-time display – Plaintext tokens transmit only during creation; the server immediately discards the original, retaining only SHA-256 hashes
  2. Scope isolation – Compromised read tokens cannot mutate configuration or create new tokens
  3. Network segmentation – Inference routes (/v1/chat/completions) use separate model-specific API keys (sk-…), keeping management tokens distinct from inference authentication

Summary

  • Bootstrap flow: omniroute connect exchanges the management password for a scoped token via POST /api/cli/connect, storing credentials in ~/.omniroute/config.json
  • Authentication: All management API requests carry Authorization: Bearer oma_… headers verified against SHA-256 hashes in the SQLite access_tokens table
  • Three scopes: read (inspection), write (configuration), and admin (token lifecycle), enforced by src/app/api/v1/_helpers/apiKeyScope.ts
  • Security: Brute-force protection from src/server/auth/loginGuard.ts, one-time token display, and separate authentication for inference endpoints
  • Multi-context: Support for switching between local and remote instances without re-authentication

Frequently Asked Questions

How do I connect the OmniRoute CLI to a remote server?

Run omniroute connect <host> with the management password. The CLI sends a POST request to /api/cli/connect, receives a scoped access token, and stores it in ~/.omniroute/config.json. All subsequent commands automatically target the remote server until you switch contexts.

What is the difference between read, write, and admin scopes?

read permits listing and inspection commands like omniroute models list. write adds configuration capabilities such as creating combos or setting variables. admin grants full token lifecycle management, provider configuration, and access to sensitive endpoints like /api/cli/tokens.

How are OmniRoute access tokens secured?

Tokens follow a one-time secret model: the server stores only SHA-256 hashes in the SQLite access_tokens table while displaying the plaintext once during creation. The system enforces scope-based authorization via src/app/api/v1/_helpers/apiKeyScope.ts and protects the bootstrap endpoint with brute-force detection from src/server/auth/loginGuard.ts.

Can I use remote mode tokens for inference endpoints?

No. Management tokens (oma_…) authenticate only administrative CLI commands against /api/cli/* endpoints. Inference routes such as /v1/chat/completions require separate model-specific API keys (sk-…) and are not accessible using scoped access tokens.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →