Supabase.PostgREST.RLS (supabase_postgrest v1.2.2)
View SourceHelpers for working with PostgreSQL Row Level Security (RLS) policies in Ecto.
This module provides utilities to set session context for RLS policies when using
the Ecto schemas generated by mix supabase.gen.schema.
Usage
Wrap operations in a transaction and set session variables that are automatically cleaned up when the transaction completes:
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app
import Supabase.PostgREST.RLS
def with_user_context(user_id, fun) do
transaction(fn ->
set_rls_context(__MODULE__, "request.jwt.claims.sub", user_id)
fun.()
end)
end
end
# Usage
MyApp.Repo.with_user_context(user_id, fn ->
MyApp.Repo.all(MyApp.Accounts.User)
end)Common Supabase RLS Patterns
Supabase RLS policies commonly use these session variables:
request.jwt.claims.sub- User ID from JWTrequest.jwt.claims.role- User role from JWTrequest.jwt.claims.email- User email from JWT
Example policy in your database:
CREATE POLICY "Users can view their own data"
ON users FOR SELECT
USING (id = current_setting('request.jwt.claims.sub')::uuid);Testing with RLS
When testing, you may want to bypass RLS policies. You can disable RLS for specific tables:
Ecto.Adapters.SQL.query!(MyApp.Repo, "ALTER TABLE users DISABLE ROW LEVEL SECURITY")
Summary
Functions
Gets the current value of an RLS context variable.
Sets multiple RLS context variables at once in a single database query.
Sets a PostgreSQL session configuration variable for the current transaction.
Functions
Gets the current value of an RLS context variable.
Returns nil if the variable is not set.
Examples
current_user_id = get_rls_context(MyApp.Repo, "request.jwt.claims.sub")
Sets multiple RLS context variables at once in a single database query.
This is more efficient than calling set_rls_context/3 multiple times when you need
to set several session variables.
Parameters
repo- The Ecto repository moduleclaims- A map of configuration keys to values
Examples
# Set multiple JWT claims at once
Repo.transaction(fn ->
set_rls_claims(repo, %{
"request.jwt.claims.sub" => user.id,
"request.jwt.claims.role" => "authenticated",
"request.jwt.claims.email" => user.email
})
Repo.all(User)
end)
Sets a PostgreSQL session configuration variable for the current transaction.
This function executes set_config/3 with the is_local parameter set to true,
ensuring the configuration is transaction-scoped and automatically cleared when
the transaction completes.
Parameters
repo- The Ecto repository modulekey- The configuration parameter name (e.g., "request.jwt.claims.sub")value- The value to set (will be converted to string)
Examples
# Setting user ID for RLS policies
Repo.transaction(fn ->
set_rls_context(repo, "request.jwt.claims.sub", user.id)
Repo.all(User)
end)
# Setting user role
Repo.transaction(fn ->
set_rls_context(repo, "request.jwt.claims.role", "authenticated")
Repo.all(User)
end)
# Setting user email
Repo.transaction(fn ->
set_rls_context(repo, "request.jwt.claims.email", user.email)
Repo.all(User)
end)
# With custom variable name for multi-tenancy
Repo.transaction(fn ->
set_rls_context(repo, "app.current_tenant", tenant_id)
Repo.all(from u in User, where: ...)
end)Security Considerations
- Always validate and sanitize the
valueparameter before passing it to this function - Never pass user input directly without validation
- Consider using prepared statements for complex values