Skip to content

Authentication

OpenViking Server supports three authentication modes with role-based access control: api_key, trusted, and dev. The mode is auto-detected if not explicitly configured.

Overview

OpenViking uses a two-layer API key system:

Key TypeCreated ByRolePurpose
Root KeyServer config (root_api_key)ROOTAccount management + selected system/monitoring operations
User KeyAdmin APIADMIN or USERPer-account data access; ADMIN can also manage users in its account

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.

Authentication Modes

Modeserver.auth_modeIdentity SourceTypical Use
API key mode"api_key"API key. Data ownership is resolved from the user/admin key.Standard multi-tenant deployment
Trusted mode"trusted"X-OpenViking-Account / X-OpenViking-User, plus root_api_key on non-localhost deployments. Role is looked up from APIKeyManager if the user exists.Behind a trusted gateway or internal network boundary
Dev mode"dev"No authentication, always ROOTLocal development only

If auth_mode is not explicitly configured:

  • If root_api_key is set (non-empty): auto-selects api_key mode
  • If root_api_key is not set: auto-selects dev mode

Note: Setting root_api_key to an empty string "" is invalid. Either set a non-empty value or remove the setting entirely.

Setting Up (Server Side)

Configure the authentication mode in the server section of ov.conf:

json
{
  "server": {
    "auth_mode": "api_key",
    "root_api_key": "your-secret-root-key"
  }
}

Start the server:

bash
openviking-server

Managing Accounts and Users

Normal requests in both api_key and trusted modes do not need Admin API as a prerequisite for ordinary reads, writes, search, or session access. Admin API is still the place to create accounts, register users, change roles, and issue user keys.

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

bash
# Create account with first admin
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"}'
# Returns: {"result": {"account_id": "acme", "admin_user_id": "alice", "user_key": "..."}}

# Register a regular user (as ROOT or ADMIN)
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"}'
# Returns: {"result": {"account_id": "acme", "user_id": "bob", "user_key": "..."}}

Trusted deployments can also call Admin API through a trusted gateway. There are two supported patterns:

  • Present only the trusted deployment's root_api_key. For /api/v1/admin/*, the server treats the request as ROOT even without X-OpenViking-Account / X-OpenViking-User.
  • Present X-OpenViking-Account + X-OpenViking-User for a registered gateway user. In that case the server looks up the effective role from the user registry.

Example using a registered gateway user:

bash
# First, register the gateway admin (do this once in api_key mode)
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": "platform", "admin_user_id": "gateway-admin"}'

# Then promote it to root if it needs cross-account admin access
curl -X PUT http://localhost:1933/api/v1/admin/accounts/platform/users/gateway-admin/role \
  -H "X-API-Key: your-secret-root-key" \
  -H "Content-Type: application/json" \
  -d '{"role": "root"}'

# Then, in trusted mode, use that identity to call Admin API
curl -X POST http://localhost:1933/api/v1/admin/accounts \
  -H "X-API-Key: your-secret-root-key" \
  -H "X-OpenViking-Account: platform" \
  -H "X-OpenViking-User: gateway-admin" \
  -H "Content-Type: application/json" \
  -d '{
    "account_id": "acme",
    "admin_user_id": "alice"
  }'

Using API Keys (Client Side)

OpenViking accepts API keys via two headers:

X-API-Key header

bash
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
  -H "X-API-Key: <user-key>"

Authorization: Bearer header

bash
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
  -H "Authorization: Bearer <user-key>"

Python SDK (HTTP)

python
import openviking as ov

client = ov.SyncHTTPClient(
    url="http://localhost:1933",
    api_key="<user-key>",
)

CLI (via ovcli.conf)

json
{
  "url": "http://localhost:1933",
  "api_key": "<user-key>"
}

When you use a user key or admin key, the server derives account and user from the key. Do not send X-OpenViking-Account / X-OpenViking-User in api_key mode; those identity headers are accepted only in trusted mode.

CLI override flags

bash
openviking ls viking://

Using --sudo with Root API Key

The CLI supports configuring both api_key (for regular user operations) and root_api_key (for admin operations) in ovcli.conf:

json
{
  "url": "http://localhost:1933",
  "api_key": "<user-key>",
  "root_api_key": "<root-key>"
}

When you need to perform admin commands (admin, system, reindex), use the --sudo flag to elevate privileges:

bash
# List all accounts (requires root privileges)
ov --sudo admin list-accounts

# System commands
ov --sudo system status

The --sudo flag:

  • Only works with management/system commands: admin, system
  • Will error if used with non-admin commands
  • Will error if root_api_key is not configured in ovcli.conf
  • Uses root_api_key instead of api_key for the request

Tenant Data Access

Tenant-scoped data APIs (for example ls, find, resources, and sessions) must use a key that is bound to an account/user in api_key mode. That can be a USER key or an ADMIN key; an ADMIN key accesses data as its own user and cannot switch identity with X-OpenViking-Account / X-OpenViking-User.

A ROOT key is not bound to a tenant user, so it cannot access tenant-scoped data APIs in api_key mode. If a deployment needs an upstream gateway to assert account / user, use trusted mode instead of passing identity headers with a root key.

ovcli.conf

json
{
  "url": "http://localhost:1933",
  "auth_mode": "trusted",
  "api_key": "your-trusted-server-key",
  "account": "acme",
  "user": "alice"
}

Trusted Mode

Trusted mode skips user-key lookup and instead trusts explicit identity headers on each request:

json
{
  "server": {
    "auth_mode": "trusted",
    "host": "127.0.0.1"
  }
}

Rules in trusted mode:

  • Normal data access does not require user registration or user-key provisioning first.
  • X-OpenViking-Account and X-OpenViking-User are required on tenant-scoped requests.
  • Use request-level peer_id for stable interaction peers in session memory and retrieval APIs.
  • /api/v1/admin/* is special: when no explicit identity is provided, trusted mode treats the request as ROOT. This is intended for trusted upstreams that authenticate only with the deployment's root API key.
  • Role is determined by looking up the account/user in APIKeyManager. If the user exists, their configured role is used; otherwise it defaults to USER.
  • Trusted identity comes from the headers, not from a user key. If root_api_key is configured, it still acts as proof that the caller is an approved trusted upstream.
  • If root_api_key is also configured, every request must still provide a matching API key.
  • Only expose this mode behind a trusted network boundary or an identity-injecting gateway.

Implications:

  • Trusted mode is not development mode.
  • Trusted mode does not use the Admin API as a prerequisite for ordinary reads, writes, search, or session access.
  • Admin API remains available in trusted mode for users that have been registered with appropriate roles (root/admin).
  • Trusted Admin API responses omit user_key from account creation and user registration results.
  • root can create/delete accounts and change roles; admin can manage users inside its own account; user cannot call Admin API.
  • To use Admin API in trusted mode, first register the gateway's service account with the appropriate role using the Admin API in api_key mode.

curl

bash
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
  -H "X-OpenViking-Account: acme" \
  -H "X-OpenViking-User: alice"

Python SDK

python
import openviking as ov

client = ov.SyncHTTPClient(
    url="http://localhost:1933",
    account="acme",
    user="alice",
)

Dev Mode

When auth_mode = "dev" (or auto-detected when no root_api_key is configured), authentication is disabled. All requests are accepted as ROOT with the default account. This is only allowed when the server binds to localhost (127.0.0.1, localhost, or ::1). If host is set to a non-loopback address (e.g. 0.0.0.0) in dev mode, the server will refuse to start.

json
{
  "server": {
    "host": "127.0.0.1",
    "port": 1933
  }
}

Or explicitly:

json
{
  "server": {
    "auth_mode": "dev",
    "host": "127.0.0.1",
    "port": 1933
  }
}

Security note: The default host is 127.0.0.1. If you need to expose the server on the network, you must configure root_api_key.

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.)

In trusted mode, ordinary tenant requests default to USER unless the account/user is registered with a higher role. Admin routes also allow a trusted ROOT fallback when no explicit identity is provided.

Unauthenticated Endpoints

The /health endpoint never requires authentication. This allows load balancers and monitoring tools to check server health.

bash
curl http://localhost:1933/health

Admin API Reference

MethodEndpointRoleDescription
POST/api/v1/admin/accountsROOTCreate account with first admin
GET/api/v1/admin/accountsROOTList all accounts
DELETE/api/v1/admin/accounts/{id}ROOTDelete account
POST/api/v1/admin/accounts/{id}/usersROOT, ADMINRegister user
GET/api/v1/admin/accounts/{id}/usersROOT, ADMINList users
DELETE/api/v1/admin/accounts/{id}/users/{uid}ROOT, ADMINRemove user
PUT/api/v1/admin/accounts/{id}/users/{uid}/roleROOTChange user role
POST/api/v1/admin/accounts/{id}/users/{uid}/keyROOT, ADMINRegenerate user key

Released under the Apache-2.0 License.