Skip to content

Multi-tenant readiness — architecture spike

Status: spike / design note (DOCS-191). Bedrock Docs is and remains single-customer (Cirius Group). This documents the path to multi-tenant so a second tenant would not be a rewrite — it is the one parity gap vs hosted platforms (GitBook/Confluence) we deliberately deferred. No multi-tenant work is planned; this is the map if it's ever needed.

Where single-tenant is baked in today

AreaCurrent single-tenant assumptionMulti-tenant change
ContentOne bedrock-docs repo = one doc setPer-tenant content namespace (repo-per-tenant, or top-level tenants/<id>/ trees)
HostingOne Cloudflare Pages project + one custom domainPages project (or path/subdomain) per tenant; deploy fans out per tenant
AccessOne CF Access app, one allow policy (@ciriusgroup.com)One CF Access app + policy per tenant; tenant↔IdP-group mapping
AI search/api/docs-ask fetches the single bedrock-docs corpusCorpus keyed by tenant; request carries a tenant id; index per tenant
BrandingHardcoded "Cirius" / "Bedrock Cybersecurity" in config + themeTheme + masthead from a per-tenant config (name, colors, logo)
GeneratorsTopology/API-refs point at Cirius's azure-infra / SOC / GRCPer-tenant source bindings (which IaC repo, which API origins)
TrackerOne DOCS projectProject per tenant, or tenant-tagged stories

Smallest viable multi-tenant shape

  1. Config-driven tenancy — a tenants.yml (id, domain, IdP group, source bindings, brand) instead of hardcoded values; the build + generators read it.
  2. Build matrix — CI builds + deploys one Pages target per tenant from its content namespace; srcExclude keeps tenants isolated.
  3. AI search by tenant/api/docs-ask takes a tenant arg, loads that tenant's corpus (separate GitHub repo/token per tenant), and the system prompt is tenant-scoped. Reuse the existing keyless OpenAI path.
  4. Access per tenant — one CF Access application + allow policy per tenant domain; no shared session across tenants.
  5. Data isolation — no cross-tenant content, corpus, or analytics; per-tenant alert routing.

What would NOT change

The core engine is already tenant-agnostic: docs-as-code, the generator pattern (topology/API-refs/coverage/changelog from source), the CI gates (smoke, freshness, security scan, SBOM), and the keyless AI architecture. Multi-tenancy is a configuration + fan-out layer on top, not a re-architecture — which is the point of writing this down now.

Recommendation

Do nothing now. Single-customer is the right scope. If a second tenant ever appears, start at step 1 (extract hardcoded Cirius values into tenants.yml) — that one refactor unlocks the rest incrementally.

Internal use only — Cirius Group