Authentication Configuration
Overview
Section titled “Overview”This runbook covers configuring and managing authentication for Everruns.
Authentication Modes
Section titled “Authentication Modes”1. No Authentication (Development)
Section titled “1. No Authentication (Development)”Use for local development when authentication isn’t needed:
export AUTH_MODE=noneAll requests will be allowed with full admin access.
2. Admin Mode (Simple Development)
Section titled “2. Admin Mode (Simple Development)”Use for local development with basic access control:
export AUTH_MODE=adminexport AUTH_ADMIN_EMAIL=admin@example.comexport AUTH_ADMIN_PASSWORD=your-secure-passwordexport AUTH_JWT_SECRET=$(openssl rand -hex 32)Only the admin user can authenticate.
3. Full Authentication (Production)
Section titled “3. Full Authentication (Production)”Use for production deployments:
export AUTH_MODE=fullexport AUTH_BASE_URL=https://your-domain.comexport AUTH_JWT_SECRET=$(openssl rand -hex 32)
# Optional: Configure OAuthexport AUTH_GOOGLE_CLIENT_ID=your-google-client-idexport AUTH_GOOGLE_CLIENT_SECRET=your-google-client-secretexport AUTH_GITHUB_CLIENT_ID=your-github-client-idexport AUTH_GITHUB_CLIENT_SECRET=your-github-client-secretEnvironment Variables Reference
Section titled “Environment Variables Reference”Core Settings
Section titled “Core Settings”| Variable | Required | Description |
|---|---|---|
AUTH_MODE | No | none, admin, or full (default: none) |
AUTH_BASE_URL | For OAuth | Base URL for callbacks (default: http://localhost:9300/api) |
AUTH_JWT_SECRET | For admin/full | JWT signing secret (min 32 chars recommended) |
Admin Mode Settings
Section titled “Admin Mode Settings”| Variable | Required | Description |
|---|---|---|
AUTH_ADMIN_EMAIL | Yes (admin mode) | Admin user email |
AUTH_ADMIN_PASSWORD | Yes (admin mode) | Admin user password |
JWT Settings
Section titled “JWT Settings”| Variable | Required | Description |
|---|---|---|
AUTH_JWT_ACCESS_TOKEN_LIFETIME | No | Access token lifetime in seconds (default: 900) |
AUTH_JWT_REFRESH_TOKEN_LIFETIME | No | Refresh token lifetime in seconds (default: 2592000) |
Feature Toggles
Section titled “Feature Toggles”| Variable | Required | Description |
|---|---|---|
AUTH_DISABLE_PASSWORD | No | Set to true to disable password login |
AUTH_DISABLE_SIGNUP | No | Set to true to disable user registration |
Google OAuth
Section titled “Google OAuth”| Variable | Required | Description |
|---|---|---|
AUTH_GOOGLE_CLIENT_ID | For Google OAuth | Google OAuth client ID |
AUTH_GOOGLE_CLIENT_SECRET | For Google OAuth | Google OAuth client secret |
AUTH_GOOGLE_REDIRECT_URI | No | Custom redirect URI |
AUTH_GOOGLE_ALLOWED_DOMAINS | No | Comma-separated allowed email domains |
GitHub OAuth
Section titled “GitHub OAuth”| Variable | Required | Description |
|---|---|---|
AUTH_GITHUB_CLIENT_ID | For GitHub OAuth | GitHub OAuth client ID |
AUTH_GITHUB_CLIENT_SECRET | For GitHub OAuth | GitHub OAuth client secret |
AUTH_GITHUB_REDIRECT_URI | No | Custom redirect URI |
Common Tasks
Section titled “Common Tasks”Generate JWT Secret
Section titled “Generate JWT Secret”# Using OpenSSLopenssl rand -hex 32
# Using Pythonpython3 -c "import secrets; print(secrets.token_hex(32))"Verify Authentication is Working
Section titled “Verify Authentication is Working”# Check auth config endpointcurl http://localhost:9300/api/v1/auth/config
# Should return:# {"mode":"none","password_auth_enabled":false,"oauth_providers":[],"signup_enabled":false}
# For admin mode:curl -X POST http://localhost:9300/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"admin@example.com","password":"your-password"}'Create API Key
Section titled “Create API Key”# Login first to get access tokenTOKEN=$(curl -s -X POST http://localhost:9300/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email":"user@example.com","password":"password"}' | jq -r '.access_token')
# Create API keycurl -X POST http://localhost:9300/api/v1/auth/api-keys \ -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"my-api-key"}'
# Response includes full key - save it, it's shown only onceRevoke API Key
Section titled “Revoke API Key”curl -X DELETE http://localhost:9300/api/v1/auth/api-keys/{key_id} \ -H "Authorization: Bearer $TOKEN"Force Logout User
Section titled “Force Logout User”Delete their refresh tokens from database:
DELETE FROM refresh_tokens WHERE user_id = 'user-uuid-here';Troubleshooting
Section titled “Troubleshooting””Authentication required” when AUTH_MODE=none
Section titled “”Authentication required” when AUTH_MODE=none”- Verify
AUTH_MODEenvironment variable is set correctly - Restart the server after changing environment variables
JWT Validation Fails
Section titled “JWT Validation Fails”- Ensure
AUTH_JWT_SECREThasn’t changed - Check token hasn’t expired
- Verify the token is for the correct environment
OAuth Redirect Fails
Section titled “OAuth Redirect Fails”- Verify
AUTH_BASE_URLmatches the OAuth app configuration - Check that redirect URI in provider matches
{AUTH_BASE_URL}{API_PREFIX}/v1/auth/callback/{provider} - If using
API_PREFIX, ensure it’s included in OAuth provider redirect URI configuration - Ensure client ID and secret are correct
Password Login Returns Unauthorized
Section titled “Password Login Returns Unauthorized”- In admin mode: check
AUTH_ADMIN_EMAILandAUTH_ADMIN_PASSWORDmatch - In full mode with password disabled: check
AUTH_DISABLE_PASSWORDisn’t set - Verify user exists and password is correct
Database Migration
Section titled “Database Migration”Authentication tables are included in the base schema and auto-applied on server startup.
No manual migration step is required. To check migration status:
# Via admin containerdocker run --rm -e DATABASE_URL="$DATABASE_URL" everruns-admin migrate-infoHealth Check
Section titled “Health Check”The /health endpoint shows current auth mode:
curl http://localhost:9300/health# {"status":"ok","version":"0.2.0","auth_mode":"None"}Security Best Practices
Section titled “Security Best Practices”- Never commit secrets: Use environment variables or secret management
- Rotate JWT secret: Change
AUTH_JWT_SECRETperiodically (invalidates all tokens) - Use HTTPS: Always use HTTPS in production for OAuth callbacks
- Limit OAuth domains: Use
AUTH_GOOGLE_ALLOWED_DOMAINSto restrict access - Monitor API key usage: Track
last_used_atfor suspicious activity - Set token expiration: Use shorter
AUTH_JWT_ACCESS_TOKEN_LIFETIMEfor higher security