Building Production-Ready Multi-Tenant SaaS in Rust with Actix-web
These articles are AI-generated summaries. Please check the original sources for full details.
Building Production-Ready Multi-Tenant SaaS in Rust with Actix-web
Developer Chinedu built SmartFarmAI to manage poultry operations across Nigeria and Tanzania. The platform employs PostgreSQL Row-Level Security (RLS) to prevent data leaks between farms, ensuring enterprise-grade isolation for operations with up to 60,000 birds.
Why This Matters
In multi-tenant architectures, relying solely on application-level logic like manual WHERE clauses creates a high risk of catastrophic data leaks due to human error. By shifting isolation enforcement to the database layer via PostgreSQL RLS, developers create a structural failsafe that ensures data remains private even if application-layer filters are omitted.
For SmartFarmAI, this approach balances the management simplicity of a shared database with the security guarantees of isolated schemas. This technical strategy significantly reduces operational overhead while maintaining the high level of trust required in agricultural business management.
Key Insights
- PostgreSQL Row-Level Security (RLS) enforces data isolation at the database layer, removing the need for manual ‘WHERE org_id = $1’ clauses in application code.
- SmartFarmAI uses composite foreign keys (org_id, farm_id) to make it structurally impossible to associate a batch with a farm from a different organization.
- Actix-web middleware extracts tenant IDs from JWT claims and uses ‘SET LOCAL app.current_tenant_id’ to scope transactions to a specific tenant.
- Using ‘SET LOCAL’ with the third argument set to ‘true’ ensures the tenant context is transaction-specific, preventing connection pool contamination between requests.
- Infrastructure tables like Outbox queues must bypass RLS to allow background workers to poll across all organizations before switching to a per-tenant context for processing.
Working Examples
Schema implementation using composite foreign keys and PostgreSQL RLS policies.
CREATE TABLE batches (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
org_id UUID NOT NULL,
farm_id UUID NOT NULL,
CONSTRAINT batch_farm_fk FOREIGN KEY (org_id, farm_id) REFERENCES farms (org_id, id) ON DELETE CASCADE
);
ALTER TABLE farms ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_isolation ON farms
USING (org_id = current_setting('app.current_tenant_id')::uuid);
Actix-web middleware logic to set the PostgreSQL transaction-local tenant context.
pub async fn set_rls_context(
pool: &PgPool,
org_id: &TenantId,
) -> Result<sqlx::Transaction<'_, sqlx::Postgres>, Error> {
let mut tx = pool.begin().await.map_err(|e| {
actix_web::error::ErrorInternalServerError(format!("DB error: {}", e))
})?;
sqlx::query("SELECT set_config('app.current_tenant_id', $1, true)")
.bind(org_id.to_string())
.execute(&mut *tx)
.await?;
Ok(tx)
}
Practical Applications
- SmartFarmAI isolates egg production and mortality logs for distinct farms using SQLx and Actix-web. Pitfall: Using session-scoped session variables instead of transaction-local ones can leak data to the next user using that pooled connection.
- Background workers process event queues by polling a global outbox table. Pitfall: Enabling RLS on infrastructure tables like work queues causes workers to return zero results because they lack a default tenant context.
- Database migrations are performed by superusers to bypass RLS restrictions. Pitfall: Assuming RLS is active during migrations can lead to logic errors in scripts that require global data access.
References:
Continue reading
Next article
Automating Terraform Security Scans with Checkov and Azure Pipelines
Related Content
Engineering a Real psql Terminal: PTY, Reverse WebSockets, and Redis Streams
Learn how to build a PTY-backed PostgreSQL console using Redis Streams to decouple I/O and reverse WebSockets to bypass NAT constraints for real terminal semantics.
Building a Multi-Tenant Observability Platform with SigNoz + OneUptime
Modern SaaS teams require robust observability while maintaining tenant isolation, achieving this platform reduced operational overhead and aligned with SOC 2/ISO 27001 compliance.
Implementing OAuth 2.0 Device Flow for Input-Constrained Environments
Streamline authentication for CLIs and IoT devices using the OAuth 2.0 device authorization grant to eliminate complex password entry on limited interfaces.