| 1 | # Workroom Security Model |
| 2 | |
| 3 | ## Scope |
| 4 | |
| 5 | This document covers the security boundaries of CodeWhale Workrooms — the |
| 6 | durable, addressable containers for threaded agent conversations described |
| 7 | in [RFC 3209](rfcs/3209-workrooms.md). |
| 8 | |
| 9 | Workrooms do **not** introduce any new network services, cloud dependencies, |
| 10 | or default-on public sharing. Security responsibility stays with the |
| 11 | operator who controls the Runtime API. |
| 12 | |
| 13 | This document describes the intended security contract for the v0.9 workroom |
| 14 | surface. In v0.8.62, only protocol data types and link parsing have landed. |
| 15 | Persistent state, Runtime API endpoints, token scoping, event storage, and |
| 16 | model-visible link resolution remain follow-up work. |
| 17 | |
| 18 | ## Principles |
| 19 | |
| 20 | 1. **Local-first.** Future persisted workroom state should live under the |
| 21 | CodeWhale home directory, protected by user-only filesystem permissions. |
| 22 | No cloud sync and no third-party hosting. Workroom content is never a |
| 23 | telemetry subject: the opt-in product telemetry in `docs/TELEMETRY.md` |
| 24 | collects counts and closed enums only, and no workroom id, title, link, or |
| 25 | body may ever be added to its schema. That telemetry now has a live ingest |
| 26 | endpoint (`https://telemetry.codewhale.net/v1/telemetry`, source in |
| 27 | `telemetry-ingest/`), which makes the rule enforced rather than merely |
| 28 | stated: the endpoint validates against a **closed** field set and rejects an |
| 29 | entire batch carrying any key the published schema does not name, so a |
| 30 | workroom field added by accident is refused at ingest rather than stored. |
| 31 | Telemetry remains opt-in and off until the first-run notice is answered with |
| 32 | Enable, so the default posture for workroom content is still that no batch |
| 33 | exists at all. |
| 34 | |
| 35 | 2. **No secrets in links.** `codewhale://workroom/wr_...` URLs contain only |
| 36 | opaque UUIDs. They carry no API keys, bearer tokens, passwords, or file |
| 37 | paths. An adversary with a workroom link can do nothing without Runtime |
| 38 | API access. |
| 39 | |
| 40 | 3. **No public read paths.** Future workroom endpoints must require a valid |
| 41 | bearer token in the `Authorization` header. There should be no |
| 42 | unauthenticated `/workroom/...` route. |
| 43 | |
| 44 | 4. **No secrets in events.** `WorkroomEvent` payloads must never contain |
| 45 | API keys, auth tokens, or plaintext credentials. The `ArtifactLinked` |
| 46 | event kind references file paths, not contents. Events are intended for |
| 47 | indexing/reference, not for replaying agent tool output. |
| 48 | |
| 49 | 5. **Share is explicit.** A workroom is `Private` by default. The operator |
| 50 | may mark it `Shared` and list allowed bearer tokens. The operator |
| 51 | controls which tokens are issued, rotated, and revoked. |
| 52 | |
| 53 | ## Threat model |
| 54 | |
| 55 | | Threat | Mitigation | |
| 56 | |---|---| |
| 57 | | Attacker obtains a workroom link | Link contains only opaque UUID; resolution requires Runtime API auth | |
| 58 | | Attacker brute-forces workroom IDs | UUID v4 (`2^122` space); future APIs should add rate limiting before exposing lookup surfaces | |
| 59 | | Attacker injects a malicious event | Future event writes should flow only through trusted Runtime clients | |
| 60 | | Attacker exfiltrates workroom state | Future filesystem state should be gated by OS user permissions and runtime auth | |
| 61 | | Bearer token leaks | Operator rotates tokens; future sharing rules should be revocable without touching workroom state | |
| 62 | |
| 63 | ## API auth |
| 64 | |
| 65 | Future workroom endpoints should inherit the same auth middleware as other |
| 66 | protected routes (`/thread`, `/app`, `/tool`, etc.): |
| 67 | |
| 68 | - `Authorization: Bearer <token>` header required |
| 69 | - Token validated against the runtime's configured bearer token(s) |
| 70 | - 401 Unauthorized if missing or invalid |
| 71 | |
| 72 | ## Future work |
| 73 | |
| 74 | | Item | Risk | Status | |
| 75 | |---|---|---| |
| 76 | | Event encryption at rest | In scope for Phase 2 if workrooms move to a multi-user model | Not implemented | |
| 77 | | Audit log for shared workrooms | Useful if shared tokens are used across operators | Not implemented | |
| 78 | | Token scoping (read/write/admin) | Currently all tokens have full access | Not planned | |
| 79 |