Multi-Tenant Support

The PyFIDO Server supports multi-tenant deployments, allowing a single server instance to serve multiple customer domains and Relying Party (RP) IDs with isolated credential storage and configurable policies per tenant.

Overview

Multi-tenant support enables:

  • Tenant Isolation: Separate credential storage per tenant

  • Domain-Based Routing: Automatic tenant detection from request origin

  • Header Override: X-ArculusFido-RelyingParty header for explicit tenant selection

  • Configurable Policies: Per-tenant authentication policies

  • Flexible Deployment: Support for both shared database and dedicated database deployments

Quick Multi-Tenant Setup

This section provides a step-by-step guide for setting up a multi-tenant deployment. For detailed deployment options, see 3. Deployment.

Step 1: Prepare Tenant Configuration

Define your tenant configurations. Each tenant requires:

  • A unique tenant name

  • One or more domains

  • A database name (optional, defaults to tenant name)

  • A MongoDB connection URI (optional, defaults to global mongourl)

Example tenant configurations:

You can define tenants directly in commands or use environment variables:

Step 2: Start Server with Tenant Parameters

Option A: Direct Python Execution

Or using environment variables:

Option B: Docker

Or using environment variables:

Option C: Docker Compose

Add tenant parameters to your docker-compose.yml:

For more deployment options, see 3.2 Docker Configuration and 3.3 Local Development.

Step 3: Configure Infrastructure

After starting the server, configure your infrastructure:

  1. Configure DNS: Point each tenant domain to your load balancer

  2. Request SSL Certificates: Obtain SSL/TLS certificates for each tenant domain

    AWS Certificate Manager (ACM) Example:

    Alternative Options:

    • Let's Encrypt (free, automated renewal)

    • Your preferred CA

    • Configure certificates on your load balancer

  3. Update Load Balancer Routing: Configure routing rules to forward requests to the FIDO2 server

    • Route /fidoapi/* paths to the FIDO2 server

    • Ensure origin headers are preserved for tenant detection

    • Configure health checks for the FIDO2 server endpoint

For detailed infrastructure setup, see:

Step 4: Verify Tenant Configuration

Test that each tenant is properly configured:

Quick Health Check:

Full FIDO2 API Test:

Each tenant should respond independently with tenant-specific configurations. Verify that:

  • Each tenant returns its own challenge and configuration

  • Credentials registered for one tenant cannot authenticate for another tenant

  • Domain-based routing correctly identifies the tenant

Tenant Identification

The PyFIDO Server supports multiple methods for identifying tenants:

1. Domain-Based Routing (Automatic)

Tenants are automatically identified based on the request origin (domain). The server extracts the domain from the request and maps it to the appropriate tenant configuration.

Example:

2. Header Override

The X-ArculusFido-RelyingParty header can be used to explicitly specify the tenant or relying party domain when domain-based routing is not sufficient.

Example:

3. Configuration-Based

Tenants can be configured at server startup using the --tenant parameter, which allows specifying tenant name, domains, and database configuration.

Tenant Configuration

Single-Tenant Mode (Default)

When no tenants are specified, the server runs in single-tenant mode:

  • Uses the domain specified by --domain parameter

  • Single database instance

  • Single FIDO2 server instance

  • Backward compatible with existing deployments

Multi-Tenant Mode

When tenants are specified via --tenant parameter:

  • Multiple tenant configurations

  • Each tenant can have multiple domains

  • Each tenant can use a separate database or shared database

  • Per-tenant FIDO2 server instances with independent policies

Configuration Format

Parameters:

  • tenantName: Unique identifier for the tenant

  • domain1,domain2: Comma-separated list of domains for this tenant

  • dbName: Database name (optional, defaults to tenantName)

  • mongoUri: MongoDB connection URI (optional, defaults to global mongourl)

Example:

Data Isolation

Shared Database Model

Multiple tenants can share the same MongoDB instance but use separate databases:

  • Each tenant has its own database

  • Complete data isolation at the database level

  • Cost-effective for smaller tenants

  • Suitable for SaaS deployments

Dedicated Database Model

Each tenant can use a completely separate MongoDB instance:

  • Maximum isolation

  • Independent scaling

  • Suitable for enterprise customers with specific requirements

Security Considerations

Tenant Isolation

  • Credential Storage: Credentials are stored per tenant and cannot be accessed across tenant boundaries

  • Domain Validation: Each tenant's domains are validated to prevent cross-tenant access

  • Session Management: Sessions are tenant-aware and isolated

  • Access Control: Tenant access is validated on every request

Origin Verification

  • FIDO2 origin verification ensures requests come from authorized domains

  • Each tenant's domains are validated against the request origin

  • Prevents credential theft through origin binding

Configuration Security

  • Tenant configurations should be managed securely

  • Database credentials stored in secrets management service

  • Tenant activation/deactivation supported

Deployment Models

Model 1: Shared Infrastructure, Separate Databases

Benefits:

  • Cost-effective

  • Centralized management

  • Shared resources

Model 2: Shared Infrastructure, Shared Database

Benefits:

  • Most cost-effective

  • Requires careful schema design

  • Suitable for smaller tenants

Model 3: Dedicated Resources

Benefits:

  • Maximum isolation

  • Independent scaling

  • Enterprise-grade security

Quick Multi-Tenant Setup

Follow these steps to configure a multi-tenant deployment:

Step 1: Define Tenant Configuration

Create your tenant parameters using the format tenantName:domains:dbName:

Step 2: Start Server with Tenants

Step 3: Configure DNS

Point each tenant domain to your load balancer:

Step 4: Configure SSL Certificates

Request SSL certificates for each tenant domain:

Step 5: Verify Configuration

Test each tenant endpoint:

Tenant Management

Adding Tenants

Tenants are configured at server startup. To add a new tenant:

  1. Update server configuration with new --tenant parameter

  2. Restart server (or use dynamic tenant management if supported)

  3. Configure DNS for tenant domains

  4. Set up SSL certificates for tenant domains

Tenant Status

Tenants can be:

  • Active: Accepting requests and processing authentications

  • Inactive: Temporarily disabled (returns 403 for requests)

  • Suspended: Permanently disabled

Monitoring

  • Per-tenant usage metrics

  • Billing and invoicing per tenant

  • Access logs per tenant

  • Error tracking per tenant

Implementation Notes

The multi-tenant implementation uses the ArculusTenantManager class to manage tenant configurations and routing. Each tenant has its own:

  • ArculusTenant instance

  • MongoPersistence instance (database connection)

  • Fido2Server instance (FIDO2 protocol handler)

  • Domain mappings

  • Configuration and policies

For detailed implementation recommendations, see the Multi-Tenancy Architecture Recommendationsarrow-up-right document in the project root.

Last updated