Authentication
Ephor delegates authentication to oauth2-proxy, which sits in front of the API and authenticates users against an identity provider. After a successful login, oauth2-proxy forwards identity information to the API via HTTP headers.
How It Works
oauth2-proxy injects the following headers into every authenticated request:
| Header | Description |
|---|---|
X-Forwarded-User | Username or user ID |
X-Forwarded-Email | Email address |
X-Forwarded-Groups | Comma-separated list of group memberships |
X-Forwarded-Preferred-Username | Display name (takes precedence over X-Forwarded-User) |
X-Forwarded-Access-Token | OAuth access token (optional) |
Ephor reads these headers to identify the current user and resolve their role. See Roles and Permissions for how groups map to roles.
Keycloak (OIDC)
A ready-to-use Keycloak stack is included for local development and testing:
docker compose -f docker-compose.oauth2.yml upThis starts Keycloak on port 8180 with a pre-configured ephor realm and the following test users (password for all: password):
| Group | Role | |
|---|---|---|
admin@example.com | ephor-admins | Admin |
lead@example.com | ephor-leads | Lead |
analyst@example.com | ephor-analysts | Analyst |
viewer@example.com | ephor-viewers | Viewer |
The Keycloak admin console is at http://localhost:8180 with credentials admin / admin.
oauth2-proxy is pre-configured to use this Keycloak instance. Group claims are extracted from the JWT token automatically.
GitHub OAuth
To authenticate with GitHub organization teams:
docker compose -f docker-compose.github-oauth2.yml upPrerequisites
- Create a GitHub OAuth App in your organization settings under Developer settings > OAuth Apps.
- Set the callback URL to
http://<your-host>/oauth2/callback. - Create the following teams in your GitHub organization:
| Team slug | Role |
|---|---|
ephor-viewers | Viewer |
ephor-analysts | Analyst |
ephor-leads | Lead |
ephor-admins | Admin |
Required Environment Variables
| Variable | Description |
|---|---|
GITHUB_OAUTH_CLIENT_ID | Client ID from your GitHub OAuth App |
GITHUB_OAUTH_CLIENT_SECRET | Client secret from your GitHub OAuth App |
GITHUB_ORG | GitHub organization name |
GITHUB_TOKEN | Personal access token with read:org scope (for team sync) |
Users must be members of at least one of the configured teams to access Ephor.
Custom Provider
Any identity provider supported by oauth2-proxy works with Ephor. Configure oauth2-proxy for your provider and ensure it forwards the X-Forwarded-User, X-Forwarded-Email, and X-Forwarded-Groups headers.
Group names in X-Forwarded-Groups must match the configured group-to-role mappings. The defaults are ephor-viewers, ephor-analysts, ephor-leads, and ephor-admins.
Refer to the oauth2-proxy provider documentation for setup details.
Development Mode
For local development without an identity provider, authentication can be bypassed entirely by setting AUTH_DEV_ENABLED=true. This injects a configurable development user on every request.
| Variable | Default | Description |
|---|---|---|
AUTH_DEV_USERNAME | dev-user | Username |
AUTH_DEV_EMAIL | dev@localhost | |
AUTH_DEV_GROUPS | ephor-admins,developers,security-team | Comma-separated groups |
AUTH_DEV_DISPLAY_NAME | Development User | Display name |
This mode is enabled by default in the standard docker-compose.yml stack.
WARNING
Never enable AUTH_DEV_ENABLED in production. It bypasses all authentication and grants access to anyone who can reach the application.
User Directory Sync
Ephor can sync users and groups from the identity provider into its local database for user management features. Configure the provider with EPHOR_USER_DIRECTORY_PROVIDER:
| Provider | Sync interval | Description |
|---|---|---|
internal | -- | Users managed in the database (default) |
keycloak | 15 minutes | Sync users and groups from Keycloak |
github | 30 minutes | Sync users and team memberships from GitHub |
none | -- | No user sync or lookup |
See the Configuration Reference for all provider-specific settings.