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

> Learn how OmniRoute remote mode lets you control remote instances using scoped access tokens for secure, hierarchical authentication via HTTP management APIs from your local machine.

- Repository: [Diego Rodrigues de Sa e Souza/OmniRoute](https://github.com/diegosouzapw/OmniRoute)
- Tags: how-to-guide
- Published: 2026-07-08

---

**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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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:

```bash

# 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:

```bash

# 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:

```bash

# 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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/v1/_helpers/apiKeyScope.ts)
- **Security**: Brute-force protection from [`src/server/auth/loginGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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`](https://github.com/diegosouzapw/OmniRoute/blob/main/src/app/api/v1/_helpers/apiKeyScope.ts) and protects the bootstrap endpoint with brute-force detection from [`src/server/auth/loginGuard.ts`](https://github.com/diegosouzapw/OmniRoute/blob/main/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.