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
37 changes: 37 additions & 0 deletions docs/en/guides/04-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,43 @@ client = ov.SyncHTTPClient(
}
```

### Accessing Tenant Data with Root Key

When using the root key to access tenant-scoped data APIs (e.g. `ls`, `find`, `sessions`), you must specify the target account and user. The server will reject the request otherwise. Admin API and system status endpoints are not affected.

**curl**

```bash
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
-H "X-API-Key: your-secret-root-key" \
-H "X-OpenViking-Account: acme" \
-H "X-OpenViking-User: alice"
```

**Python SDK**

```python
import openviking as ov

client = ov.SyncHTTPClient(
url="http://localhost:1933",
api_key="your-secret-root-key",
account="acme",
user="alice",
)
```

**ovcli.conf**

```json
{
"url": "http://localhost:1933",
"api_key": "your-secret-root-key",
"account": "acme",
"user": "alice"
}
```

## Roles and Permissions

| Role | Scope | Capabilities |
Expand Down
37 changes: 37 additions & 0 deletions docs/zh/guides/04-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,43 @@ client = ov.SyncHTTPClient(
}
```

### 使用 Root Key 访问租户数据

使用 root key 访问租户级数据 API(如 `ls`、`find`、`sessions` 等)时,必须指定目标 account 和 user,否则服务端将拒绝请求。Admin API 和系统状态端点不受此限制。

**curl**

```bash
curl http://localhost:1933/api/v1/fs/ls?uri=viking:// \
-H "X-API-Key: your-secret-root-key" \
-H "X-OpenViking-Account: acme" \
-H "X-OpenViking-User: alice"
```

**Python SDK**

```python
import openviking as ov

client = ov.SyncHTTPClient(
url="http://localhost:1933",
api_key="your-secret-root-key",
account="acme",
user="alice",
)
```

**ovcli.conf**

```json
{
"url": "http://localhost:1933",
"api_key": "your-secret-root-key",
"account": "acme",
"user": "alice"
}
```

## 角色与权限

| 角色 | 作用域 | 能力 |
Expand Down
14 changes: 14 additions & 0 deletions openviking_cli/client/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ def __init__(
url: Optional[str] = None,
api_key: Optional[str] = None,
agent_id: Optional[str] = None,
account: Optional[str] = None,
user: Optional[str] = None,
timeout: float = 60.0,
):
"""Initialize AsyncHTTPClient.
Expand All @@ -143,6 +145,10 @@ def __init__(
url: OpenViking Server URL. If not provided, reads from ovcli.conf.
api_key: API key for authentication. If not provided, reads from ovcli.conf.
agent_id: Agent identifier. If not provided, reads from ovcli.conf.
account: Account identifier for multi-tenant auth. Required when using root key
to access tenant-scoped APIs. If not provided, reads from ovcli.conf.
user: User identifier for multi-tenant auth. Required when using root key
to access tenant-scoped APIs. If not provided, reads from ovcli.conf.
timeout: HTTP request timeout in seconds. Default 60.0.
"""
if url is None:
Expand All @@ -155,6 +161,8 @@ def __init__(
url = cfg.get("url")
api_key = api_key or cfg.get("api_key")
agent_id = agent_id or cfg.get("agent_id")
account = account or cfg.get("account")
user = user or cfg.get("user")
if timeout == 60.0: # only override default with config value
timeout = cfg.get("timeout", 60.0)
if not url:
Expand All @@ -165,6 +173,8 @@ def __init__(
self._url = url.rstrip("/")
self._api_key = api_key
self._agent_id = agent_id
self._account = account
self._user_id = user
self._user = UserIdentifier.the_default_user()
self._timeout = timeout
self._http: Optional[httpx.AsyncClient] = None
Expand All @@ -179,6 +189,10 @@ async def initialize(self) -> None:
headers["X-API-Key"] = self._api_key
if self._agent_id:
headers["X-OpenViking-Agent"] = self._agent_id
if self._account:
headers["X-OpenViking-Account"] = self._account
if self._user_id:
headers["X-OpenViking-User"] = self._user_id
self._http = httpx.AsyncClient(
base_url=self._url,
headers=headers,
Expand Down
9 changes: 8 additions & 1 deletion openviking_cli/client/sync_http.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,17 @@ def __init__(
url: Optional[str] = None,
api_key: Optional[str] = None,
agent_id: Optional[str] = None,
account: Optional[str] = None,
user: Optional[str] = None,
timeout: float = 60.0,
):
self._async_client = AsyncHTTPClient(
url=url, api_key=api_key, agent_id=agent_id, timeout=timeout
url=url,
api_key=api_key,
agent_id=agent_id,
account=account,
user=user,
timeout=timeout,
)
self._initialized = False

Expand Down
Loading