CtrlK
BlogDocsLog inGet started
Tessl Logo

testland/multi-engine-row-level-security-reference

Pure-reference catalog of row/tenant isolation mechanisms across four database engines: MySQL and MariaDB (no native RLS - views with SQL SECURITY INVOKER plus app-layer enforcement), CockroachDB (native RLS via ALTER TABLE ENABLE ROW LEVEL SECURITY and CREATE POLICY, matching Postgres semantics), Vitess (keyspace sharding + vindexes route tenant writes to dedicated shards without a policy layer), and SQL Server (CREATE SECURITY POLICY with inline table-valued function filter/block predicates). Covers the isolation mechanism, tenant-context pattern, bypass risks, and test patterns for each engine. Use when designing or auditing tenant isolation on MySQL, MariaDB, CockroachDB, Vitess, or SQL Server.

79

Quality

99%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Overview
Quality
Evals
Security
Files

vitess.mdreferences/

Vitess - keyspace sharding + vindexes

Vitess has no row-level security policy layer. Tenant isolation happens at the routing tier: a tenant's rows sit on a dedicated shard (or shard range), and vindexes route queries so cross-tenant access never reaches the wrong MySQL shard. A keyspace is a logical database; when sharded it maps to multiple MySQL databases across shards, and a vindex maps a column value to a keyspace ID.

Vindexes for tenant isolation

A primary vindex on tenant_id maps each tenant to a keyspace-ID range; Vitess routes every query carrying a tenant_id condition to the owning shard(s).

Vindex typeUse for tenant isolation
Functional hash (xxhash, hash)Maps tenant_id to a keyspace ID deterministically; no lookup table needed
Consistent lookup (unique)Stores tenant_id -> keyspace_id in a MySQL lookup table; supports non-hash distributions
Non-unique lookupSecondary routing on tenant-level subtables

Example VSchema fragment:

{
  "sharded": true,
  "vindexes": { "tenant_hash": { "type": "xxhash" } },
  "tables": {
    "documents": {
      "columnVindexes": [ { "column": "tenant_id", "name": "tenant_hash" } ]
    }
  }
}

Any query without a tenant_id condition scatters to all shards. Isolation therefore depends on every query carrying a tenant_id predicate - an application-layer responsibility.

Bypass risks

RiskWhy
Query without tenant_id predicateScatters to all shards; returns rows from every tenant
Cross-shard transactions2PC for cross-shard writes; isolation bugs can occur in rollback paths
Row updates that change tenant_idVitess cannot move rows between shards on update; tenant_id must be immutable
Direct MySQL access (bypassing VTGate)Shard-level MySQL has no vindex awareness; direct access bypasses routing

Sources: Vitess Vindexes vitess.io/docs/21.0/reference/features/vindexes/; Vitess Keyspaces vitess.io/docs/21.0/concepts/keyspace/.

SKILL.md

tile.json