Skip to main content

Database Multi-Tenancy & Row-Level Security (RLS)

Okustera enforces defense-in-depth multi-tenant isolation across all relational metadata tables (omc-postgres) using a Dual-Layer Database Multi-Tenancy Architecture.

Rather than relying solely on manual .where(Model.project_id == project_id) clauses inside individual API controllers, every database session and transaction is automatically scoped to the authenticated tenant at both the SQLAlchemy ORM Session Layer and the PostgreSQL Storage Engine Kernel Layer.


Dual-Layer Isolation Architecture​

Layer 1: SQLAlchemy Session-Scoped ORM Interceptor​

Every asynchronous database session (AsyncSession) registers three lifecycle interceptors:

  • Read & Mutation Filtering (do_orm_execute): Automatically attaches with_loader_criteria to all SELECT queries and explicit .where(...) clauses to all UPDATE and DELETE statements for tenant-scoped models. Even if an application query omits a WHERE clause, cross-tenant rows are never returned or modified.
  • Write Ownership Guard (before_flush): Inspects every newly added (session.new) and modified (session.dirty) ORM entity before flush. If a non-admin tenant attempts to insert or mutate a record belonging to another project_id, the flush is immediately aborted with a PermissionError (RLS Violation).

Layer 2: PostgreSQL Kernel Row-Level Security (FORCE ROW LEVEL SECURITY)​

At the start of every database transaction (after_begin), the backend binds transaction-local session variables inside PostgreSQL using set_config(..., true):

SELECT
set_config('app.current_tenant_id', '<TENANT_PROJECT_ID>', true),
set_config('app.is_admin', 'false', true),
set_config('app.bypass_rls', 'false', true);

All tenant tables in omc-postgres enforce both ENABLE ROW LEVEL SECURITY and FORCE ROW LEVEL SECURITY, ensuring that even table owners and raw SQL queries (SELECT, INSERT, UPDATE, DELETE) are restricted by the PostgreSQL kernel:

ALTER TABLE dns_zones ENABLE ROW LEVEL SECURITY;
ALTER TABLE dns_zones FORCE ROW LEVEL SECURITY;

CREATE POLICY omc_rls_dns_zones_isolation ON dns_zones
USING (
current_setting('app.is_admin', true) = 'true'
OR current_setting('app.bypass_rls', true) = 'true'
OR project_id = current_setting('app.current_tenant_id', true)
)
WITH CHECK (
current_setting('app.is_admin', true) = 'true'
OR current_setting('app.bypass_rls', true) = 'true'
OR project_id = current_setting('app.current_tenant_id', true)
);

3-Tier Database Model Taxonomy (37/37 Models)​

100% of relational models in the Okustera backend are explicitly classified into one of three security tiers and continuously verified in CI (audit_rls_coverage.py):

Security TierMixin ClassIsolation PredicateCovered Platform Tables (37 Total)
Tier A: Strict Single-Tenant (14 Models)TenantScopedMixinproject_id = current_tenant_id (or tenant_id = current_tenant_id)dns_zones, dns_recordsets, vpcs, vpc_subnets, vpc_route_tables, vpc_endpoints, ai_sandbox_instances, ai_colibri_batch_jobs, dbaas_upgrade_jobs, brownfield_migration_jobs, functions, gateway_routes, traffic_policies, certificates
Tier B: Composite / Shared (13 Models)CompositeTenantMixinMulti-column or public/shared visibility (requester_project_id OR peer_project_id, scope = 'system' OR project_id = current_tenant_id, is_public OR is_system OR project_id)vpc_peerings, vpc_route_table_associations, artifactory_repositories, artifactory_artifacts, ai_sandbox_skills, ai_oci_artifacts, ai_rayservice_deployments, ai_foundry_models, layers, layer_versions, layer_permissions, service_instances, tenant_services
Tier C: Global Catalog & Identity (10 Models)GlobalCatalogMixinPlatform-wide read catalog or RBAC-governed identity/audit ledgerai_sandbox_toolchains, ai_sandbox_security_policies, ai_gpu_profiles, dbaas_engine_versions, brownfield_target_catalog, services, tenants, users, user_sessions, audit_logs

Global Conflict Detection vs. Tenant Isolation​

Certain cloud resources require global uniqueness or shared system catalog visibility across the entire platform while keeping tenant resource metadata strictly private to the owning tenant:

  1. Authoritative DNS Zones (dns_zones):
    • Under RFC 1035, two tenants cannot claim authoritative ownership of the same public domain (e.g., example.com.) on the same nameserver cluster.
    • During POST /api/v1/networking/dns/zones, the backend performs a targeted existence check using .execution_options(bypass_tenant_filter=True) and returns HTTP 409 Conflict if the domain is already registered—without exposing the owning tenant's project ID, email, or recordsets.
  2. Cross-Tenant VPC Peering (vpc_peerings):
    • When Tenant A initiates a VPC Peering request (POST /api/v1/networking/vpcs/peerings) targeting Tenant B's VPC ID, the Tier B composite policy (requester_project_id = current_tenant_id OR peer_project_id = current_tenant_id) allows both participating tenants to view the peering connection while hiding it from all other tenants (Tenant C receives 0 rows).
  3. Artifact Registry & Serverless Layers (artifactory_repositories, layers):
    • Public and system-scoped repositories/layers (is_public = true or scope = 'system') are readable across tenants for shared base images and SDK dependencies, while WITH CHECK (project_id = current_setting('app.current_tenant_id', true)) guarantees that only the owning tenant can modify or delete them.
  4. AI Model Foundry, KubeRay Deployments, OCI ModelKits & Skill Registry (ai_foundry_models, ai_rayservice_deployments, ai_oci_artifacts, ai_sandbox_skills):
    • System-curated foundation models, baseline Multi-LoRA serving deployments, and pre-audited system skills are stored with scope = 'system' and project_id = NULL, making them readable across all authenticated tenants while strictly immutable by tenants (WITH CHECK (scope = 'tenant' AND project_id = current_setting('app.current_tenant_id', true))).
    • All AI endpoints enforce fail-closed tenant resolution (resolve_ai_project_id) with zero RLS bypass (bypass_rls_context is prohibited in portal AI handlers) and zero fallback to default/admin tenants.