afx-team / afx-team/hebb-mind

discussion: multi-tenant / hosted / auth model for team-scale adoption

Aperta
#33 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub
area: security needs-discussion
Lingua principale
Python
Stelle
52
Fork
18
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

## Context

For the cross-cutting goal "every agent, at team scale, can adopt us," Hebb Mind first has to answer a question it has so far deferred: **what is our multi-tenant / hosted / auth model?** Today the framework is a single-user, loopback-only service with no authentication and no tenancy boundary. The moment a team wants multiple agents (or multiple users) to share one deployment, every one of those gaps becomes blocking. This is a **discussion** issue: the deliverable is a decision doc and a chosen direction, not code.

## Current state

The server is **single-user localhost with zero auth**, verified against the current tree (post audit-remediation merge, PR #24):

- Default bind address is loopback: `host: str = Field(default="127.0.0.1", ...)` in `src/hebb/config/settings.py:133-138`. (Note: the 2026-06-07 audit recorded the old default as `0.0.0.0`; that has since been changed to `127.0.0.1`, with remote exposure now an explicit opt-in.)
- **No authentication on any route.** Every router dependency injects only store/settings/searcher/etc. — there is no auth `Depends()` anywhere. See `src/hebb/server/dependencies.py:17-43` (the full set of providers: `get_settings`, `get_memory_store`, `get_partition_store`, `get_embedder`, `get_knowledge_graph`, `get_searcher`, `get_scheduler` — none authenticate) and e.g. `src/hebb/server/routers/search.py:16-22`, `src/hebb/server/routers/partitions.py:14-39`.
- The only browser-borne protection is `AntiCsrfMiddleware`, an **origin check, not authentication**: it passes any request without an `Origin` header (CLI, MCP, server-to-server) straight through. See `src/hebb/server/auth.py:1-19, 62-105`. Its own docstring states the server "ships with no authentication."
- CORS is now restricted to loopback console origins with credentials disabled (`src/hebb/server/app.py:121-138`, `src/hebb/config/settings.py:202-216`) — a real improvement over the audited `allow_origins=["*"] + allow_credentials=True`, but it does not add auth.
- The plaintext-key endpoint `GET /api/v1/admin/config/reveal/{key}` **still exists** (`src/hebb/server/routers/config.py:184-185`); it is now guarded against cross-origin browser reads by the CSRF middleware but remains unauthenticated for any client that omits an `Origin` header. (The remediation hardened, not removed, this surface.)
- **Partitions are not a tenancy boundary.** `src/hebb/server/routers/partitions.py` exposes full unauthenticated CRUD and `list()`; there is no caller identity, no ACL, and no isolation guarantee between partitions — a partition is an organizational label, not a security boundary.

Net: the moment `host != 127.0.0.1` (an explicit but available opt-in), any host that can reach the port can read all memories, mutate config, reveal secrets, and restart the service. That threat model is acceptable for single-user localhost and unacceptable for "every agent connects."

## Proposed approach

Run a focused design discussion and land a decision doc in `reports/design/`. The doc should resolve the open questions below, pick a direction, and define a phased path (auth first, then tenancy, then optional hosting) without committing implementation here.

## Open questions

- [ ] **Hosting posture** — do we offer a hosted/managed tier, or stay self-host only? This gates everything downstream.
- [ ] **Auth model** — static bearer token (simplest, per-deployment) vs per-tenant API keys vs OIDC/JWT for org SSO. What is the minimum viable choice, and what is the 1.0 target?
- [ ] **Tenant ↔ partition mapping** — do partitions become the tenancy unit? What isolation/ACL guarantees do we make (logical filter vs enforced row-level / per-tenant DB), and how is caller identity threaded from the API/MCP/hook surfaces down to the store?
- [ ] **Storage-backend coupling** — real multi-tenant isolation likely needs Postgres/pgvector rather than the single-connection SQLite ceiling. How does this decision interlock with the storage-backend strategy (roadmap **D4**)?
- [ ] **Threat model once `host != 127.0.0.1`** — enumerate the surface (admin/config, `/reveal`, test endpoints that contact external URLs, restart/upgrade routes) and define what auth + transport (TLS/reverse-proxy) is mandatory before remote bind is supported, vs. what stays loopback-only.

## Acceptance criteria

- [ ] A decision doc lands in `reports/design/` capturing the discussion, the open questions above, and a chosen direction.
- [ ] Hosting posture (self-host only vs managed tier) is decided.
- [ ] An auth model (token / per-tenant key / OIDC) is selected, at least for the near-term milestone.
- [ ] The partition-vs-tenant isolation model and its concrete guarantees are written down.
- [ ] The relationship to the storage-backend decision (D4) is stated explicitly.
- [ ] A threat model for the non-loopback case is recorded, with the minimum security bar for supporting remote bind.

## Scope / out of scope

- **In scope:** the decision and its rationale — posture, auth model, tenancy/ACL guarantees, threat model, and the D4 interlock.
- **Out of scope:** any implementation. No code is expected from this issue; follow-up implementation issues will be split out once the direction is chosen. The CSRF/CORS/loopback hardening from PR #24 is already landed and is not re-litigated here.

## References

- `reports/audit/core-system-audit-2026-06-07.md` — cluster **C2** (network exposure + zero auth + plaintext keys), including the unified fix direction (bind 127.0.0.1, add bearer token on remote opt-in, auth on admin/config).
- `reports/audit/newuser-experience-audit-2026-06-08.md` — new-user/first-run experience context.
- `reports/design/capability-gap-roadmap-2026-06-11.md` — discussion item **D3** (multi-tenant / hosted / security model) and its dependency on **D4** (storage backend).

Filed from the capability-gap roadmap (reports/design/capability-gap-roadmap-2026-06-11.md).

Guida per i contributori

Apri la guida per i contributori

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.