rls
graphql
Row-Level Security (RLS)
Excalibase GraphQL passes request headers directly into the PostgreSQL session, so your existing RLS policies work automatically.
How it works
Pass X-User-Id in your request header. Excalibase sets it as a PostgreSQL session variable before executing any query:
SET request.user_id = 'alice';
Your RLS policies can then reference this variable to filter rows.
Example
1. Create a table with RLS
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id TEXT NOT NULL,
amount DECIMAL,
status VARCHAR(20)
);
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
2. Create an RLS policy
CREATE POLICY user_isolation ON orders
FOR ALL
USING (user_id = current_setting('request.user_id', true));
3. Query with user context
POST /graphql
Content-Type: application/json
X-User-Id: alice
{
"query": "{ orders { order_id amount status } }"
}
Alice only sees her own rows — the policy is enforced at the database level.
Role-based access
-- Different policies for different roles
CREATE POLICY admin_all ON orders
FOR ALL TO admin_role
USING (true);
CREATE POLICY user_own ON orders
FOR ALL TO app_user
USING (user_id = current_setting('request.user_id', true));
Pass X-User-Role header to switch roles.
Supported headers
| Header | PostgreSQL variable |
|---|---|
X-User-Id | request.user_id |
X-User-Role | request.user_role |
X-Tenant-Id | request.tenant_id |
These are set as session-scoped variables — they are isolated per connection and reset between requests.