TenantAtlas/specs/093-scope-001-workspace-id-isolation/data-model.md
2026-02-14 22:32:38 +01:00

2.6 KiB

Data Model — 093 SCOPE-001 Workspace ID Isolation

Core Entities

Workspace

  • workspaces:
    • id (bigint)
    • name, slug, timestamps

Tenant

  • tenants:
    • id (bigint)
    • workspace_id (bigint, intended non-null logically; currently nullable in schema)

Ownership rule: A tenant belongs to exactly one workspace; this mapping is the source of truth for deriving workspace bindings.

Tenant-owned Tables (must become workspace-bound)

For each table below:

  • Add workspace_id (bigint FK to workspaces.id)
  • Enforce workspace_id derived from tenant (DB-level composite FK on Postgres/MySQL)
  • Keep tenant_id immutable (application enforcement)

policies

  • Existing: tenant_id, external_id, policy_type, etc.
  • Add: workspace_id

policy_versions

  • Existing: tenant_id, policy_id, snapshot, etc.
  • Add: workspace_id

backup_sets

  • Existing: tenant_id, status/count, etc.
  • Add: workspace_id

backup_items

  • Existing: tenant_id, backup_set_id, payload, etc.
  • Add: workspace_id

restore_runs

  • Existing: tenant_id, backup_set_id, status, preview/results, etc.
  • Add: workspace_id

backup_schedules

  • Existing: tenant_id, enabled/frequency/schedule fields
  • Add: workspace_id

inventory_items

  • Existing: tenant_id, policy identifiers, meta_jsonb, last_seen fields
  • Add: workspace_id
  • Existing: tenant_id, source/target relationship identifiers
  • Add: workspace_id

entra_groups

  • Existing: tenant_id, entra_id, display fields
  • Add: workspace_id

findings

  • Existing: tenant_id, fingerprint, status/severity, run references
  • Add: workspace_id

entra_role_definitions

  • Existing: tenant_id, entra_id, display fields
  • Add: workspace_id

tenant_permissions

  • Existing: tenant_id, permission_key, status
  • Add: workspace_id

Audit Logs (scope invariants)

audit_logs

  • Existing: tenant_id nullable, workspace_id nullable, action/resource fields

Invariant:

  • Tenant-scoped audit entry: tenant_id != null implies workspace_id != null.
  • Workspace-only audit entry: workspace_id != null and tenant_id == null is allowed.
  • Platform-only audit entry: both null is allowed.

Relationship + Constraint Strategy

Tenant-owned enforcement (Postgres/MySQL)

  • Composite FK on each tenant-owned table:
    • (tenant_id, workspace_id) → tenants(id, workspace_id)
  • Standard FK on workspace_id → workspaces.id

SQLite

  • Foreign key / composite constraint enforcement is limited.
  • Testing relies on application enforcement + basic NOT NULL where feasible.