Previously: In Spinning Up Temporary Testing Databases for Postgres, we created a pets module with a schema and table. Now let's add RLS policies and test them.
Row-Level Security (RLS) is Postgres's most powerful security feature, but it's also the hardest to test. You need to simulate different users, different roles, and verify that policies actually enforce the access control you expect.
In this lesson, you'll add RLS policies to your pets module and test them with pgsql-test by switching between user contexts.
Prerequisites
See Prerequisites. Requires: Complete Spinning Up Temporary Testing Databases for Postgres.
Why Test RLS?
RLS secures multi-tenant applications by ensuring users only access their own data. Without testing, you risk data leaks between users or overly restrictive policies that block legitimate access.
pgsql-test makes RLS testing simple with the setContext() method—switch between users and roles to verify your security policies work correctly.
Adding RLS to Pets
Add owner_id column and RLS policies:
Edit deploy/schemas/pets/tables/pets/add_rls.sql:
Understanding Test Database Clients
pgsql-test provides two database clients:
pg- Postgres superuser for setup/teardown operationsdb- User client for testing with authentication roles
Use pg to insert test data as superuser. Use db with setContext() to test RLS policies.
Testing RLS Policies
Create __tests__/rls.test.ts:
The setContext() method on db sets the role and user context for the current transaction. All subsequent queries run with that authentication context.
Using Watch Mode for Rapid Testing
For faster feedback, use watch mode. First, initialize git if you haven't already:
Then run tests in watch mode:
Watch mode re-runs tests automatically when you save changes, giving you instant feedback as you develop.
Note:
pgpm initdefaults to Jest, but pgsql-test is test-framework agnostic—you can use it with Mocha, Vitest, or any other test runner.
Jest watch mode commands:
- Press
pto filter by filename pattern - Press
tto filter by test name pattern - Press
ato run all tests - Press
qto quit watch mode
Testing Authenticated User Access
Add tests for authenticated users managing their own pets:
Run the tests:
Key Takeaways
pgclient - Use for superuser operations (setup/teardown)dbclient - Use for testing with authentication roles- setContext() sets authentication context for the current transaction
- Role switching is automatic and scoped to the transaction
- Use
pgpm addto add RLS policies as proper database changes - owner_id with jwt.claims.user_id enables user-based access control
- Test isolation ensures RLS context doesn't bleed between tests
What's Next
You've added RLS policies to your pets module and tested basic user access scenarios. In the next lesson, we'll explore advanced multi-user testing scenarios, simulating malicious attempts and testing complex user interactions.
