Repository navigation
Description
Context
Flagged during a review of standard enterprise functionality against the current stack (Phase 4d complete). Isolation today is per-user (user_id, derived from the validated Keycloak sub claim), enforced structurally by ThreadRepository/APIKeyRepository and the doc-search MCP boundary (see docs/SECURITY.md's "MCP Server Isolation" and docs/REPOSITORY_PATTERN.md). There is no organization/tenant concept anywhere in the schema, auth flow, or Keycloak realm config.
The gap
This is fine — arguably correct — for the assumed deployment shape: one Keycloak realm per organization, one EAIStack deployment per organization, fully isolated at the infrastructure level (separate K8s namespace/cluster per org). But that assumption is implicit, not written down anywhere. A fork evaluating this template for a multi-tenant SaaS use case (one deployment serving multiple customer organizations, sharing a Postgres instance/knowledge base pool) would currently discover the absence of tenant isolation by reading code, not by reading a doc that told them upfront.
This is different in kind from the other three gaps identified in the same review (observability #4, backups #12, rate limiting) — those are missing functionality to build. This one is a missing scope statement about an architectural boundary that's already correct for the intended use case and shouldn't be casually extended.
Scope
This issue is documentation-only, not a feature to build:
- Add a short, explicit section to
docs/ARCHITECTURE.md(ordocs/SECURITY.md, near "MCP Server Isolation") stating: isolation is per-user within a single organization/realm; cross-organization multi-tenancy (shared DB/deployment serving multiple customer orgs) is out of scope; the supported deployment pattern is one Keycloak realm + one EAIStack deployment per organization. - State the upgrade path for a fork that needs true multi-tenant SaaS isolation (e.g. a
tenant_idcolumn threaded through every repository query alongsideuser_id, tenant-scoped Keycloak realms or a multi-realm token-audience check, row-level security in Postgres) — same treatmentdocs/SECURITY.mdalready gives the "No KMS in v1" gap: documented upgrade path, not built in, to keep template complexity down. - Cross-reference from
CLAUDE.md's constraints section so it's visible alongside the other stated hard constraints (air-gapped, K8s-native, etc).
Done when
A reader evaluating this template for a multi-tenant SaaS use case can find, in one place, that this isolation boundary doesn't exist yet and what the upgrade path would look like — without having to read repository code to discover it.
Activity
Document single-organization tenancy scope and the multi-tenant upgra…