Self-Hosting
Environment Variables
Complete reference for all HelloJohn environment variables and configuration options.
HelloJohn is configured entirely through environment variables. There are no configuration files.
These must be set or HelloJohn will refuse to start.
| Variable | Example | Description |
|---|
DATABASE_URL | postgres://user:pass@host:5432/db | PostgreSQL connection string |
JWT_SECRET | <32+ random bytes> | Secret used to sign JWTs. Generate with openssl rand -hex 32 |
APP_URL | https://auth.yourdomain.com | Public base URL of the HelloJohn instance |
| Variable | Default | Description |
|---|
DATABASE_URL | — | Full PostgreSQL DSN |
DATABASE_MAX_CONNECTIONS | 20 | Max open connections in the pool |
DATABASE_IDLE_CONNECTIONS | 5 | Max idle connections |
DATABASE_CONNECT_TIMEOUT | 10s | Connection timeout |
DATABASE_SSL_MODE | prefer | disable, require, verify-ca, verify-full |
| Variable | Default | Description |
|---|
JWT_SECRET | — | Required. HMAC secret or path to Ed25519 private key |
JWT_ALGORITHM | EdDSA | EdDSA (default) or HS256 |
JWT_PRIVATE_KEY_PATH | — | Path to PEM-encoded Ed25519 private key (preferred over secret) |
JWT_PUBLIC_KEY_PATH | — | Path to PEM-encoded Ed25519 public key |
ACCESS_TOKEN_TTL | 15m | Access token lifetime |
REFRESH_TOKEN_TTL | 720h | Refresh token lifetime (30 days) |
REFRESH_TOKEN_ROTATION | true | Rotate refresh tokens on each use |
| Variable | Default | Description |
|---|
APP_URL | — | Required. Public base URL (no trailing slash) |
PORT | 3000 | Port to listen on |
HOST | 0.0.0.0 | Interface to bind to |
LOG_LEVEL | info | debug, info, warn, error |
LOG_FORMAT | json | json or text |
ENV | production | development or production |
Required for magic links, email verification, and password resets.
| Variable | Default | Description |
|---|
SMTP_HOST | — | SMTP server hostname |
SMTP_PORT | 587 | SMTP port |
SMTP_USER | — | SMTP username |
SMTP_PASS | — | SMTP password |
SMTP_FROM | — | Sender address, e.g. HelloJohn <noreply@yourdomain.com> |
SMTP_TLS | starttls | starttls, tls, or none |
SMTP_TIMEOUT | 10s | Connection timeout |
EMAIL_MAGIC_LINK_TTL | 15m | Magic link expiry |
EMAIL_VERIFICATION_TTL | 24h | Email verification link expiry |
Replace PROVIDER with GOOGLE, GITHUB, GITLAB, MICROSOFT, or DISCORD.
| Variable | Example | Description |
|---|
OAUTH_PROVIDER_CLIENT_ID | — | OAuth app client ID |
OAUTH_PROVIDER_CLIENT_SECRET | — | OAuth app client secret |
OAUTH_PROVIDER_ENABLED | true | Enable this provider |
Examples:
OAUTH_GOOGLE_CLIENT_ID=1234567890.apps.googleusercontent.com
OAUTH_GOOGLE_CLIENT_SECRET=GOCSPX-...
OAUTH_GOOGLE_ENABLED=true
OAUTH_GITHUB_CLIENT_ID=Iv1.abc123
OAUTH_GITHUB_CLIENT_SECRET=abc123...
OAUTH_GITHUB_ENABLED=true
| Variable | Default | Description |
|---|
REDIS_URL | — | Redis connection URL, e.g. redis://localhost:6379 |
REDIS_TLS | false | Enable TLS for Redis connection |
REDIS_PASSWORD | — | Redis AUTH password |
REDIS_DB | 0 | Redis database index |
When REDIS_URL is not set, HelloJohn falls back to in-memory rate limiting and session storage (not suitable for multi-instance deployments).
| Variable | Default | Description |
|---|
RATE_LIMIT_ENABLED | true | Enable global rate limiting |
RATE_LIMIT_LOGIN_MAX | 10 | Max login attempts per IP per window |
RATE_LIMIT_LOGIN_WINDOW | 1m | Window duration for login attempts |
RATE_LIMIT_SIGNUP_MAX | 5 | Max signup attempts per IP per window |
RATE_LIMIT_SIGNUP_WINDOW | 1h | Window duration for signup attempts |
RATE_LIMIT_MAGIC_LINK_MAX | 5 | Max magic link requests per email per window |
RATE_LIMIT_MAGIC_LINK_WINDOW | 10m | Window duration for magic link requests |
| Variable | Default | Description |
|---|
MFA_TOTP_ISSUER | HelloJohn | TOTP issuer name shown in authenticator apps |
MFA_TOTP_PERIOD | 30 | TOTP period in seconds |
MFA_TOTP_DIGITS | 6 | TOTP digit count (6 or 8) |
MFA_TOTP_DRIFT | 1 | Allowed clock drift in periods (1 = ±30s) |
MFA_WEBAUTHN_RP_ID | — | WebAuthn Relying Party ID (e.g. yourdomain.com) |
MFA_WEBAUTHN_RP_NAME | — | Human-readable RP name shown in browser prompts |
MFA_WEBAUTHN_ORIGIN | — | Allowed origin, e.g. https://yourdomain.com |
MFA_BACKUP_CODE_COUNT | 10 | Number of backup codes generated per user |
| Variable | Default | Description |
|---|
STORAGE_DRIVER | local | local, s3, or r2 |
STORAGE_LOCAL_PATH | ./storage | Local storage directory |
STORAGE_S3_BUCKET | — | S3 bucket name |
STORAGE_S3_REGION | — | AWS region |
STORAGE_S3_ACCESS_KEY | — | AWS access key ID |
STORAGE_S3_SECRET_KEY | — | AWS secret access key |
STORAGE_S3_ENDPOINT | — | Custom endpoint (for R2, MinIO, etc.) |
STORAGE_PUBLIC_URL | — | Base URL for public assets |
| Variable | Default | Description |
|---|
WEBHOOK_TIMEOUT | 10s | Timeout for webhook delivery |
WEBHOOK_MAX_RETRIES | 5 | Number of retry attempts |
WEBHOOK_SIGNING_SECRET | — | Default HMAC signing secret (per-endpoint secrets override this) |
| Variable | Default | Description |
|---|
ADMIN_EMAIL | — | Email of the first admin (seeded on first start) |
ADMIN_PASSWORD | — | Password for the first admin (seeded on first start) |
DASHBOARD_ENABLED | true | Enable the built-in admin dashboard |
DASHBOARD_PATH | /_hj/admin | Admin dashboard path |
| Variable | Default | Description |
|---|
CORS_ALLOWED_ORIGINS | * | Comma-separated list of allowed CORS origins |
CORS_ALLOWED_METHODS | GET,POST,PUT,DELETE,OPTIONS | Allowed HTTP methods |
SESSION_COOKIE_SECURE | true | Set Secure flag on session cookies |
SESSION_COOKIE_SAME_SITE | Lax | Strict, Lax, or None |
TRUST_PROXY | true | Trust X-Forwarded-For headers from reverse proxy |
TRUST_PROXY_HOPS | 1 | Number of trusted proxy hops |
# JWT secret (HMAC)
openssl rand -hex 32
# Ed25519 key pair (recommended)
openssl genpkey -algorithm ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem
# Webhook signing secret
openssl rand -hex 32
Store secrets in a secret manager (AWS Secrets Manager, HashiCorp Vault, Doppler) — never commit them to version control.