Row level security is currently only supported for Postgres databases. If you need RLS support for other database dialects, please contact us to discuss your use case.
How it works
When a user in your Basedash workspace runs a query, Basedash automatically sets a session variable calledbasedash.groups that contains all the groups the user belongs to (comma-separated). You can then create policies on your Postgres database that reference this session variable to restrict which rows are returned.
We will always set up the
basedash.groups session variable for Postgres databases. It will be an empty string if the user making the query doesn’t belong to any groups.- You assign users to groups in Basedash (e.g., “Engineering”, “Sales”, “Support”)
- You create row-level security policies on your database tables
- When a user runs a query, Basedash sets the
basedash.groupssession variable - Your database policies automatically filter the results based on the user’s groups
Setting up RLS in Basedash
Whenever a query is executed against a Postgres database, Basedash automatically sets thebasedash.groups session variable with the user’s group memberships.
To view the available groups that will be passed in the session variable:
- Open the command menu (Cmd+K or Ctrl+K)
- Navigate to your data source settings
- Select “Row Level Security”
- View the available group names that you can reference in your policies
Creating policies on your database
To control data access, you need to create RLS policies directly on your Postgres database. These policies define which rows users can access based on their group membership.Basic example
Here’s a simple example for anorders table where you want to restrict access based on a department column:
- Normal access when
basedash.groupsis not set (so your existing applications continue to work) - Filtered access when the session variable is set (Basedash queries)
Multiple group membership
The policy pattern uses comma-separated values, so it automatically handles users who belong to multiple groups. For example, if a user belongs to both “Engineering” and “Support” groups, thebasedash.groups variable will be set to "Engineering,Support", and the policy will match rows where the department is either “Engineering” or “Support”.
Permissive policies for external systems
If you want to allow all operations from external systems (those not using Basedash), you can create permissive policies:Basedash Warehouse
If you’re using Basedash Warehouse (our managed Postgres warehouse for Fivetran connections), you can create policies using the warehouse credentials. To access your Basedash Warehouse credentials:- Open the command menu (Cmd+K or Ctrl+K)
- Type “Basedash Warehouse”
- Select “View credentials”
- Use these credentials to connect to your warehouse and create policies
psql, pgAdmin, or TablePlus) and run the CREATE POLICY statements directly.
Forcing row level security
When using Basedash Warehouse, you’ll need to force row level security on your tables to ensure that RLS policies are properly applied:FORCE ROW LEVEL SECURITY command ensures that RLS policies are enforced even for the table owner, so your security policies will be properly applied to all queries running through Basedash.
RLS with chat
Row level security automatically applies to all queries in Basedash, including those generated through the AI chat interface. When users ask questions about their data in chat, the AI-generated SQL queries will respect your RLS policies, ensuring users only see data they’re authorized to access.
RLS with reports
When scheduled reports are executed, thebasedash.groups session variable is set using the groups associated with the user who created the report. RLS policies are applied based on the report creator’s group memberships.
To maintain security, only the report creator can modify the report’s prompt/instructions. This ensures that users cannot modify reports created by someone with broader access to query data they wouldn’t normally have access to. Other users with access to the report can view it and receive scheduled deliveries, but cannot modify its configuration.
RLS with slack integration
When queries are executed through the Basedash Slackbot, we attempt to match the Slack user to their Basedash user account.- If a match is found: The
basedash.groupssession variable is set with the user’s group memberships, and RLS policies are applied based on their access - If no match is found: The
basedash.groupssession variable will be set to an empty string, and tables with RLS policies that require group membership will return no rows
Important considerations
Database support
Row level security is currently supported for Postgres databases only. Support for other database systems may be added in the future. If you need RLS support for other database dialects, please contact us and let us know about your use case.Admin access outside Basedash
Admin users who have access to your database credentials (including Basedash Warehouse credentials) can connect to the database directly and query data without RLS restrictions. The policies only apply when thebasedash.groups session variable is set, which only happens during Basedash queries.
If you need to ensure that all access to your database goes through RLS policies, you should use dedicated database users for external access and create policies that apply to those users as well.
Compatibility with existing applications
The policy pattern shown above uses a NULL check (current_setting('basedash.groups', true) IS NULL) to ensure that your existing applications and services that query the database directly will continue to work normally without any restrictions. Only queries that come through Basedash (which set the session variable) will have the RLS policies applied.
Performance
Row level security policies are evaluated for every query, so complex policies can impact query performance. Keep policies simple and ensure that any columns referenced in the policies are properly indexed.Best practices
- Start simple - Begin with policies on a single table and test thoroughly before expanding to your entire database
-
Use consistent column names - If you’re using RLS across multiple tables, use consistent column names (like
departmentorteam_id) to make policy management easier - Test with different user groups - Create test users in different groups and verify that they can only access the appropriate data
- Document your policies - Keep track of which tables have RLS enabled and what the policies do, especially as your database schema grows
- Monitor query performance - Watch for any performance degradation after enabling RLS, and optimize policies or add indexes as needed