SMTP Configuration Guide¶
Configure SMTP for Keycloak email features (verification, password reset, notifications).
Quick Setup¶
1. Create SMTP Credentials Secret¶
kubectl create secret generic my-realm-smtp \
--from-literal=username=smtp-user \
--from-literal=password=smtp-password \
--namespace=my-app
2. Configure Realm with SMTP¶
apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
name: my-realm
namespace: my-app
spec:
realmName: my-realm
operatorRef:
namespace: keycloak-system
smtp:
host: smtp.sendgrid.net
port: 587
from: noreply@example.com
fromDisplayName: My Application
auth: true
starttls: true
credentialsSecret: my-realm-smtp
Provider Examples¶
SendGrid¶
# Create secret
kubectl create secret generic smtp-sendgrid \
--from-literal=username=apikey \
--from-literal=password=SG.your-api-key \
--namespace=my-app
smtp:
host: smtp.sendgrid.net
port: 587
from: noreply@example.com
fromDisplayName: My App
auth: true
starttls: true
credentialsSecret: smtp-sendgrid
Gmail¶
Setup: Enable 2FA and create App Password at https://myaccount.google.com/apppasswords
kubectl create secret generic smtp-gmail \
--from-literal=username=your-email@gmail.com \
--from-literal=password=your-app-password \
--namespace=my-app
smtp:
host: smtp.gmail.com
port: 587
from: your-email@gmail.com
fromDisplayName: My Application
auth: true
starttls: true
credentialsSecret: smtp-gmail
AWS SES¶
# Get SMTP credentials from AWS SES Console
kubectl create secret generic smtp-ses \
--from-literal=username=YOUR_SMTP_USERNAME \
--from-literal=password=YOUR_SMTP_PASSWORD \
--namespace=my-app
smtp:
host: email-smtp.us-east-1.amazonaws.com
port: 587
from: verified-sender@example.com # Must be verified in SES
fromDisplayName: My Application
auth: true
starttls: true
credentialsSecret: smtp-ses
Mailgun¶
kubectl create secret generic smtp-mailgun \
--from-literal=username=postmaster@mg.example.com \
--from-literal=password=your-smtp-password \
--namespace=my-app
smtp:
host: smtp.mailgun.org
port: 587
from: noreply@mg.example.com
fromDisplayName: My Application
auth: true
starttls: true
credentialsSecret: smtp-mailgun
Office 365¶
kubectl create secret generic smtp-o365 \
--from-literal=username=your-email@company.com \
--from-literal=password=your-password \
--namespace=my-app
smtp:
host: smtp.office365.com
port: 587
from: your-email@company.com
fromDisplayName: Company Name
auth: true
starttls: true
credentialsSecret: smtp-o365
Testing SMTP Configuration¶
1. Enable Email Verification¶
Update your realm to enable email verification:
apiVersion: vriesdemichael.github.io/v1
kind: KeycloakRealm
metadata:
name: my-realm
namespace: my-app
spec:
realmName: my-realm
operatorRef:
namespace: keycloak-system
security:
verifyEmail: true
registrationAllowed: true # For testing only
smtp:
host: smtp.sendgrid.net
port: 587
from: noreply@example.com
fromDisplayName: My Application
auth: true
starttls: true
credentialsSecret: my-realm-smtp
Apply the changes:
2. Test Email Delivery¶
Option A: Self-Registration Flow (recommended for testing) 1. Navigate to your realm's account registration page:
https://keycloak.example.com/realms/my-realm/protocol/openid-connect/registrations?client_id=account&response_type=code
Option B: Password Reset Flow 1. Create a test user via Keycloak admin console or realm import 2. Navigate to password reset page:
3. Enter test user's email 4. Check email for password reset link3. Check Keycloak Logs¶
Troubleshooting¶
SMTP Connection Refused¶
# Test SMTP connectivity from Keycloak pod
KEYCLOAK_POD=$(kubectl get pods -n keycloak-system -l app=keycloak -o name | head -1)
kubectl exec -it -n keycloak-system ${KEYCLOAK_POD} -- \
curl -v telnet://smtp.sendgrid.net:587
Solutions: - Verify host/port correct - Check firewall/network policies - Ensure SMTP service allows connections
Authentication Failed¶
Check: - Username/password correct in secret - API key format (some providers use "apikey" as username) - Account not locked/suspended
Emails Not Received¶
Check: 1. Spam folder 2. Sender verification (AWS SES requires verified senders) 3. Rate limits (provider may throttle) 4. DKIM/SPF records if using custom domain
SSL/TLS Issues¶
Port Configuration:
- Port 587: Use starttls: true, ssl: false
- Port 465: Use ssl: true, starttls: false
- Port 25: Use starttls: false, ssl: false (not recommended)
Production Best Practices¶
1. Use SealedSecrets¶
# Encrypt SMTP credentials
kubeseal -o yaml < smtp-secret.yaml > smtp-secret-sealed.yaml
kubectl apply -f smtp-secret-sealed.yaml
2. Dedicated SMTP Service Account¶
Create dedicated account/API key for Keycloak: - Limit permissions (send-only) - Easier to rotate credentials - Better audit trail
3. Monitor Email Delivery¶
Track metrics: - Emails sent (Keycloak events) - Bounce rate (provider dashboard) - Delivery time
4. Configure Rate Limits¶
Avoid provider throttling: - SendGrid: 100 emails/day (free), higher for paid - Gmail: 500 emails/day - AWS SES: 200 emails/day (sandbox), higher after verification