> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/calcom/cal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Single Sign-On (SSO)

> Configure SSO authentication for your Cal.com organization

Single Sign-On (SSO) allows users to authenticate with Cal.com using their organization's identity provider instead of creating separate credentials. Cal.com supports both SAML and OIDC protocols.

## Overview

SSO provides:

* **Centralized Authentication**: Users log in through your identity provider
* **Enhanced Security**: Leverage your organization's security policies
* **Simplified Management**: Centrally manage user access and permissions
* **Automatic Provisioning**: Works with SCIM for user lifecycle management

## Prerequisites

* Cal.com Enterprise license
* Organizations feature enabled
* Separate PostgreSQL database for SAML/SSO data
* Identity Provider (IdP) supporting SAML 2.0 or OIDC

## Configuration

### 1. Environment Variables

Add the following to your `.env` file:

```bash .env theme={null}
# Required: Separate database for SSO/SAML data
SAML_DATABASE_URL=postgresql://postgres:@localhost:5450/cal-saml

# Required: Admin emails with SSO management access
SAML_ADMINS=admin@example.com,sysadmin@example.com

# Required: Application encryption key (32 bytes for AES256)
# Generate with: openssl rand -base64 24
CALENDSO_ENCRYPTION_KEY=your_encryption_key

# Optional: Client secret verifier for OAuth 2.0 flow
SAML_CLIENT_SECRET_VERIFIER=your_secret_verifier

# Optional: Enable hosted Cal.com features
NEXT_PUBLIC_HOSTED_CAL_FEATURES=1
```

Source: `.env.example:46-55`

### 2. Database Setup

Create a separate PostgreSQL database for SSO data:

```bash theme={null}
# Create database
creatdb cal-saml

# Run migrations
DATABASE_URL="postgresql://postgres:@localhost:5450/cal-saml" yarn prisma migrate deploy
```

### 3. Jackson SSO Library

Cal.com uses [BoxyHQ's Jackson](https://github.com/boxyhq/jackson) library for SSO implementation.

Jackson Configuration:

```typescript theme={null}
const opts: JacksonOption = {
  externalUrl: WEBAPP_URL,
  samlPath: "/api/auth/saml/callback",
  samlAudience: "https://saml.cal.com",
  oidcPath: "/api/auth/oidc",
  scimPath: "/api/scim/v2.0",
  db: {
    engine: "sql",
    type: "postgres",
    url: samlDatabaseUrl,
    encryptionKey: process.env.CALENDSO_ENCRYPTION_KEY,
  },
  idpEnabled: true,
  clientSecretVerifier,
};
```

Source: `packages/features/ee/sso/lib/jackson.ts:19-33`

## SSO Admin Access

### Self-Hosted

For self-hosted deployments, SSO configuration is restricted to admins listed in `SAML_ADMINS`:

```typescript theme={null}
// Check if user is SSO admin
const isSAMLAdmin = (email: string) => {
  const samlAdmins = (process.env.SAML_ADMINS || "").split(",");
  return samlAdmins.some(
    admin => admin.toLowerCase() === email.toLowerCase()
  );
};
```

Source: `packages/features/ee/sso/lib/saml.ts:20-30`

### Hosted Cal.com

For hosted deployments, SSO access is controlled by organization permissions:

* Organization Owners: Full SSO configuration access
* Organization Admins: Full SSO configuration access
* Organization Members: No SSO configuration access

Source: `packages/features/ee/sso/lib/saml.ts:32-81`

## SSO Login Flow

### 1. User Initiates Login

User enters email at login screen:

```
1. User visits /auth/login
2. Enters email address
3. Cal.com checks for SSO configuration
4. Redirects to IdP if SSO is enabled
```

### 2. Identity Provider Authentication

```
1. User redirects to IdP login page
2. User authenticates with IdP credentials
3. IdP generates SAML assertion/OIDC token
4. IdP redirects back to Cal.com callback URL
```

### 3. Cal.com Processes Response

```
1. Cal.com receives SAML assertion/OIDC token
2. Validates signature and attributes
3. Extracts user information
4. Creates or updates user account
5. Creates session and redirects to app
```

Source: `packages/features/ee/sso/lib/sso.ts:26-83`

## Automatic User Provisioning

SSO can automatically provision users on first login:

### Email Domain Matching

When `ORGANIZATIONS_AUTOLINK=1` is enabled:

```typescript theme={null}
const domain = email.split("@")[1];
const organization = await organizationRepository
  .getVerifiedOrganizationByAutoAcceptEmailDomain(domain);

if (organization) {
  // Auto-provision user to organization
  await createUsersAndConnectToOrg({
    emailsToCreate: [email],
    identityProvider: IdentityProvider.SAML,
    identityProviderId: email,
    org: organization,
  });
}
```

Source: `packages/features/ee/sso/lib/sso.ts:34-49`

### Organization Assignment

Users are automatically assigned to organizations based on:

1. **Email Domain**: Matching verified organization domain
2. **Existing Membership**: Current team memberships
3. **SSO Connection**: Configured SSO tenant mapping

Source: `packages/features/ee/sso/lib/sso.ts:26-83`

## Multi-Team SSO

Cal.com supports SSO across multiple teams within an organization:

```typescript theme={null}
// Check SSO connections for each team user is a member of
const promises = memberships.map(({ teamId }) =>
  connectionController.getConnections({
    tenant: `team-${teamId}`,
    product: "Cal.com",
  })
);

// Use first SSO connection found
const connectionResults = await Promise.allSettled(promises);
```

Source: `packages/features/ee/sso/lib/sso.ts:56-70`

## SSO Tenants

Each team/organization has its own SSO tenant:

* **Tenant ID Format**: `team-{teamId}`
* **Product ID**: `Cal.com`
* **Audience**: `https://saml.cal.com`

Source: `packages/features/ee/sso/lib/saml.ts:10-18`

## Security Considerations

### Client Secret Verification

For enhanced security during OAuth 2.0 flows:

```bash .env theme={null}
# Set a random secret for client verification
SAML_CLIENT_SECRET_VERIFIER=your_random_secret
```

Use this value as `client_secret` during the OAuth 2.0 flow.

Source: `.env.example:55`

### Encryption

All SSO credentials and sensitive data are encrypted using the `CALENDSO_ENCRYPTION_KEY`:

```bash theme={null}
# Generate a secure 32-byte key
openssl rand -base64 24
```

Source: `packages/features/ee/sso/lib/jackson.ts:29`

### Admin Restrictions

SSO configuration is restricted to:

* Emails listed in `SAML_ADMINS` (self-hosted)
* Organization Owners/Admins (hosted)

Source: `packages/features/ee/sso/lib/saml.ts:32-81`

## Troubleshooting

### SSO Not Available

**Error**: "To enable this feature, add value for `SAML_DATABASE_URL` and `SAML_ADMINS` to your `.env`"

**Solution**: Ensure environment variables are configured:

```bash theme={null}
SAML_DATABASE_URL=postgresql://postgres:@localhost:5450/cal-saml
SAML_ADMINS=admin@example.com
```

Source: `packages/features/ee/sso/lib/saml.ts:35-39`

### Permission Denied

**Error**: "dont\_have\_permission"

**Solutions**:

* **Self-hosted**: Add your email to `SAML_ADMINS`
* **Hosted**: Verify you have Owner or Admin role in the organization

Source: `packages/features/ee/sso/lib/saml.ts:46-74`

### No SSO Connection Found

**Error**: "Could not find a SSO Identity Provider for your email. Please contact your admin to ensure you have been given access to Cal"

**Solutions**:

1. Verify SSO connection is configured for your team/organization
2. Check that your email matches an existing membership
3. Confirm the SSO tenant is correctly mapped
4. Review SSO connection status in organization settings

Source: `packages/features/ee/sso/lib/sso.ts:72-77`

### User Belongs to Different Organization

**Error**: "User belongs to another organization."

**Solution**: Users can only belong to one organization. Contact support to migrate the user.

Source: `packages/features/ee/dsync/lib/handleUserEvents.ts:81-83`

## API Endpoints

SSO uses the following API endpoints:

| Endpoint                  | Protocol | Purpose                                               |
| ------------------------- | -------- | ----------------------------------------------------- |
| `/api/auth/saml/callback` | SAML 2.0 | SAML assertion callback                               |
| `/api/auth/oidc`          | OIDC     | OpenID Connect authentication                         |
| `/api/scim/v2.0`          | SCIM 2.0 | User provisioning (see [SCIM docs](/enterprise/scim)) |

Source: `packages/features/ee/sso/lib/jackson.ts:21-24`

## Best Practices

1. **Use Separate Database**: Always use a dedicated database for SSO data to isolate sensitive authentication information
2. **Rotate Secrets**: Regularly rotate `SAML_CLIENT_SECRET_VERIFIER` and `CALENDSO_ENCRYPTION_KEY`
3. **Limit Admins**: Only add necessary users to `SAML_ADMINS`
4. **Test Thoroughly**: Test SSO flow in staging before production deployment
5. **Monitor Logs**: Enable logging for SSO events to track authentication issues
6. **Use SCIM**: Combine SSO with SCIM for automated user lifecycle management

## Related Documentation

* [SAML Configuration](/enterprise/saml)
* [SCIM Provisioning](/enterprise/scim)
* [Organizations Setup](/enterprise/organizations)
* [BoxyHQ Jackson Documentation](https://boxyhq.com/docs/jackson/overview)
