Skip to content

Document multi-tenancy scope: single-org isolation only, not multi-tenant SaaS #26

Closed

Description

@prometheusgr

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:

  1. Add a short, explicit section to docs/ARCHITECTURE.md (or docs/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.
  2. State the upgrade path for a fork that needs true multi-tenant SaaS isolation (e.g. a tenant_id column threaded through every repository query alongside user_id, tenant-scoped Keycloak realms or a multi-realm token-audience check, row-level security in Postgres) — same treatment docs/SECURITY.md already gives the "No KMS in v1" gap: documented upgrade path, not built in, to keep template complexity down.
  3. 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

  1. added
    enhancementNew feature or request
    documentationImprovements or additions to documentation
    effort:SSmall: single file/component, hours not days
    and removed
    enhancementNew feature or request
    on Aug 31, 2026
  2. added a commit that references this issue on Sep 4, 2026
    7870be1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentationeffort:SSmall: single file/component, hours not dayspriority:P1High value, near-term

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions