How to Configure Remote Mode with Scoped Access Tokens in OmniRoute

To configure remote mode with scoped access tokens in OmniRoute, generate a token with the CLI using omniroute token create --scope <read|write|admin>, set it as the OMNIRoute_TOKEN environment variable, and point the CLI to your remote server with --server https://your-server.com.

OmniRoute supports a remote mode that shifts management operations from your local machine to a dedicated server instance. When you configure remote mode with scoped access tokens in OmniRoute, you authenticate using bearer tokens that carry specific permissions rather than inference API keys. This guide walks through the complete setup using the actual implementation from the diegosouzapw/OmniRoute repository.

Understanding the Token Scope Model

OmniRoute implements a three-tier scope hierarchy that determines which management actions a token can perform. The system is defined in src/lib/accessTokens/scopes.ts and uses a simple ranking system where higher scopes inherit lower permissions.

The Three-Level Hierarchy

The ACCESS_SCOPES constant defines the available levels:

// src/lib/accessTokens/scopes.ts
export const ACCESS_SCOPES = ["read", "write", "admin"] as const;
export type AccessScope = (typeof ACCESS_SCOPES)[number];
  • read – Allows listing and inspecting resources (e.g., viewing providers or combos)
  • write – Includes read permissions plus the ability to create or modify configuration
  • admin – Includes write permissions plus sensitive actions like creating or revoking tokens, adding providers, or installing services

The hierarchy follows admin ⊃ write ⊃ read, meaning an admin token can perform any action a write or read token can.

How Scope Validation Works

The server uses the scopeSatisfies(have, need) helper function to check if a token's scope meets the endpoint's requirements. This function verifies that the token's rank is greater than or equal to the required rank. Remote mode tokens must always be sent in the Authorization header; tokens passed via URL are explicitly ignored in src/lib/api/requireManagementAuth.ts.

Creating Scoped Access Tokens

Use the CLI to generate tokens with specific permission levels. These tokens always start with the prefix oma_ and are managed through the access_tokens database table.

CLI Token Creation Commands

Generate tokens for different operational needs:


# Read-only token for dashboard inspection

omniroute token create --scope read --name "readonly-dashboard"

# Write token for configuration management

omniroute token create --scope write --name "config-writer"

# Admin token for full management access

omniroute token create --scope admin --name "admin-access"

Each command performs three operations internally:

  1. Generates a random UUID and prefixes it with oma_
  2. Stores the token in the access_tokens table (defined in db/migrations/…_access_tokens.sql) with the specified scope and metadata
  3. Displays the full token value exactly once

Important: The secret is shown only during creation. Store it immediately in a secret manager or environment variable—never commit tokens to source control.

Enabling Remote Mode in the CLI

Remote mode activates automatically when the CLI targets a non-local server URL. You only need to provide the scoped token and server address.

Environment Variable Configuration

Set the OMNIRoute_TOKEN variable to inject the authentication header automatically:

OMNIRoute_TOKEN=oma_3f4a7c8d9e10ab11cd22ef33ab44cd55 \
  omniroute --server https://omniroute.example.com combo list

The CLI reads this variable and adds Authorization: Bearer <token> to every HTTP request.

Explicit Flag Method

Alternatively, pass the token directly via command line:

omniroute --server https://omniroute.example.com \
          --token oma_3f4a7c8d9e10ab11cd22ef33ab44cd55 \
          combo edit myCombo --add-model gpt-4o

Both methods require the token to have sufficient scope for the requested operation.

Server-Side Token Validation

When a request hits a management route (e.g., /api/cli/*, /api/providers/*, /api/combo/*), the server executes a strict validation pipeline defined across several authorization modules.

The Validation Flow

The sequence in src/server/authz/accessTokenAuth.ts and src/server/authz/policies/management.ts follows these steps:

  1. evaluateAccessTokenAuth(request) extracts the bearer token and verifies the oma_ prefix
  2. verifyAccessToken performs a database lookup in the access_tokens table
  3. inferRequiredScope determines the necessary permission level based on the HTTP method and pathname
  4. scopeSatisfies(token.scope, requiredScope) validates that the token meets the requirement
  5. requireManagementAuth (in src/lib/api/requireManagementAuth.ts) returns a verdict of ok, invalid, insufficient, error, or absent, which translates to HTTP status codes 200, 401, 403, 503, or similar

If the token lacks sufficient scope, the server returns 403 Forbidden with a message indicating the required scope.

Practical Implementation Examples

Querying Resources with Read Scope

Use a read-only token to inspect configuration without modification rights:

OMNIRoute_TOKEN=oma_5a6b7c8d9e0f1a2b3c4d5e6f7g8h9i0j \
omniroute --server https://omniroute.example.com provider list

Or using raw HTTP:

const token = process.env.OMNIRoute_TOKEN;
const resp = await fetch('https://omniroute.example.com/api/combo/list', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
});

const data = await resp.json();
console.log('Available combos:', data);

Modifying Configuration with Write Scope

Update combos or providers using a write-scoped token:

omniroute --server https://omniroute.example.com \
          --token oma_9f8e7d6c5b4a3a2b1c0d9e8f7g6h5i4j \
          combo edit myCombo --add-model gpt-4o

A read-only token would receive 403 Forbidden with the message: Access token scope 'read' is insufficient; 'write' required.

Administrative Operations

Creating new tokens requires admin scope:

omniroute --server https://omniroute.example.com \
          --token oma_admin_token \
          token create --scope write --name "ci-writer"

This operation manipulates credential material in the access_tokens table, which is protected to admin-only access as enforced by the policy in src/server/authz/policies/management.ts.

Summary

  • Scoped tokens use the prefix oma_ and come in three levels: read, write, and admin, defined in src/lib/accessTokens/scopes.ts
  • Token creation happens via omniroute token create --scope <level>, storing secrets in the database via migrations in db/migrations/…_access_tokens.sql
  • Remote mode requires setting OMNIRoute_TOKEN or using --token, targeting a remote server with --server, and relies on header-based authentication handled by src/lib/api/requireManagementAuth.ts
  • Validation occurs in src/server/authz/accessTokenAuth.ts and src/server/authz/policies/management.ts, using scopeSatisfies to enforce the hierarchy
  • Security mandates storing tokens in environment variables or secret managers, never in source control, and using the minimum necessary scope for each operation

Frequently Asked Questions

What is the difference between an OmniRoute scoped token and an inference API key?

Scoped access tokens (prefixed with oma_) are management credentials for remote CLI operations like configuring providers and editing combos, while inference API keys are used for actual model inference requests. The scoped tokens operate against management routes (/api/cli/*, /api/combo/*) and carry permissions (read, write, admin), whereas inference keys authenticate prediction requests and do not have the hierarchical scope system defined in src/lib/accessTokens/scopes.ts.

How do I rotate or revoke a compromised scoped token?

You must use an admin-scoped token to create or revoke credentials. Run omniroute token revoke <token-id> or delete the entry directly from the access_tokens table in the database. Since tokens are evaluated against the database on every request in src/server/authz/accessTokenAuth.ts, removal takes effect immediately without requiring server restarts.

Why does my request return 403 when I have a valid token?

A 403 error indicates your token exists but lacks sufficient scope for the operation. The server evaluates requirements using scopeSatisfies in src/lib/accessTokens/scopes.ts, where read cannot perform write operations. Check the error message—it explicitly states the required scope (e.g., 'write' required) and verify you are using the correct token level for the endpoint's method (POST/PUT typically require write or admin).

Can I use scoped tokens in the URL query parameters instead of headers?

No. The evaluateAccessTokenAuth function in src/server/authz/accessTokenAuth.ts only checks the Authorization: Bearer header. The requireManagementAuth.ts file explicitly ignores tokens passed in URLs for security reasons. Always set the token via the OMNIRoute_TOKEN environment variable or the --token CLI flag, which properly injects it into the request header.

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 →