Adding a tenant identifier to a table is a useful starting point, but it does not prove that tenants are isolated. The application query, export worker and administrative script may use different database roles. Review all of those paths before relying on a shared database to enforce a customer's boundary.
Understand the role that runs the query
PostgreSQL row-level security can restrict which rows a role may read or modify. Its policy documentation also explains important exceptions: superusers and roles with BYPASSRLS bypass the rules, and table owners normally do too. A test executed only as the table owner can therefore give a misleading picture of application behaviour.
Write down the roles used by the web application, workers, migrations and support tools. Keep ordinary application requests away from privileged maintenance credentials. Decide how tenant identity is established from authenticated context, and ensure the client cannot simply choose another tenant by changing a request parameter.
Build an adversarial fixture
Create two synthetic tenants with recognisable records. Test selecting, inserting, updating and deleting through the same role and connection setup used by the application. Attempt to attach a record to the wrong tenant. Include joins, bulk operations and missing tenant context, rather than checking only a single read endpoint.
Exercise the connection pool with alternating tenants. If tenant context is stored on a connection, verify that it cannot survive into another request unexpectedly. Prefer a well-defined transaction boundary and test cleanup after errors. Include a failing transaction in the fixture because the exceptional path often differs from the normal one.
Follow copies out of the database
Exports, caches and search indexes need their own access checks. Row-level security does not automatically protect a file after it leaves the database. Check who can download an export, how long it remains available and what happens when membership changes. A background worker must receive trustworthy tenant context just as the web request does.
Map these paths in a data engineering engagement. If the product includes document search, use the same identity model in its retrieval permission design, while testing each storage layer's enforcement separately.










