docs: clarify operator trust boundary for shared gateways

This commit is contained in:
Peter Steinberger
2026-02-24 00:24:48 +00:00
parent f0c3c8b6a3
commit 7d55277d72
2 changed files with 21 additions and 1 deletions

View File

@@ -39,6 +39,7 @@ For fastest triage, include all of the following:
- Reproducible PoC against latest `main` or latest released version.
- Demonstrated impact tied to OpenClaw's documented trust boundaries.
- For exposed-secret reports: proof the credential is OpenClaw-owned (or grants access to OpenClaw-operated infrastructure/services).
- Explicit statement that the report does not rely on adversarial operators sharing one gateway host/config.
- Scope check explaining why the report is **not** covered by the Out of Scope section below.
Reports that miss these requirements may be closed as `invalid` or `no-action`.
@@ -75,11 +76,20 @@ The best way to help the project right now is by sending PRs.
When patching a GHSA via `gh api`, include `X-GitHub-Api-Version: 2022-11-28` (or newer). Without it, some fields (notably CVSS) may not persist even if the request returns 200.
## Operator Trust Model (Important)
OpenClaw does **not** model one gateway as a multi-tenant, adversarial user boundary.
- Authenticated Gateway callers are treated as trusted operators for that gateway instance.
- Session identifiers (`sessionKey`, session IDs, labels) are routing controls, not per-user authorization boundaries.
- If one operator can view data from another operator on the same gateway, that is expected in this trust model.
- If you need adversarial-user isolation, split by trust boundary (separate OS users/hosts/gateways).
## Out of Scope
- Public Internet Exposure
- Using OpenClaw in ways that the docs recommend not to
- Deployments where mutually untrusted/adversarial operators share one gateway host and config
- Deployments where mutually untrusted/adversarial operators share one gateway host and config (for example, reports expecting per-operator isolation for `sessions.list`, `sessions.preview`, `chat.history`, or similar control-plane reads)
- Prompt injection attacks
- Reports that require write access to trusted local state (`~/.openclaw`, workspace files like `MEMORY.md` / `memory/*.md`)
- Reports that depend on trusted operator-supplied configuration values to trigger availability impact (for example custom regex patterns). These may still be fixed as defense-in-depth hardening, but are not security-boundary bypasses.

View File

@@ -38,6 +38,15 @@ OpenClaw assumes the host and config boundary are trusted:
- Running one Gateway for multiple mutually untrusted/adversarial operators is **not a recommended setup**.
- For mixed-trust teams, split trust boundaries with separate gateways (or at minimum separate OS users/hosts).
### Practical consequence (operator trust boundary)
Inside one Gateway instance, authenticated operator access is a trusted control-plane role, not a per-user tenant role.
- Operators with read/control-plane access can inspect gateway session metadata/history by design.
- Session identifiers (`sessionKey`, session IDs, labels) are routing selectors, not authorization tokens.
- Example: expecting per-operator isolation for methods like `sessions.list`, `sessions.preview`, or `chat.history` is outside this model.
- If you need adversarial-user isolation, run separate gateways per trust boundary.
## Trust boundary matrix
Use this as the quick model when triaging risk:
@@ -57,6 +66,7 @@ These patterns are commonly reported and are usually closed as no-action unless
- Prompt-injection-only chains without a policy/auth/sandbox bypass.
- Claims that assume hostile multi-tenant operation on one shared host/config.
- Claims that classify normal operator read-path access (for example `sessions.list`/`sessions.preview`/`chat.history`) as IDOR in a shared-gateway setup.
- Localhost-only deployment findings (for example HSTS on loopback-only gateway).
- Discord inbound webhook signature findings for inbound paths that do not exist in this repo.
- "Missing per-user authorization" findings that treat `sessionKey` as an auth token.