Email OTP Authentication for Dashboard Access¶
Overview¶
Users in the user_emails list can now authenticate to the dashboard using email OTP (One-Time Password) as an alternative to their regular organizational credentials (GitHub, Google, etc.).
Configuration¶
Enable/Disable Email OTP¶
In terraform.auto.tfvars:
# Users who can access the dashboard (same list)
user_emails = [
"tautcius@gmail.com"
]
# Enable email OTP authentication
enable_email_otp = true
Who Can Use Email OTP?¶
Any email address in the user_emails list can authenticate using:
1. Primary method: Their configured organizational login (GitHub, Google, etc.)
2. Alternative method: Email OTP (requires email verification)
How It Works¶
Authentication Flow¶
- User visits dashboard:
https://rpi-prod-1883c404a12f.tagai.uk(or similar) - Cloudflare Access prompts for authentication
- User chooses one of:
- GitHub/Google Login (if configured)
- Email OTP: Receives one-time code via email, enters it
- Access is granted if user is in the
user_emailslist
Email OTP Details¶
- Delivery: Sent directly to user's email
- Validity: 10 minutes (Cloudflare default)
- Resend: Available if code expires
- No password: Purely email-based verification
Access Control¶
Admins (admin_emails)¶
- Access: Node-RED UI, SSH, Dashboard
- Authentication: GitHub + Organization Team
- Email OTP: Not available (admins only)
Users (user_emails)¶
- Access: Dashboard (read-only)
- Authentication: GitHub/Google OR Email OTP
- Node-RED UI: Not accessible (admin-only)
Terraform Configuration¶
Variables¶
variable "user_emails" {
description = "User email addresses for Cloudflare Access"
type = list(string)
default = []
}
variable "enable_email_otp" {
description = "Enable email OTP as authentication method for users"
type = bool
default = true
}
Module Setup¶
module "access" {
source = "./modules/access"
user_emails = var.user_emails
enable_email_otp = var.enable_email_otp
# ... other variables
}
Policy Details¶
Dashboard Application Policy¶
When enable_email_otp = true:
Policy: Allow Users - Dashboard Access
├─ Include: Gaisro Technika Users group
├─ Require: Email OTP provider
└─ Decision: Allow
Users must be in the user_emails list and pass email OTP authentication.
When enable_email_otp = false:
Policy: Allow Users - Dashboard Access
├─ Include: Gaisro Technika Users group
└─ Decision: Allow
Users in the list are automatically granted access (no additional auth required if already logged in via GitHub/Google).
Use Cases¶
1. Guest Access¶
Add temporary users to user_emails:
user_emails = [
"tautcius@gmail.com",
"guest@example.com" # Temporary guest with email OTP
]
Guest authenticates via email OTP without needing GitHub/Google account.
2. External Stakeholders¶
Partners/contractors who don't have organizational credentials:
user_emails = [
"partner@example.com"
]
They use email OTP to access the dashboard for monitoring.
3. Passwordless Internal Users¶
Employees can use email instead of password manager:
user_emails = [
"user@company.com" # Can use email OTP OR company GitHub
]
Security Considerations¶
✅ Strengths: - No password storage or reuse - Email-based verification is auditable - Time-limited (10 minutes) - Sent via secure email infrastructure - No third-party OAuth dependency
⚠️ Limitations: - Email interception possible (use company email) - Email account compromise = access compromise - Cannot enforce 2FA with email OTP alone - Requires valid email delivery
Deployment¶
Apply Changes¶
cd terraform/
# Validate configuration
terraform validate
# Plan changes
terraform plan
# Apply
terraform apply
Verify Configuration¶
# Check Access group created
terraform output | grep -i user
# Check policy created
cloudflare_zero_trust_access_policy.web_users
Testing¶
Test Email OTP Login¶
- Clear browser cookies/cache
- Visit dashboard URL:
https://rpi-prod-1883c404a12f.tagai.uk - Click "Email" option (if shown)
- Enter email:
tautcius@gmail.com - Check email for OTP code
- Enter code on Cloudflare Access page
- Should be redirected to dashboard
Test Regular Login (If Configured)¶
- Visit same URL
- Click "GitHub" or "Google" option
- Authenticate with organizational credentials
- Should be redirected to dashboard
Troubleshooting¶
Issue: "Email not recognized"¶
- Cause: Email not in
user_emailslist - Fix: Add email to variable and reapply Terraform
Issue: "OTP code expired"¶
- Cause: Took >10 minutes to use code
- Fix: Request new OTP code from login page
Issue: "Email not received"¶
- Cause: Spam filter, wrong email, or email service issue
- Fix: Check spam folder, verify email address, contact admin
Issue: "Still can't login after adding to list"¶
- Cause: Terraform not applied
- Fix: Run
terraform apply
Advanced Configuration¶
Require Email OTP + GitHub (MFA-style)¶
To require both email OTP AND GitHub authentication (stronger security):
# Modify the policy in access/main.tf
require = [{
github = { ... }
}, {
email_otp = { ... }
}]
This enforces multi-factor authentication.
Disable Email OTP¶
To turn off email OTP:
enable_email_otp = false
Then:
terraform apply
Users must use GitHub/Google to login.
Audit Trail¶
All email OTP authentications are logged in: - Cloudflare Logs: Access > Accounts > Activity - Filter: Look for "Email OTP" authentication events - Details: Email, IP, timestamp, success/failure
Best Practices¶
- Use company emails: Avoid personal/free emails for security
- Monitor access logs: Regularly review who's accessing
- Limit user list: Keep only necessary users
- Combine with policies: Use Access groups for fine-grained control
- Test before rollout: Test with pilot users first
Related Documentation¶
Last Updated: January 7, 2026 Status: Ready for Deployment ✅