Skip to main content

Magic Link Authentication

Magic link authentication lets users sign in by clicking a one-time link sent to their email address — no passwords required. Oxy delivers these links via Amazon SES and verifies them server-side.
Only Amazon SES is supported as an email delivery provider at this time. Support for additional providers (SMTP, SendGrid, etc.) is planned for a future release.

How It Works

  1. User enters their email on the login page
  2. Oxy generates a cryptographically random 256-bit token and stores it with a 15-minute expiry
  3. An email containing a sign-in link is sent to the user via Amazon SES
  4. User clicks the link → token is verified and immediately invalidated → user is logged in

Features

  • ✅ No passwords to manage or leak
  • ✅ Tokens expire in 15 minutes and are single-use
  • ✅ Works alongside Google OAuth and Okta OAuth
  • ✅ Optional domain blocklist and email allowlist for access control
  • ✅ IAM role credentials — no long-lived AWS keys required
  • ✅ Local development mode (browser-based, no SES needed)

Prerequisites

  • An AWS account with Amazon SES access
  • A verified sender email address (or verified domain) in SES
  • If your SES account is in the sandbox, recipient emails must also be verified

Environment Variables

VariableRequiredDescription
MAGIC_LINK_FROM_EMAILYes (production)SES-verified sender address, e.g. noreply@yourcompany.com
MAGIC_LINK_AWS_REGIONNoAWS region for SES (falls back to AWS_REGION)
MAGIC_LINK_BLOCKED_DOMAINSNoComma-separated domains that are denied sign-in (e.g. gmail.com)
MAGIC_LINK_ALLOWED_EMAILSNoComma-separated individual emails allowed to sign in
MAGIC_LINK_LOCAL_TESTNoSet to any value to enable browser-based local testing
AWS_REGIONNoDefault AWS region (used by SES if MAGIC_LINK_AWS_REGION not set)

Setup Guide

1. Verify a Sender in Amazon SES

  1. Open the AWS SES Console
  2. Navigate to Verified identitiesCreate identity
  3. Choose Email address (or Domain for organization-wide use)
  4. Verify ownership via the confirmation email AWS sends
New SES accounts start in sandbox mode. In sandbox mode, you can only send to verified email addresses. Request production access (“Move out of sandbox”) when you’re ready to send to all users.

2. Configure AWS Credentials

Oxy uses the standard AWS credential chain. Preferred approaches (no long-lived keys): EC2 / ECS / Kubernetes with IAM Role (recommended): Attach an IAM role to your compute resource with this policy:
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "ses:SendEmail",
      "Resource": "*"
    }
  ]
}
No environment variables needed — the SDK picks up the role automatically. Static credentials (development/CI):
export AWS_ACCESS_KEY_ID=AKIA...
export AWS_SECRET_ACCESS_KEY=your_secret
export AWS_REGION=us-east-1

3. Set the Sender Email

export MAGIC_LINK_FROM_EMAIL=noreply@yourcompany.com

4. Start Oxy

oxy serve
The login page will display a “Continue with email” input. Users enter their email, receive a link, and click it to sign in.

Access Control

By default, any email address can request a magic link. Use the options below to restrict access: Domain blocklist — deny sign-in from specific domains (e.g. public email providers):
export MAGIC_LINK_BLOCKED_DOMAINS=gmail.com,yahoo.com,hotmail.com
Individual email allowlist — when set, only these specific addresses can sign in:
export MAGIC_LINK_ALLOWED_EMAILS=alice@example.com,bob@example.com
Combined — blocked domains are always rejected first, then the allowlist is checked:
export MAGIC_LINK_BLOCKED_DOMAINS=gmail.com
export MAGIC_LINK_ALLOWED_EMAILS=contractor@example.com
When an email is denied, Oxy still returns a success response — it never reveals whether a specific address is allowed. No email is sent.

Local Development

For local development you don’t need an AWS account. Set MAGIC_LINK_LOCAL_TEST to any value and Oxy will write the sign-in email to a temporary HTML file and open it automatically in your browser:
export MAGIC_LINK_LOCAL_TEST=1
oxy serve
When you enter an email on the login page, your browser opens the rendered sign-in email. Click the button inside it to complete the login flow — identical to the real experience, no AWS required.
MAGIC_LINK_FROM_EMAIL is optional in local test mode. If omitted, Oxy uses noreply@localhost as a placeholder sender.

Combining with Other Auth Methods

Magic link works alongside Google OAuth and Okta. All enabled methods appear on the login page simultaneously:
# Magic link + Google
export MAGIC_LINK_FROM_EMAIL=noreply@yourcompany.com
export GOOGLE_CLIENT_ID=123...apps.googleusercontent.com
export GOOGLE_CLIENT_SECRET=GOCSPX-...

oxy serve

Security Details

PropertyValue
Token entropy256 bits (32 random bytes, hex-encoded)
Token lifetime15 minutes
Single-useYes — token is deleted immediately on first use
Email verificationSet automatically on successful sign-in
Access control disclosureNever — always returns 200 to prevent enumeration