This guide explains how to integrate Keycloak as your identity provider for unified authentication across all your applications, similar to Zoho's unified login system.
Overview#
Edesy Email already has built-in OpenID Connect (OIDC) support, and Keycloak is a fully-compliant OIDC provider. This means you can integrate Keycloak without any code changes - just configuration.
Benefits of Using Keycloak#
- Unified Login: Single sign-on (SSO) across all your applications
- Centralized User Management: Manage all users in one place
- Multi-Factor Authentication: Built-in 2FA/MFA support
- Identity Brokering: Connect to other identity providers (Google, Facebook, SAML, etc.)
- Fine-grained Authorization: Role-based access control (RBAC)
- User Federation: Connect to LDAP/Active Directory
Prerequisites#
- Running Keycloak instance (self-hosted or cloud)
- Admin access to your Keycloak realm
- Edesy Email installation
Step 1: Configure Keycloak#
1.1 Create a Realm (Optional)#
If you want a dedicated realm for your applications:
- Log in to Keycloak Admin Console
- Click the realm dropdown (top-left) and select Add realm
- Name it (e.g., "mycompany" or "production")
- Click Create
1.2 Create a Client for Edesy Email#
-
In your Keycloak realm, go to Clients -> Create
-
Configure the client:
- Client ID:
edesy-email(or your preferred name) - Client Protocol:
openid-connect - Click Save
- Client ID:
-
Configure Client Settings:
- Access Type:
confidential - Standard Flow Enabled:
ON - Direct Access Grants Enabled:
ON(optional) - Valid Redirect URIs:
https://your-edesy-email-domain.com/api/auth/login/openid/callback http://localhost:3000/api/auth/login/openid/callback - Web Origins:
https://your-edesy-email-domain.comor*for development - Click Save
- Access Type:
-
Get Client Credentials:
- Go to the Credentials tab
- Copy the Secret - you'll need this later
1.3 Configure Client Scopes (Optional but Recommended)#
Ensure the following scopes are available:
- Go to Client Scopes
- Make sure these are included:
openid,email,profile - In your client's Client Scopes tab, ensure these are added as Default Client Scopes
1.4 Configure User Attributes Mappers#
To ensure proper user information is passed to Edesy Email:
- Go to your client -> Mappers tab
- Create the following mappers if they don't exist:
Email Mapper:
- Name:
email - Mapper Type:
User Property - Property:
email - Token Claim Name:
email - Claim JSON Type:
String - Add to ID token:
ON - Add to access token:
ON - Add to userinfo:
ON
First Name Mapper:
- Name:
given name - Mapper Type:
User Property - Property:
firstName - Token Claim Name:
given_name - Claim JSON Type:
String - Add to ID token:
ON
Last Name Mapper:
- Name:
family name - Mapper Type:
User Property - Property:
lastName - Token Claim Name:
family_name - Claim JSON Type:
String - Add to ID token:
ON
Picture Mapper (Optional):
- Name:
picture - Mapper Type:
User Attribute - User Attribute:
picture - Token Claim Name:
picture - Claim JSON Type:
String - Add to ID token:
ON
Step 2: Configure Edesy Email Environment Variables#
Update your .env file or environment configuration:
# Set OpenID as the auth driver
AUTH_DRIVER=openid
# OpenID Connect Configuration
AUTH_OPENID_NAME=Login with Keycloak
AUTH_OPENID_ISSUER_URL=https://your-keycloak-domain.com/realms/your-realm-name
AUTH_OPENID_CLIENT_ID=edesy-email
AUTH_OPENID_CLIENT_SECRET=your-client-secret-from-keycloak
# Note: AUTH_OPENID_REDIRECT_URI is automatically set to {API_BASE_URL}/auth/login/openid/callback
# Optional: Domain whitelist (comma-separated list of allowed email domains)
# Leave empty to allow all domains
AUTH_OPENID_DOMAIN=
# Base URLs (make sure these are correct)
BASE_URL=https://your-edesy-email-domain.com
API_BASE_URL=https://your-edesy-email-domain.com/api
Configuration Details#
AUTH_OPENID_ISSUER_URL: This is your Keycloak realm's issuer URL. Format:
https://{keycloak-host}/realms/{realm-name}- Example:
https://auth.mycompany.com/realms/production - For local development:
http://localhost:8080/realms/master
You can verify this URL by visiting: {ISSUER_URL}/.well-known/openid-configuration
AUTH_OPENID_CLIENT_ID: The Client ID you created in Keycloak (e.g., edesy-email)
AUTH_OPENID_CLIENT_SECRET: Found in Keycloak under Clients -> {your-client} -> Credentials tab
AUTH_OPENID_DOMAIN: Optional. If you want to restrict login to specific email domains:
- Single domain:
mycompany.com - Multiple domains:
company1.com,company2.com - All domains: Leave empty or omit
Step 3: Restart Edesy Email#
After updating your environment variables:
# If using Docker
docker-compose restart
# If running directly
npm run start
Step 4: Test the Integration#
- Navigate to your Edesy Email login page:
https://your-edesy-email-domain.com/login - You should see "Login with Keycloak" (or whatever you set in
AUTH_OPENID_NAME) - Click the button - you'll be redirected to Keycloak
- Log in with your Keycloak credentials
- After successful authentication, you'll be redirected back to Edesy Email
Advanced Configuration#
Multiple Authentication Methods#
You can enable multiple authentication methods simultaneously:
# Enable both OpenID (Keycloak) and Email authentication
AUTH_DRIVER=openid,email
# Email auth settings
[email protected]
AUTH_EMAIL_SMTP_HOST=smtp.yourcompany.com
AUTH_EMAIL_SMTP_PORT=587
AUTH_EMAIL_SMTP_SECURE=true
AUTH_EMAIL_SMTP_USERNAME=your-smtp-username
AUTH_EMAIL_SMTP_PASSWORD=your-smtp-password
Multi-Organization Support#
If you're using Edesy Email's multi-organization feature, you can configure different auth methods per organization:
# Enable multi-org
MULTI_ORG=true
# Set the default auth driver
AUTH_DRIVER=multi
Organizations can then have their own auth configurations in the database.
Domain-based Routing#
To automatically route users based on their email domain (similar to Zoho):
- Set up the Multi auth driver:
AUTH_DRIVER=multi
AUTH_MULTI_NAME=Login
- Configure different organizations with different auth methods
- When users enter their email, they'll be routed to the appropriate auth method
Unified Authentication Across Your Apps#
To achieve Zoho-style unified authentication:
1. Use the Same Keycloak Realm#
Configure all your applications to use the same Keycloak realm. This way:
- Users log in once
- They're automatically authenticated across all apps
- Single logout works across all apps
2. Configure Each Application as a Keycloak Client#
For each application:
- Create a new client in Keycloak
- Set appropriate redirect URIs
- Configure the same user attribute mappers
3. Enable Single Sign-On (SSO)#
Keycloak automatically provides SSO. When a user logs into one application:
- Keycloak creates a session
- When they visit another app using the same Keycloak realm
- They're automatically logged in (if the session is still active)
4. Implement Single Sign-Out (Optional)#
For proper single sign-out across all apps, you may need to:
- Enable backchannel logout in Keycloak clients
- Implement logout endpoints in your applications
- Configure logout redirect URIs
Troubleshooting#
Error: "OpenID validation error"#
Cause: Usually a mismatch in configuration
Solutions:
- Verify the issuer URL is correct and accessible
- Check that the client secret matches
- Ensure the redirect URI in Keycloak matches exactly:
{API_BASE_URL}/auth/login/openid/callback - Check Keycloak logs for more details
Error: "Missing email in claims"#
Cause: Email not included in the ID token
Solutions:
- Ensure the email scope is added to the client
- Check that email mappers are configured correctly
- Verify the user has an email address in Keycloak
Error: "Invalid redirect URI"#
Cause: The redirect URI in the auth request doesn't match Keycloak configuration
Solutions:
- Check
BASE_URLandAPI_BASE_URLin your.envfile - Verify the redirect URI in Keycloak includes:
{API_BASE_URL}/auth/login/openid/callback - Make sure there are no trailing slashes causing mismatches
Users Can't Log In#
Solutions:
- Check if the user exists in Keycloak
- Verify the user's email is verified (if required by your realm)
- Check if there are any required actions on the user account
- Verify the client has the correct access type (confidential)
Session Issues#
If users are getting logged out frequently:
- Check Keycloak's session timeout settings (Realm Settings -> Tokens)
- Verify
APP_SECRETin Edesy Email is set correctly - Check if cookies are being blocked (HTTPS, SameSite issues)
Security Best Practices#
- Use HTTPS: Always use HTTPS in production for both Keycloak and Edesy Email
- Rotate Secrets: Regularly rotate client secrets
- Restrict Domains: Use
AUTH_OPENID_DOMAINto limit which domains can log in - Enable MFA: Configure multi-factor authentication in Keycloak
- Session Timeouts: Set appropriate session timeout values
- Monitor Logs: Regularly review authentication logs in both systems
- Use Strong Passwords: Enforce password policies in Keycloak
- Limit Client Scope: Only request the scopes your application needs
Example: Complete Local Development Setup#
Keycloak (Docker)#
docker run -d \
--name keycloak \
-p 8080:8080 \
-e KEYCLOAK_ADMIN=admin \
-e KEYCLOAK_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:latest \
start-dev
Access Keycloak at http://localhost:8080
Edesy Email .env#
# Authentication
AUTH_DRIVER=openid
AUTH_OPENID_NAME=Login with Keycloak
AUTH_OPENID_ISSUER_URL=http://localhost:8080/realms/master
AUTH_OPENID_CLIENT_ID=edesy-email
AUTH_OPENID_CLIENT_SECRET=your-secret-here
AUTH_OPENID_DOMAIN=
# Base URLs
BASE_URL=http://localhost:3000
API_BASE_URL=http://localhost:3000/api
# Other required settings
APP_SECRET=your-app-secret-here
DB_HOST=localhost
DB_USERNAME=edesy-email
DB_PASSWORD=password
DB_PORT=3306
DB_DATABASE=edesy-email
REDIS_HOST=localhost
REDIS_PORT=6379
Migration from Basic Auth#
If you're currently using basic auth and want to migrate to Keycloak:
- Set up Keycloak as described above
- Create your admin user in Keycloak with the same email
- Update environment variables to use OpenID
- Test the login before fully switching
- Keep basic auth as backup during transition:
AUTH_DRIVER=openid,basic - Remove basic auth once you confirm Keycloak works:
AUTH_DRIVER=openid
Additional Resources#
Support#
If you encounter issues:
- Check the Edesy Email logs for error details
- Check Keycloak admin console -> Events for authentication events
- Verify your configuration matches this guide
- Open an issue on the Edesy Email GitHub repository