Skip to content

Web Console Operation Guide

Doc Version: 1.0.0 Last Updated: 2026-09-15 Applicable Version: v3.1.1 Author: Lincoln

This guide is for first-time users of the JAiRouter Web Console, covering everything from login to connecting your first model service, quota management, observability, and access control.

1. Login and First Launch

1.1 Access URL

DeploymentURLNotes
Local dev (Vite)http://localhost:3000/adminVite dev server, hot reload
Production / standalonehttp://<host>:8080/adminBackend-served SPA

Both entry points serve the same frontend code with identical functionality.

1.2 Default Accounts

UsernameDefault PasswordRoleDescription
adminChangeMeOnFirstStartup123456ADMIN, USERSuper admin with all 63 permission codes
useruser123456USERRegular user, primarily read-only

⚠️ Change the admin password before first production use. The password is set via the INITIAL_ADMIN_PASSWORD environment variable (see src/main/resources/config/auth/jwt.yml). Restart the service after changing it.

# Example: set the environment variable before startup
export INITIAL_ADMIN_PASSWORD="YourStr0ngPassword#2026"

1.3 Token Storage

After a successful login, the JWT is stored in the browser localStorage under the key admin_token.

⚠️ Do not inject tokens manually. The frontend route guard (router.beforeEach) performs the following checks on every navigation:

  1. Checks whether admin_token exists in localStorage;
  2. Decodes the JWT to verify expiration (marked expired 60 seconds early);
  3. Validates that the route's meta.roles / meta.permissions requirements are met.

Only when all conditions pass is navigation allowed; otherwise the user is redirected to /login. A manually written token that is expired or missing the permissions claim will prevent the console from functioning properly.

1.4 Login Flow

  1. Open the console URL in a browser;
  2. The page title displays JAiRouter Admin (zh: JAiRouter 管理后台);
  3. Enter your username and password, then click the Login button;
  4. On success, you are automatically redirected to the Dashboard page.

Login page


2. Interface Layout

2.1 Left Navigation

The console has a collapsible sidebar containing 7 menu groups with 28 menu items. Pages that belong together are folded into tabs (for example, "Call History" holds "Call Records / Call History Dashboard"); tabs are ordered and switch in place.

Menu visibility is controlled by permission codes: groups/menu items for which the user lacks the required code are hidden, and each tab is gated separately — if the user can only see some tabs, the item still shows and the landing tab is the first one the user is allowed to open.

Dashboard interface

#Group (en)Group (zh)Menu items (tabs in parentheses, | separated)
1Overview概览Dashboard
2Observability运行观测Call History (Call Records | Call History Dashboard), Distributed Tracing (Trace Search | Tracing Dashboard), Exceptions (Exception List | Statistics), Slow Requests (Slow Calls | Slow SQL), Usage (Token Usage | Quota Usage)
3Traffic Governance流量治理Routing Rules, Load Balancing (Real-time Monitoring | Strategy Config), Rate Limiting (Rate Limit Monitoring), Circuit Breakers (Circuit Monitoring | Circuit History | Global Config), Response Cache Management, Quota Runtime Config, Resource Pools
4Model & Instances模型与实例Service Management, Instance Management, Version Management, Adapters
5Security安全API Key Management, PII Sanitization, JWT Token Management, Blacklist Management, Audit Logs, Record Governance
6System系统Account Management, Permission Management, Tracing Config, State Persistence
7Developer Tools开发工具AI Playground (Chat Playground | Embedding | Rerank | Audio Service | Image Service), Client Access Guide

This information architecture (IA) change folds 9 groups / 40 entries into 7 groups / 28 items (29 since v3.5.1 added Record Governance): 12 entries became tabs of a sibling item, and every URL stays the same. Deep links, bookmarks, and the paths in the appendix keep working; they simply no longer occupy a sidebar row of their own.

2.2 Top Bar

AreaElementDescription
LeftBreadcrumbFormat: Group / Menu item / Current tab (duplicates collapsed)
RightLanguage SwitcherCapsule button with dropdown to select 中文 or English; change takes effect immediately
RightTheme ToggleRound button with ☀️/🌙 icon to switch between light and dark themes
RightUser MenuAvatar + username (e.g. admin); dropdown contains Profile and Log Out

2.3 Breadcrumb

The top of the page displays the current navigation path, e.g. Overview / Dashboard or Observability / Call History / Call Records. The last segment is the current page and is not clickable; the preceding segments are. Detail pages (e.g. /exceptions/detail/:id) append #<id> to the last segment. The breadcrumb updates automatically when navigating between pages.


3. Minimum Path to Connect Your First Model Service

The following steps are ordered by dependency, using an Ollama model service as an example.

Service Management page

Step 1: Configure a Service

Menu path: Model & Instances → Service Management

  1. Go to the Service Management page;
  2. Click the Add Service button;
  3. Fill in the form:
FieldDescriptionRequired
Service TypeDropdown selection, e.g. chat, embedding, completion✅
AdapterDropdown to select the adapter type✅
Load Balance StrategyRandom / Round Robin / Least Connections / IP Hash✅
DescriptionOptional note❌
  1. Click Save;
  2. After saving, the service type appears in the list with status Enabled.

Step 2: Configure an Instance

Menu path: Model & Instances → Instance Management

Instance Management page

  1. Go to the Instance Management page;
  2. Select the corresponding service type from the left dropdown;
  3. Click the Add Instance button;
  4. Fill in the form:
FieldDescriptionRequiredExample
Service TypeThe associated service type✅chat
Instance NameInstance identifier✅ollama-local
Base URLDownstream service address✅http://localhost:11434
PathRequest path (optional)❌/v1/chat/completions
WeightLoad balancing weight✅1
AdapterLeave empty to use global config❌—
  1. Expand the Request Header Config section and add headers required by the downstream service:
Header NameHeader ValueDescription
AuthorizationBearer <your-api-key>Authentication credential transparently forwarded to the downstream model service

💡 The Authorization header is forwarded transparently to the downstream service — it is not the gateway's own credential. The gateway credential is X-Jairouter-Token (JWT).

  1. Optional: expand the Tag Config section and add tags for routing rule matching;
  2. Click Save;
  3. After saving, the instance appears in the list. The status column shows the health status (healthy/unhealthy).

Step 3: Version and Adapter (If Needed)

  • Version Management (Model & Instances → Version Management): Configure version information if needed. This is not a required step.
  • Adapters (Model & Instances → Adapters): View and manage registered adapters. Skip this step if the adapter was correctly selected in Step 1.

Step 4: Verify Connectivity

After configuration, verify using these methods:

  1. Dashboard (Overview → Dashboard): Check the "Service Configuration Overview" area to confirm service instance count and healthy instance count;
  2. Instance Management page: The instance status column should show a green Healthy label (not Unhealthy);
  3. Load Balancer Monitoring (Traffic Governance → Load Balancer Monitoring): View real-time load balancing status.

Step 5: Test in Playground

Menu path: Developer Tools → AI Playground → Chat Playground

  1. Go to the Chat Playground page;
  2. Select the model matching the service type configured in Step 1;
  3. Enter a message and send it;
  4. If you receive a response, the entire pipeline (Console → Gateway → Model Service) is working.

💡 Playground requires the ai:playground:use permission code. Both ADMIN and USER roles have this permission by default.


4. How Quotas Work

4.1 Quota Runtime Configuration

Menu path: Traffic Governance → Quota Runtime Config

The quota feature is disabled by default. To enable it:

Quota Runtime Configuration page

  1. Go to the Quota Runtime Configuration page;
  2. Find the Hot-Editable Configuration section;
  3. Turn on the Enable Quota switch;
  4. Optional settings:
  5. Fail Open: whether to allow requests when the quota system is unavailable;
  6. Stat Windows: select the statistical window dimensions;
  7. Click Save Configuration.

Hot-editable fields (take effect immediately, no restart):

FieldDescription
enabledEnable/disable quotas
failOpenFail-open switch
windowsStatistical window selection

Restart-required fields (marked with a Restart badge, read-only):

FieldDescription
backendNameStorage backend name
distributedEnabledDistributed enabled
distributedKeyPrefixDistributed key prefix
distributedTimeoutDistributed timeout
flushIntervalSecondsFlush interval

4.2 Quota Usage Monitoring

Menu path: Observability → Usage → Quota Usage

On the Quota Usage Monitoring page you can:

  • View quota runtime status: storage backend type, degradation status;
  • Filter usage data by Tenant ID / API Key ID / User ID / Service Type / Model / Window;
  • View usage details: request count, token count.

💡 If the page displays "Quota ledger not enabled, usage data unavailable", the quota feature is not enabled. Go to the Quota Runtime Config page first to enable it.


5. Observability and Troubleshooting

5.1 Call History and Exceptions (Observability)

PagePathWhat It Answers
Call History Dashboard/call-history/dashboardOverall call volume trend, success/failure rate overview
Call List/call-history/listDetailed record of every request (time, service, status code, latency)
Token Usage/call-history/token-usageToken consumption per model/service
Slow Calls/call-history/slow-callsWhich requests took too long
Slow SQL/monitoring/slow-queriesDeep analysis of slow requests (requires monitoring:slowquery:read)
Quota Usage Monitoring/monitoring/quotaQuota consumption details
Exception List/exceptions/listList of all exception events (requires monitoring:exceptions:read)
Statistics/exceptions/statisticsException distribution by type/time

5.2 Distributed Tracing (Observability)

PagePathWhat It Answers
Tracing Dashboard/tracing/dashboardTrace volume trends, latency distribution, error rate trends, throughput
Tracing Search/tracing/searchLocate specific request traces by Trace ID / service name / time range
Tracing Config/tracing/managementTracing toggle, sampling rate, exporter configuration (Logging / OTLP / Jaeger); moved to the System group

5.3 Dashboard Overview

Overview → Dashboard provides a single-pane view:

  • System Overview: service count, instance count, healthy instances, unhealthy instances;
  • System Metrics: JVM memory, thread count, HTTP requests, CPU usage, uptime;
  • Governance Chain: shortcuts to rule hits, rate limiting, circuit breaker, load balancing status;
  • Exception / Alert Summary: recent exception event list;
  • Service Configuration Overview: global config summary (adapter, rate limit, circuit breaker, etc.).

6. Permissions and Roles

6.1 Four Built-in Roles

RolePermission CountPermission ScopeDescription
ADMIN63All permission codesSuper admin; bypasses URL rules, full codes embedded in JWT
OPERATOR43All :read + :write codesDay-to-day ops; excludes system management (system:*), security management manage codes (API Key / JWT Token / Blacklist management)
USER28Dashboard + config read + full lb/cb/rl + monitoring read + tracing dashboard/search + AI PlaygroundRegular user; only write code is lb:config:write
VIEWER27All :read codesPure read-only role; no callhistory:view, ai:playground:use, or other non-:read codes

6.2 Why Some Menu Pages Are Missing

Frontend menu rendering is filtered by permission codes:

  1. Each menu group/item is associated with a permission code (e.g. config:services:read);
  2. After login, the JWT's permissions claim contains the current user's permission code list;
  3. The usePermission composable filters out menu items the user does not have;
  4. The route guard (meta.permissions) further blocks direct URL access without permissions.

Resolution:

  1. Go to System → Permission Management (requires system:permissions:manage, ADMIN only);
  2. Find the target role, check the missing permission codes, and save.

💡 /v1/** (OpenAI-compatible inference endpoints) is independent of the RBAC system and only requires authentication — it is not restricted by permission codes.


7. Multi-Protocol Access

7.1 Client Access Guide

Menu path: Developer Tools → Client Access Guide

This page provides complete access examples for the OpenAI-compatible API and the Anthropic-compatible API, including Base URL, authentication method, curl examples, and SDK examples.

7.2 Credential Header Specifications

Protocol SurfaceCredential HeaderDescription
OpenAI-compatibleX-API-Key: <Gateway API Key>Used for /v1/* endpoints
Anthropic-compatiblex-api-key: <Gateway API Key>Used for the Anthropic Messages API
ConsoleX-Jairouter-Token: <JWT>Management API credential after Web Console login
Authorization—Forwarded transparently to the downstream model service; not a gateway credential

⚠️ The Authorization header (e.g. Bearer <token>) is forwarded as-is to the downstream model service by the gateway — it is not used as the gateway's own authentication credential.


8. Common Issues

8.1 401 After Login

Symptom: API requests return 401 Unauthorized after logging in.

Possible causes:

  1. The JWT has expired (default validity is 60 minutes);
  2. The JWT_SECRET environment variable is inconsistent across restarts, causing token signature verification to fail.

Resolution:

  • Log in again to obtain a new token;
  • Verify that the JWT_SECRET environment variable has not changed after a restart.

8.2 403 After Login

Symptom: Some APIs return 403 Forbidden.

Possible cause: The current user's role lacks the required permission code.

Resolution:

  • Log in with the admin account, go to System → Permission Management, and add the missing permission code to the role;
  • See the RBAC Permission Management documentation for details on the permission code system.

8.3 Missing Menu Pages

Symptom: After logging in, some menu groups or pages are missing from the sidebar.

Possible cause: The current user's role does not include the permission code for the corresponding menu item.

Resolution:

8.4 OpenAI SDK Integration Error

Symptom: Using the OpenAI SDK returns 401.

Possible cause: The SDK defaults to using the Authorization: Bearer <key> header rather than X-API-Key. The gateway's OpenAI-compatible endpoint requires the X-API-Key header for API Key authentication.

Resolution:

  • Use the X-API-Key header instead of Authorization to pass the API Key;
  • See the SDK example on the Developer Tools → Client Access Guide page.

8.5 Redis Unavailable Degradation

Symptom: The dashboard or monitoring pages show connection errors.

Possible cause: When JAiRouter uses Redis for JWT persistence or distributed quota storage, Redis is not started or is unreachable. In local development, Redis is disabled by default (redis.enabled: false), and JWT uses H2 + memory fallback.

Resolution:

  • Local development: No Redis needed — JWT uses H2 storage with memory fallback, and functionality is unaffected;
  • Production: Ensure Redis is available, or configure jairouter.security.jwt.persistence.fallback-storage: memory.

8.6 Quotas Not Taking Effect

Symptom: After sending requests, the Quota Usage Monitoring page shows no data.

Possible cause: The quota feature is disabled by default.

Resolution:

  1. Go to Traffic Governance → Quota Runtime Config;
  2. Enable the quota switch and save;
  3. Verify the storage backend status is normal (not degraded).

Appendix: Page Path Quick Reference

GroupMenu ItemTabs and Route Paths (order = tab order)
OverviewDashboard/dashboard/main
ObservabilityCall HistoryCall Records /call-history/list | Call History Dashboard /call-history/dashboard
ObservabilityDistributed TracingTrace Search /tracing/search | Tracing Dashboard /tracing/dashboard
ObservabilityExceptionsException List /exceptions/list | Statistics /exceptions/statistics (detail /exceptions/detail/:id is a deep link, not a sidebar entry)
ObservabilitySlow RequestsSlow Calls /call-history/slow-calls | Slow SQL /monitoring/slow-queries
ObservabilityUsageToken Usage /call-history/token-usage | Quota Usage /monitoring/quota
Traffic GovernanceRouting Rules/config/rules
Traffic GovernanceLoad BalancingReal-time Monitoring /load-balancers/monitoring | Strategy Config /load-balancers/strategy-config
Traffic GovernanceRate LimitingRate Limit Monitoring /rate-limiters/monitoring
Traffic GovernanceCircuit BreakersCircuit Monitoring /circuit-breakers/monitoring | Circuit History /circuit-breakers/history | Global Config /circuit-breakers/global-config
Traffic GovernanceResponse Cache Management/config/cache
Traffic GovernanceQuota Runtime Config/config/quota
Traffic GovernanceResource Pools/config/pools
Model & InstancesService Management/config/services
Model & InstancesInstance Management/config/instances
Model & InstancesVersion Management/config/versions
Model & InstancesAdapters/config/adapters
SecurityAPI Key Management/security/api-keys
SecurityPII Sanitization/security/sanitization
SecurityJWT Token Management/security/jwt-tokens
SecurityBlacklist Management/security/blacklist
SecurityAudit Logs/security/audit-logs
SecurityRecord Governance/security/record-governance
SystemAccount Management/system/accounts
SystemPermission Management/system/permissions
SystemTracing Config/tracing/management
SystemState Persistence/config/state-persistence
Developer ToolsAI PlaygroundChat Playground /playground/chat | Embedding /playground/embedding | Rerank /playground/rerank | Audio Service /playground/audio | Image Service /playground/image
Developer ToolsClient Access Guide/tools/client-access

PII Sanitization (v3.2.0)

Path: Security → PII Sanitization /security/sanitization (permission security:sanitization:manage)

  1. Review the response-side sub-config (PII patterns, sensitive words, masking char, scope)
  2. Save to hot-rebuild the rule set (record-path SUMMARY applies immediately)
  3. Dry-run with a chat sample; expect **** in the result
  4. Gateway live responses are not masked by default; admin /api/** and AI paths are excluded

Record Governance (v3.5.1)

Path: Security → Record Governance /security/record-governance (permissions config:callhistory:read / config:callhistory:write)

  1. Pick one of three record levels: METADATA_ONLY / SUMMARY / FULL (full content, encrypted at rest); switching to FULL asks for confirmation
  2. The read-only "Encryption and storage" card shows both the configured key source and the effective key source, plus the key fingerprint, per-record content limit (64 KB by default), retention and max records
  3. If the configuration requests env but JAIR_CALL_HISTORY_KEY is unavailable, a fallback warning appears and "effective" reads auto — content is then encrypted with the key file at ~/.jairouter/call-history.key
  4. Save submits recordLevel only; every other field is driven by jairouter.call-history.* and is read-only here
  5. At the FULL level, viewing a record detail decrypts it on the server and writes a FULL_CONTENT_ACCESS audit event (queryable on the Audit Logs page)

API Key Quota Ops (v3.2.0)

Path: Security → API Key Management → row action Quota

  1. Open the quota drawer: today usage / remaining + presets
  2. Adjust limits → Save Quota (quota fields only)
  3. Reset Counters clears daily usage/rate
  4. Quota Monitoring cross-links back to API Keys for limit edits

Quota Usage Monitoring

Path: Observability → Usage → Quota Usage /monitoring/quota

  • Shows multi-dimensional usage plus daily request/token limits and progress
  • Set limits on API Keys navigates to /security/api-keys