Skip to main content
OpenViking Server supports multi-tenant API key authentication with role-based access control for secure production deployments.

Overview

OpenViking uses a two-layer API key system:
Key TypeCreated ByRolePurpose
Root KeyServer config (root_api_key)ROOTFull access + admin operations
User KeyAdmin APIADMIN or USERPer-account access
All API keys are plain random tokens with no embedded identity. The server resolves identity by first comparing against the root key, then looking up the user key index.

Server Setup

1

Configure Root Key

Add the root_api_key to ov.conf:
{
  "server": {
    "host": "0.0.0.0",
    "port": 1933,
    "root_api_key": "your-secret-root-key",
    "cors_origins": ["*"]
  }
}
Generate a secure key with: openssl rand -base64 32
2

Start Server

openviking-server
3

Verify

curl http://localhost:1933/health
# {"status": "ok"}

Managing Accounts and Users

Use the root key to create accounts (workspaces) and users via the Admin API.

Create Account

curl -X POST http://localhost:1933/api/v1/admin/accounts \
  -H "X-API-Key: your-secret-root-key" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "acme",
    "admin_user_id": "alice"
  }'
Response:
{
  "status": "ok",
  "result": {
    "account_id": "acme",
    "admin_user_id": "alice",
    "user_key": "uk_abc123..."
  }
}
The first user in an account is automatically assigned the ADMIN role.

Register Regular User

curl -X POST http://localhost:1933/api/v1/admin/accounts/acme/users \
  -H "X-API-Key: your-secret-root-key" \
  -H "Content-Type: application/json" \
  -d '{
    "user_id": "bob",
    "role": "user"
  }'
Response:
{
  "status": "ok",
  "result": {
    "account_id": "acme",
    "user_id": "bob",
    "role": "user",
    "user_key": "uk_xyz789..."
  }
}

Using API Keys

HTTP Headers

OpenViking accepts API keys via two headers:
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
  -H "X-API-Key: uk_abc123..."

Python SDK

import openviking as ov

client = ov.SyncHTTPClient(
    url="http://localhost:1933",
    api_key="uk_abc123...",
    agent_id="my-agent"
)

client.initialize()
results = client.find("search query")

CLI

Create ~/.openviking/ovcli.conf:
{
  "url": "http://localhost:1933",
  "api_key": "uk_abc123...",
  "agent_id": "my-agent"
}
Then use the CLI:
ov ls viking://resources/
ov find "what is openviking"

Roles and Permissions

RoleScopeCapabilities
ROOTGlobalAll operations + Admin API (create/delete accounts, manage users)
ADMINOwn accountRegular operations + manage users in own account
USEROwn accountRegular operations (ls, read, find, sessions, etc.)
Full system access:
  • Create and delete accounts
  • Manage users across all accounts
  • Change user roles
  • All regular operations
  • Access admin endpoints
Use case: System administrators
Account-level management:
  • Register users in own account
  • Remove users from own account
  • Regenerate user keys
  • All regular operations within account
Use case: Team leads, project managers
Standard operations:
  • Add and manage resources
  • Create and manage sessions
  • Search and retrieve context
  • File system operations (ls, read, tree, etc.)
Use case: Regular users, agents

Admin API Reference

Account Management

POST /api/v1/admin/accountsRole: ROOTRequest:
{
  "account_id": "acme",
  "admin_user_id": "alice"
}
Response:
{
  "status": "ok",
  "result": {
    "account_id": "acme",
    "admin_user_id": "alice",
    "user_key": "uk_..."
  }
}
GET /api/v1/admin/accountsRole: ROOTResponse:
{
  "status": "ok",
  "result": [
    {"account_id": "acme", "created_at": "2026-01-15T10:00:00Z"},
    {"account_id": "widget-co", "created_at": "2026-01-16T14:30:00Z"}
  ]
}
DELETE /api/v1/admin/accounts/{account_id}Role: ROOTExample:
curl -X DELETE http://localhost:1933/api/v1/admin/accounts/acme \
  -H "X-API-Key: root-key"

User Management

POST /api/v1/admin/accounts/{account_id}/usersRole: ROOT, ADMINRequest:
{
  "user_id": "bob",
  "role": "user"
}
Response:
{
  "status": "ok",
  "result": {
    "account_id": "acme",
    "user_id": "bob",
    "role": "user",
    "user_key": "uk_..."
  }
}
GET /api/v1/admin/accounts/{account_id}/usersRole: ROOT, ADMINResponse:
{
  "status": "ok",
  "result": [
    {"user_id": "alice", "role": "admin"},
    {"user_id": "bob", "role": "user"}
  ]
}
DELETE /api/v1/admin/accounts/{account_id}/users/{user_id}Role: ROOT, ADMINExample:
curl -X DELETE http://localhost:1933/api/v1/admin/accounts/acme/users/bob \
  -H "X-API-Key: admin-key"
PUT /api/v1/admin/accounts/{account_id}/users/{user_id}/roleRole: ROOTRequest:
{
  "role": "admin"
}
POST /api/v1/admin/accounts/{account_id}/users/{user_id}/keyRole: ROOT, ADMINResponse:
{
  "status": "ok",
  "result": {
    "user_key": "uk_new_key..."
  }
}

Development Mode

When no root_api_key is configured, authentication is disabled.
{
  "server": {
    "host": "127.0.0.1",
    "port": 1933
  }
}
Security: Dev mode (no auth) is only allowed when binding to localhost (127.0.0.1, localhost, or ::1). If host is set to 0.0.0.0 without a root_api_key, the server will refuse to start.

Unauthenticated Endpoints

The /health endpoint never requires authentication:
curl http://localhost:1933/health
# {"status": "ok"}
This allows load balancers and monitoring tools to check server health without credentials.

Best Practices

1

Generate Strong Keys

Use cryptographically secure random keys:
openssl rand -base64 32
2

Rotate Keys Regularly

Regenerate user keys periodically:
curl -X POST http://localhost:1933/api/v1/admin/accounts/acme/users/bob/key \
  -H "X-API-Key: admin-key"
3

Use Separate Keys per Agent

Create different user keys for each agent/service:
# Agent A
curl -X POST .../users -d '{"user_id": "agent-a", "role": "user"}'

# Agent B
curl -X POST .../users -d '{"user_id": "agent-b", "role": "user"}'
4

Store Keys Securely

Use environment variables or secret managers:
import os

client = ov.SyncHTTPClient(
    url=os.environ["OPENVIKING_URL"],
    api_key=os.environ["OPENVIKING_API_KEY"]
)

Configuration

Server configuration reference

Deployment

Production deployment guide

Python SDK

Client authentication setup

CLI Usage

CLI authentication setup