Authentication

Tenrankai supports modern passwordless authentication with email magic links and WebAuthn passkeys.

Enabling Authentication

Add these settings to your site configuration (config.d/sites/default/site.toml):

# config.d/sites/default/site.toml
base_url = "https://photos.example.com"  # Required for login links
user_database = "users.toml"              # Enables authentication

Note: cookie_secret must be set in the [app] section of your bootstrap config.toml. See the Core Concepts guide.

User Storage Backends

Tenrankai supports multiple storage backends for user data. Configure via URL-style paths:

TOML File (Default)

Simple file-based storage, perfect for single-server deployments:

[app]
user_database = "users.toml"

SQLite

Local database with better concurrency. Ideal for medium deployments:

[app]
user_database = "sqlite:///var/data/users.db"
# Or relative path
user_database = "sqlite://users.db"

Build requirement: SQLite and PostgreSQL backends require the users-sql feature flag:

cargo build --release --features users-sql

PostgreSQL

For production deployments with existing database infrastructure:

[app]
user_database = "postgresql://user:password@localhost/tenrankai"

DynamoDB

Serverless option for AWS deployments:

[app]
user_database = "dynamodb://users-table?region=us-east-1"

Build requirement: DynamoDB requires the users-dynamodb feature flag:

cargo build --release --features users-dynamodb

Multi-Site Isolation

SQL and DynamoDB backends automatically scope users by site ID, enabling secure multi-tenant deployments where each site has isolated user accounts.

Migration Between Backends

Export and import users between backends:

# Export from TOML
tenrankai user export --database users.toml --output users.json

# Import to SQLite
tenrankai user import --database sqlite://users.db --input users.json

Email Configuration

Configure an email provider to send login links. Currently implemented providers:

ProviderUse CaseConfiguration
nullDevelopment/testingLogs emails to console
sesProductionAmazon SES

Note: The configuration accepts smtp, sendgrid, and mailgun as provider values, but these are not yet implemented and will return an error. Use ses for production deployments.

Development (Null Provider)

For testing, use the null provider which logs emails to console:

[email]
provider = "null"
from_address = "noreply@example.com"

Production (Amazon SES)

For production, use Amazon SES:

[email]
provider = "ses"
from_address = "noreply@photos.example.com"
from_name = "Photo Gallery"
region = "us-east-1"  # Optional

AWS credentials are discovered automatically via:

  1. Environment variables (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
  2. AWS credentials file (~/.aws/credentials)
  3. IAM role (EC2, ECS, Lambda)

User Management

Adding Users

Use the CLI to create users:

# Add a user (username and email)
tenrankai user add jane jane@example.com

# List all users
tenrankai user list

# Update a user's email
tenrankai user update jane newemail@example.com

# Remove a user
tenrankai user remove jane

User Database Format

Users are stored in users.toml:

[users.jane]
email = "jane@example.com"

[[users.jane.passkeys]]
id = "..."
public_key = "..."
name = "iPhone"

Login Flow

Email Magic Links

  1. User visits /_login
  2. Enters their email address
  3. Receives email with login link
  4. Clicks link to authenticate
  5. Session cookie is created (7-day expiry)

WebAuthn/Passkeys

After email login, users can register passkeys:

  1. User logs in via email
  2. System prompts to register a passkey
  3. User authenticates with biometrics/security key
  4. Passkey is stored for future logins

Supported methods:

  • Touch ID / Face ID (macOS, iOS)
  • Windows Hello (Windows)
  • Fingerprint sensors (Android, laptops)
  • Hardware security keys (YubiKey, etc.)

Managing Passkeys

Users manage passkeys at /_login/profile:

  • View registered passkeys
  • Remove passkeys
  • Add new passkeys
  • See creation dates

Security Features

Rate Limiting

Login attempts are rate-limited:

  • 5 attempts per email per 5 minutes
  • Prevents brute force attacks
  • Automatic cleanup of old rate limits

Token Expiration

  • Login email tokens: 10 minutes
  • Session cookies: 7 days
  • Tokens are single-use

Session Security

  • HTTPOnly cookies (not accessible to JavaScript)
  • Signed cookies (tamper-proof)
  • Secure flag in production (HTTPS only)

WebAuthn Configuration

WebAuthn is automatically configured from your site settings:

# config.d/sites/default/site.toml
base_url = "https://photos.example.com"    # RP ID = hostname (photos.example.com)
user_database = "users.toml"

The RP (Relying Party) name comes from the name field in your bootstrap config.toml.

Requirements:

  • base_url must be HTTPS (or localhost for development)
  • Hostname becomes the Relying Party ID
  • Works on any subdomain of the RP ID

Integration with Permissions

Authentication enables the permission system. Configure roles in config.d/sites/default/permissions.toml:

public_role = "viewer"                    # Unauthenticated users
default_authenticated_role = "member"      # Logged-in users

[[user_roles]]
username = "jane"
roles = ["admin"]

See Permissions for complete access control documentation.

Troubleshooting

Login Links Not Arriving

  1. Check email provider configuration
  2. Verify from_address is authorized in SES
  3. Check spam folder
  4. For development, check console output (null provider)

WebAuthn Not Working

  1. Ensure base_url uses HTTPS
  2. Check browser supports WebAuthn
  3. Verify domain matches base_url
  4. Check browser console for errors

Session Expired

  • Default session is 7 days
  • Users can re-login via email or passkey
  • Consider implementing “remember me” for longer sessions

Next Steps