@@ -1,54 +1,29 @@
|
||||
-- Add SAML authentication support
|
||||
-- This migration adds SAML SSO functionality including:
|
||||
-- - SAML configurations per organization
|
||||
-- - SAML request/assertion tracking for security
|
||||
-- - Domain verification
|
||||
-- - User SAML subject tracking
|
||||
|
||||
-- Create ENUM for SAML enforcement policies
|
||||
CREATE TYPE saml_enforcement_policy AS ENUM (
|
||||
'OFF', -- SAML disabled, must use password
|
||||
'OPTIONAL', -- SAML available but not required (default)
|
||||
'REQUIRED' -- Everyone must use SAML
|
||||
'OFF',
|
||||
'OPTIONAL',
|
||||
'REQUIRED'
|
||||
);
|
||||
|
||||
-- Create auth_saml_configurations table
|
||||
CREATE TABLE auth_saml_configurations (
|
||||
id TEXT PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
organization_id TEXT NOT NULL,
|
||||
email_domain TEXT NOT NULL,
|
||||
|
||||
-- SAML enabled flag
|
||||
enabled BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- Enforcement policy for this SAML configuration
|
||||
enforcement_policy saml_enforcement_policy NOT NULL,
|
||||
|
||||
-- Identity Provider (IdP) configuration
|
||||
idp_entity_id TEXT NOT NULL,
|
||||
idp_sso_url TEXT NOT NULL,
|
||||
idp_certificate TEXT NOT NULL, -- X.509 certificate (PEM format)
|
||||
idp_metadata_url TEXT, -- Optional: for auto-refresh
|
||||
|
||||
-- Attribute mapping configuration (using WS-Federation Claims)
|
||||
idp_certificate TEXT NOT NULL,
|
||||
idp_metadata_url TEXT,
|
||||
attribute_email TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress',
|
||||
attribute_firstname TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname',
|
||||
attribute_lastname TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname',
|
||||
attribute_role TEXT NOT NULL DEFAULT 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/role',
|
||||
|
||||
-- Default role if mapping fails or attribute missing
|
||||
default_role TEXT NOT NULL DEFAULT 'MEMBER',
|
||||
|
||||
-- Auto-signup settings
|
||||
auto_signup_enabled BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
-- Domain verification fields
|
||||
domain_verified BOOLEAN NOT NULL DEFAULT false,
|
||||
domain_verification_token TEXT,
|
||||
domain_verified_at TIMESTAMP,
|
||||
|
||||
-- Timestamps
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
updated_at TIMESTAMP NOT NULL,
|
||||
|
||||
@@ -56,63 +31,47 @@ CREATE TABLE auth_saml_configurations (
|
||||
REFERENCES organizations(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Index for fast organization lookup
|
||||
CREATE INDEX idx_auth_saml_configurations_organization_id
|
||||
ON auth_saml_configurations(organization_id);
|
||||
|
||||
-- Index for tenant scoping
|
||||
CREATE INDEX idx_auth_saml_configurations_tenant_id
|
||||
ON auth_saml_configurations(tenant_id);
|
||||
|
||||
-- Unique constraint scoped to organization
|
||||
-- This allows the same domain in different organizations
|
||||
-- while preventing duplicates within the same organization
|
||||
CREATE UNIQUE INDEX idx_saml_config_domain_org_unique
|
||||
ON auth_saml_configurations(organization_id, email_domain)
|
||||
WHERE enabled = true AND domain_verified = true;
|
||||
|
||||
-- Index for fast domain lookup (for email-based SAML discovery)
|
||||
CREATE INDEX idx_saml_config_email_domain
|
||||
ON auth_saml_configurations(email_domain)
|
||||
WHERE enabled = true AND domain_verified = true;
|
||||
|
||||
-- Add SAML subject to users table for tracking SAML NameID
|
||||
ALTER TABLE users ADD COLUMN saml_subject TEXT;
|
||||
|
||||
-- Unique constraint: one SAML subject globally
|
||||
CREATE UNIQUE INDEX idx_users_saml_subject
|
||||
ON users(saml_subject)
|
||||
WHERE saml_subject IS NOT NULL;
|
||||
|
||||
-- Make hashed_password nullable for SAML users
|
||||
-- SAML users authenticate via IdP and don't have passwords
|
||||
ALTER TABLE users ALTER COLUMN hashed_password DROP NOT NULL;
|
||||
|
||||
-- Create auth_saml_assertions table for replay attack prevention
|
||||
CREATE TABLE auth_saml_assertions (
|
||||
id TEXT PRIMARY KEY, -- SAML Assertion ID
|
||||
id TEXT PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
organization_id TEXT NOT NULL,
|
||||
used_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL
|
||||
);
|
||||
|
||||
-- Index for cleanup of expired assertions
|
||||
CREATE INDEX idx_auth_saml_assertions_expires_at
|
||||
ON auth_saml_assertions(expires_at);
|
||||
|
||||
-- Index for organization lookup
|
||||
CREATE INDEX idx_auth_saml_assertions_organization_id
|
||||
ON auth_saml_assertions(organization_id);
|
||||
|
||||
-- Index for tenant scoping
|
||||
CREATE INDEX idx_auth_saml_assertions_tenant_id
|
||||
ON auth_saml_assertions(tenant_id);
|
||||
|
||||
-- Create auth_saml_requests table for proper InResponseTo validation
|
||||
-- This prevents replay attacks and validates the SAML authentication flow
|
||||
CREATE TABLE auth_saml_requests (
|
||||
id TEXT PRIMARY KEY, -- SAML Request ID generated by SP
|
||||
id TEXT PRIMARY KEY,
|
||||
organization_id TEXT NOT NULL,
|
||||
tenant_id TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
@@ -122,20 +81,16 @@ CREATE TABLE auth_saml_requests (
|
||||
REFERENCES organizations(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Index for fast request ID lookup during SAML callback
|
||||
CREATE INDEX idx_auth_saml_requests_id_org ON auth_saml_requests(id, organization_id);
|
||||
|
||||
-- Index for cleanup of expired requests
|
||||
CREATE INDEX idx_auth_saml_requests_expires_at ON auth_saml_requests(expires_at);
|
||||
|
||||
-- Create auth_saml_relay_states table for secure RelayState management
|
||||
-- This prevents organization hijacking attacks
|
||||
CREATE TABLE auth_saml_relay_states (
|
||||
token TEXT PRIMARY KEY, -- Cryptographically secure random token
|
||||
token TEXT PRIMARY KEY,
|
||||
tenant_id TEXT NOT NULL,
|
||||
organization_id TEXT NOT NULL,
|
||||
request_id TEXT NOT NULL, -- Links to auth_saml_requests.id
|
||||
saml_config_id TEXT NOT NULL, -- Links to auth_saml_configurations.id
|
||||
request_id TEXT NOT NULL,
|
||||
saml_config_id TEXT NOT NULL,
|
||||
created_at TIMESTAMP NOT NULL,
|
||||
expires_at TIMESTAMP NOT NULL,
|
||||
|
||||
@@ -147,11 +102,8 @@ CREATE TABLE auth_saml_relay_states (
|
||||
REFERENCES auth_saml_requests(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
-- Index for fast token lookup during callback
|
||||
CREATE INDEX idx_auth_saml_relay_states_token ON auth_saml_relay_states(token);
|
||||
|
||||
-- Index for cleanup of expired relay states
|
||||
CREATE INDEX idx_auth_saml_relay_states_expires_at ON auth_saml_relay_states(expires_at);
|
||||
|
||||
-- Index for tenant scoping
|
||||
CREATE INDEX idx_auth_saml_relay_states_tenant_id ON auth_saml_relay_states(tenant_id);
|
||||
|
||||
Reference in New Issue
Block a user