Skip to main content

dovecote_sqlx_postgres/
rls.rs

1//! Optional `PostgreSQL` row-level-security profile for tenant isolation.
2
3use dovecote::TenantId;
4use sqlx::{Postgres, Transaction, query};
5
6/// Installs the opt-in RLS policies for a tenant-aware schema.
7///
8/// RLS is deliberately separate from the ordinary migration. Applications
9/// that enable it must use a role with `BYPASSRLS` for [`crate::AdminDovecote`]
10/// and call [`bind_tenant`] at the start of every scoped transaction.
11pub const RLS_PROFILE_SQL: &str = include_str!("../migrations/0002_dovecote_tenant_rls.sql");
12
13/// Binds a validated tenant to the current transaction for the RLS profile.
14///
15/// The setting is transaction-local and cannot outlive the supplied `SQLx`
16/// transaction. It does not replace the adapter's tenant predicates.
17///
18/// # Errors
19/// Returns the database error if binding transaction-local tenant context fails.
20/// The caller must roll back the transaction before retrying.
21pub async fn bind_tenant<'c>(
22    transaction: &mut Transaction<'c, Postgres>,
23    tenant_id: &TenantId,
24) -> Result<(), sqlx::Error> {
25    query("SELECT set_config('dovecote.tenant_id', $1, true)")
26        .bind(tenant_id.as_str())
27        .execute(&mut **transaction)
28        .await
29        .map(|_| ())
30}