Thanks to visit codestin.com
Credit goes to lib.rs

#multi-tenant #actix-web #framework #saas #security-framework #security

corteq

Enterprise-grade multi-tenant SaaS framework for Rust with security-first design

1 unstable release

0.1.0 Nov 21, 2025

#639 in Authentication

MIT license

64KB
905 lines

Corteq Framework

Enterprise-Grade Multi-Tenant SaaS Framework for Rust

License: MIT Rust Version Tests

Corteq is a security-first, production-ready framework for building multi-tenant SaaS applications in Rust. Built on Actix Web, it provides comprehensive tenant isolation, authentication, encryption, and compliance features out of the box.

๐Ÿš€ Features

๐Ÿ”’ Security First

  • Row-Level Security (RLS): Automatic tenant data isolation at the PostgreSQL level
  • AES-256-GCM Encryption: Data at rest encryption with tenant-specific keys
  • JWT Authentication: Bearer token & HTTP cookie support
  • Defense in Depth: Multiple layers of security (middleware + database)

๐Ÿข Multi-Tenant Architecture

  • Zero Cross-Tenant Leakage: Database-level isolation with compile-time safety
  • Per-Tenant Encryption: Each tenant has unique encryption keys
  • Tenant Context: Automatic tenant identification from JWT claims
  • Efficient Caching: In-memory tenant data caching

๐Ÿ›ก๏ธ Compliance Ready

  • GDPR: Data isolation, encryption, audit trails
  • HIPAA: PHI protection with encryption at rest
  • SOC 2: Security controls and audit logging patterns

โšก Production Ready

  • 64+ Tests: Comprehensive test coverage including security tests
  • Type Safety: Compile-time guarantees prevent common mistakes
  • Performance: Efficient connection pooling and caching
  • Observability: Built-in tracing and logging support

๐Ÿ“ฆ Quick Start

[dependencies]
corteq = "0.1"
actix-web = "4.9"
tokio = { version = "1", features = ["full"] }
use actix_web::{web, App, HttpServer};
use corteq::CorteqApp;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
    let app_config = CorteqApp::builder()
        .with_database("postgres://user:pass@localhost/db")
        .with_jwt_secret("your-secret-key-min-32-chars!!")
        .build()
        .await?;

    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(app_config.clone()))
            .service(
                web::scope("/api")
                    .wrap(corteq::TenantContextMiddleware)
                    .route("/data", web::get().to(get_tenant_data))
            )
    })
    .bind("0.0.0.0:8080")?
    .run()
    .await
}

๐Ÿ—๏ธ Architecture

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                     HTTP Request                        โ”‚
โ”‚         Authorization: Bearer <jwt_token>               โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚           TenantContextMiddleware                        โ”‚
โ”‚  โ€ข Extracts JWT from Bearer token or Cookie             โ”‚
โ”‚  โ€ข Validates signature and expiration                   โ”‚
โ”‚  โ€ข Loads tenant context from cache/database             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  Handler Function                        โ”‚
โ”‚              (tenant: TenantExtractor)                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                  TenantDatabase                          โ”‚
โ”‚  โ€ข Begins transaction                                    โ”‚
โ”‚  โ€ข Sets app.current_tenant_id session variable          โ”‚
โ”‚  โ€ข RLS policies automatically filter queries            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
                         โ”‚
                         โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚            PostgreSQL with RLS Enabled                   โ”‚
โ”‚  โ€ข Row-Level Security enforces tenant isolation         โ”‚
โ”‚  โ€ข Only returns rows matching current_tenant_id         โ”‚
โ”‚  โ€ข Blocks INSERT/UPDATE/DELETE for other tenants        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ” Security Features

Tenant Isolation (RLS)

// Automatically filtered by tenant_id
let mut db = TenantDatabase::begin(&pool, &tenant_ctx).await?;
let docs = sqlx::query!("SELECT * FROM documents")
    .fetch_all(db.connection())
    .await?;
// โœ… Only returns documents for current tenant

JWT Authentication

// Bearer Token
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

// HTTP Cookie (automatically handled)
Cookie: token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Data Encryption

let encryption = EncryptionService::new();

// Encrypt with tenant-specific key
let encrypted = encryption.encrypt(plaintext, &tenant_ctx)?;
let bytes = encrypted.to_bytes(); // Store in database

// Decrypt
let decrypted = encryption.decrypt(&encrypted, &tenant_ctx)?;

๐Ÿ“ Project Structure

.
corteq/                    # Framework library crate
โ”œโ”€โ”€ src/
โ”‚   โ”œโ”€โ”€ lib.rs            # Main library exports
โ”‚   โ”œโ”€โ”€ auth.rs           # JWT authentication
โ”‚   โ”œโ”€โ”€ cache.rs          # Tenant caching layer
โ”‚   โ”œโ”€โ”€ database/         # RLS database wrapper
โ”‚   โ”œโ”€โ”€ domain.rs         # Tenant, TenantContext models
โ”‚   โ”œโ”€โ”€ encryption.rs     # AES-256-GCM encryption
โ”‚   โ”œโ”€โ”€ error.rs          # Framework error types
โ”‚   โ”œโ”€โ”€ middleware.rs     # Tenant context middleware
โ”‚   โ””โ”€โ”€ repository/       # Tenant repository
โ””โ”€โ”€ tests/                # Integration & security tests

๐Ÿ“š Documentation

๐Ÿงช Running Tests

# All tests
cargo test

# Specific test suite
cargo test --test test_encryption
cargo test --test test_security_critical
cargo test --test test_rls_isolation

# With output
cargo test -- --nocapture

# Integration tests only
cargo test --test '*'

๐Ÿ”จ Development Setup

# 1. Clone repository
git clone https://github.com/Trendium-Labs/corteq
cd corteq

# 2. Start PostgreSQL
docker-compose up -d postgres

# 3. Run migrations (automatic on first run)
# Migrations run automatically when CorteqApp::builder().build() is called

# 4. Run demo app
cargo run --bin server

# 5. Test the API
curl http://localhost:3000/health

# Generate demo token
curl -X POST http://localhost:3000/auth/demo-token \
  -H "Content-Type: application/json" \
  -d '{"tenant_id": "11111111-1111-1111-1111-111111111111"}'

# Use token
curl -H "Authorization: Bearer <token>" \
  http://localhost:3000/api/me

๐ŸŽฏ Use Cases

Perfect for building:

  • ๐Ÿข B2B SaaS platforms
  • ๐Ÿ’ผ Enterprise applications
  • ๐Ÿฅ Healthcare systems (HIPAA compliant)
  • ๐Ÿ’ฐ Financial services (SOC 2 ready)
  • ๐Ÿ“Š Analytics platforms
  • ๐ŸŽ“ EdTech applications

๐Ÿšฆ Development Status

โœ… Completed Phases (1-5)

Phase 1: Foundation

  • Cargo workspace setup (corteq + demo-app)
  • Core dependencies configured
  • Module structure created
  • PostgreSQL Docker Compose setup
  • Test infrastructure configured
  • Switched to Actix Web

Phase 2: Authentication & Middleware

  • JWT token encoding/decoding with tenant claims
  • Bearer token authentication
  • HTTP cookie authentication
  • Tenant context middleware
  • Tenant caching layer (in-memory)
  • Tenant repository for database access
  • Demo app with protected routes

Phase 3: Row-Level Security

  • PostgreSQL RLS migrations
  • TenantDatabase wrapper with automatic context setting
  • Comprehensive RLS isolation tests (9 tests)
  • Non-superuser role for proper RLS testing
  • Cross-tenant access blocking verified

Phase 4: Security Testing

  • SQL injection prevention tests
  • Malformed UUID handling tests
  • JWT token manipulation tests
  • Cache poisoning prevention tests
  • Concurrent transaction isolation tests
  • Session variable isolation tests
  • Tampering detection tests

Phase 5: Encryption

  • AES-256-GCM encryption service
  • Tenant-specific key derivation
  • EncryptedData serialization for database storage
  • Nonce uniqueness verification
  • 11 comprehensive encryption tests
  • Cross-tenant encryption isolation

๐Ÿ“‹ Upcoming Phases

  • Phase 6: RBAC authorization system
  • Phase 7: Audit logging framework
  • Phase 8: Rate limiting & throttling
  • Phase 9: Performance optimization
  • Phase 10: Documentation & examples

๐Ÿข Production Deployment

Docker

FROM rust:1.75 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/app /usr/local/bin/
EXPOSE 8080
CMD ["app"]

Environment Variables

DATABASE_URL=postgres://user:pass@host:5432/db
JWT_SECRET=your-production-secret-key-min-32-chars!!
RUST_LOG=info
SERVER_PORT=8080

๐Ÿค Contributing

This project is currently in active development. Contributions, issues, and feature requests are welcome!

๐Ÿ“„ License

Licensed under MIT License (LICENSE-MIT)

๐Ÿ™ Acknowledgments

Built with these amazing technologies:


Built with โค๏ธ by Trendium Labs

โญ Star this repo if you find it useful!

Dependencies

~78MB
~1.5M SLoC