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
99%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
MySQL 8.x and MariaDB have no native row-level security statement.
Isolation combines a view defined SQL SECURITY INVOKER with an
application role that holds no direct grants on the base table.
The CREATE VIEW default is SQL SECURITY DEFINER: the view runs with
the creator's privileges, so any user with SELECT on the view reads
every row the creator can read, including other tenants'. With
SQL SECURITY INVOKER the view runs with the caller's privileges, so the
view's WHERE clause becomes the tenant boundary. The only clauses
material to isolation are SQL SECURITY { DEFINER | INVOKER } and
WITH [CASCADED | LOCAL] CHECK OPTION; the MySQL 8.4 CREATE VIEW
reference has the full grammar.
CREATE VIEW tenant_docs AS
SELECT *
FROM documents
WHERE tenant_id = /* app sets via session var or stored function */ ...
SQL SECURITY INVOKER
WITH CASCADED CHECK OPTION;WITH CHECK OPTION rejects inserts or updates that would create rows
outside the view's WHERE clause.
Views do not block TRUNCATE, constraint checks, or direct table access
when the role holds table-level grants. The application must:
SELECT/INSERT/UPDATE/DELETE
on the base table (only on the view).WHERE clause as the sole row gate and re-validate it
in every schema migration.MariaDB shares this model. Its DEFINER clause also accepts
role | CURRENT_ROLE, which makes a schema-per-tenant view owned by a
per-tenant role viable at low tenant counts. Atomic DDL for CREATE VIEW
landed in MariaDB 10.6.1.
| Risk | Why |
|---|---|
SQL SECURITY DEFINER (default) | View runs as creator; tenant filter is advisory only |
| Direct base-table grants on the app role | App can bypass the view entirely |
TRUNCATE | Never filtered by views; requires separate role restriction |
| Schema changes to the view | Migration that widens WHERE clause removes isolation |
Sources: MySQL 8.4 CREATE VIEW
dev.mysql.com/doc/refman/8.4/en/create-view.html;
MariaDB CREATE VIEW
mariadb.com/kb/en/create-view/.