Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/en/guides/01-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -854,12 +854,12 @@ When running OpenViking as an HTTP service, add a `server` section to `ov.conf`:
| `host` | str | Bind address | `0.0.0.0` |
| `port` | int | Bind port | `1933` |
| `auth_mode` | str | Authentication mode: `"api_key"` or `"trusted"`. Default is `"api_key"` | `"api_key"` |
| `root_api_key` | str | Root API key for multi-tenant auth in `api_key` mode. In `trusted` mode it is optional extra protection, not the source of user identity | `null` |
| `root_api_key` | str | Root API key for multi-tenant auth in `api_key` mode. In `trusted` mode it is optional on localhost, but required for any non-localhost deployment; it does not become the source of user identity | `null` |
| `cors_origins` | list | Allowed CORS origins | `["*"]` |

`api_key` mode uses API keys and is the default. `trusted` mode trusts `X-OpenViking-Account` / `X-OpenViking-User` headers from a trusted gateway or internal caller.

When `root_api_key` is configured in `api_key` mode, the server enables multi-tenant authentication. Use the Admin API to create accounts and user keys. In `trusted` mode, ordinary requests do not require user registration first; each request is resolved as `USER` from the injected identity headers. Development mode only applies when `auth_mode = "api_key"` and `root_api_key` is not set.
When `root_api_key` is configured in `api_key` mode, the server enables multi-tenant authentication. Use the Admin API to create accounts and user keys. In `trusted` mode, ordinary requests do not require user registration first; each request is resolved as `USER` from the injected identity headers. However, skipping `root_api_key` in `trusted` mode is allowed only on localhost. Development mode only applies when `auth_mode = "api_key"` and `root_api_key` is not set.

For startup and deployment details see [Deployment](./03-deployment.md), for authentication see [Authentication](./04-authentication.md).

Expand Down
4 changes: 2 additions & 2 deletions docs/en/guides/04-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ All API keys are plain random tokens with no embedded identity. The server resol
| Mode | `server.auth_mode` | Identity Source | Typical Use |
|------|--------------------|-----------------|-------------|
| API key mode | `"api_key"` | API key, with optional tenant headers for root requests | Standard multi-tenant deployment |
| Trusted mode | `"trusted"` | `X-OpenViking-Account` / `X-OpenViking-User` / optional `X-OpenViking-Agent` headers | Behind a trusted gateway or internal network boundary |
| Trusted mode | `"trusted"` | `X-OpenViking-Account` / `X-OpenViking-User` / optional `X-OpenViking-Agent` headers, plus `root_api_key` on non-localhost deployments | Behind a trusted gateway or internal network boundary |

`api_key` is the default and standard production mode. `trusted` is an alternative mode for deployments where an upstream gateway or trusted internal caller injects identity headers on every request.
`api_key` is the default and standard production mode. `trusted` is an alternative mode for deployments where an upstream gateway or trusted internal caller injects identity headers on every request. In `trusted` mode, running without `root_api_key` is allowed only when the server binds to localhost; non-localhost `trusted` deployments must configure `root_api_key`.

## Setting Up (Server Side)

Expand Down
4 changes: 2 additions & 2 deletions docs/zh/guides/04-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ OpenViking 使用两层 API Key 体系:
| 模式 | `server.auth_mode` | 身份来源 | 典型使用场景 |
|------|--------------------|----------|--------------|
| API Key 模式 | `"api_key"` | API Key,root 请求可附带租户请求头 | 标准多租户部署 |
| Trusted 模式 | `"trusted"` | `X-OpenViking-Account` / `X-OpenViking-User` / 可选 `X-OpenViking-Agent` 请求头 | 部署在受信网关或内网边界之后 |
| Trusted 模式 | `"trusted"` | `X-OpenViking-Account` / `X-OpenViking-User` / 可选 `X-OpenViking-Agent` 请求头;非 localhost 部署还必须配置 `root_api_key` | 部署在受信网关或内网边界之后 |

`api_key` 是默认模式,也是标准生产部署方式。`trusted` 是替代模式,适合由上游网关或受信内网调用方在每个请求里显式注入身份头。
`api_key` 是默认模式,也是标准生产部署方式。`trusted` 是替代模式,适合由上游网关或受信内网调用方在每个请求里显式注入身份头。在 `trusted` 模式下,只有服务绑定到 localhost 时才允许不配置 `root_api_key`;只要是非 localhost 部署,就必须配置 `root_api_key`。

## 服务端配置

Expand Down
2 changes: 1 addition & 1 deletion openviking/console/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ http://127.0.0.1:8020/
```

4. In **Settings**, configure headers for your upstream auth mode.
`api_key` is the default server mode, so in that mode you normally paste `X-API-Key` and click **Save** (or press Enter). If the upstream server runs in `trusted` mode, you usually do not need `X-API-Key` for ordinary requests; instead set `X-OpenViking-Account` and `X-OpenViking-User` (and optionally `X-OpenViking-Agent`).
`api_key` is the default server mode, so in that mode you normally paste `X-API-Key` and click **Save** (or press Enter). If the upstream server runs in `trusted` mode, you can omit `X-API-Key` for ordinary requests only when that server is localhost-only and has no `root_api_key`; otherwise you still need `X-API-Key`, and you should also set `X-OpenViking-Account` and `X-OpenViking-User` (and optionally `X-OpenViking-Agent`).
`X-API-Key` is stored locally in the browser and restored into the current tab.

When the upstream server runs in `trusted` mode, ordinary access does not require user registration first. If you try account or user management actions against Admin API endpoints in `trusted` mode, the server now returns an explicit error explaining that `trusted` mode resolves requests as `USER` and that account/user management requires `api_key` mode with `root_api_key`.
Expand Down
5 changes: 3 additions & 2 deletions openviking/server/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,9 @@ async def lifespan(app: FastAPI):
else:
logger.warning(
"Trusted mode enabled: authentication uses X-OpenViking-Account/User/Agent "
"headers without API keys. Only expose this server behind a trusted "
"network boundary or identity-injecting gateway."
"headers without API keys. This is only allowed on localhost. "
"Only expose this server behind a trusted network boundary or "
"identity-injecting gateway after configuring server.root_api_key."
)
else:
app.state.api_key_manager = None
Expand Down
23 changes: 16 additions & 7 deletions openviking/server/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,22 @@ def validate_server_config(config: ServerConfig) -> None:
sys.exit(1)

if config.auth_mode == "trusted":
if not _is_localhost(config.host):
logger.warning(
"SECURITY: server.auth_mode='trusted' on non-localhost host '%s'. "
"Only use this behind a trusted network boundary or identity-injecting gateway.",
config.host,
)
return
if config.root_api_key:
return
if _is_localhost(config.host):
return
logger.error(
"SECURITY: server.auth_mode='trusted' requires server.root_api_key when "
"server.host is '%s' (non-localhost). Only localhost trusted mode may run "
"without an API key.",
config.host,
)
logger.error(
"To fix, either:\n"
" 1. Set server.root_api_key in ov.conf, or\n"
' 2. Bind trusted mode to localhost (server.host = "127.0.0.1")'
)
sys.exit(1)

if config.root_api_key:
return
Expand Down
14 changes: 11 additions & 3 deletions tests/server/test_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -784,7 +784,15 @@ def test_validate_with_key_any_host_passes():
validate_server_config(config) # should not raise


def test_validate_trusted_mode_without_key_non_localhost_passes():
"""Trusted mode should bypass the localhost-only dev-mode restriction."""
def test_validate_trusted_mode_without_key_localhost_passes():
"""Trusted mode without root_api_key should still be allowed on localhost only."""
for host in ("127.0.0.1", "localhost", "::1"):
config = ServerConfig(host=host, root_api_key=None, auth_mode="trusted")
validate_server_config(config)


def test_validate_trusted_mode_without_key_non_localhost_raises():
"""Trusted mode without root_api_key should be rejected off localhost."""
config = ServerConfig(host="0.0.0.0", root_api_key=None, auth_mode="trusted")
validate_server_config(config)
with pytest.raises(SystemExit):
validate_server_config(config)
Loading