Authentication
The auth feature (on by default) validates who is calling and resolves the active profile. The
tutorial chapter walks through setup. This page is the reference.
Providers
auth_provider | Use | Credentials accepted |
|---|---|---|
None | Services with no callers to identify | none; set RIVERBASE_AUTH_DISABLED=1 to make it explicit |
MockAuth | Local development and tests | Authorization: MockAuth-<base64url(claims)>, or a session from the local picker |
Keycloak (alias oidc) | Production | Authorization: Bearer <JWT> validated against JWKS, or a session from the OAuth2 flow |
Configuration keys
[riverbase.auth]
auth_provider = "Keycloak"
issuer = "https://idp.example.com/realms/acme"
audience = "acme-api"
accepted_azp = ["acme-web", "acme-cli"]
jwks_ttl_secs = 300
leeway_secs = 30
keycloak_base_url = "https://idp.example.com"
keycloak_realm = "acme"
oauth2_client_id = "acme-web"
# secrets from env: RIVERBASE_AUTH_OAUTH2_CLIENT_SECRET, application_secret_key
session_cookie = "riverbase_session"
cookie_https_only = true
cookie_same_site = "lax"
validate_csrf_token = true
default_signin_redirect_uri = "https://app.example.com/"
safe_redirect_domains = ["app.example.com"]
| Group | Keys |
|---|---|
| Token validation | issuer, audience, accepted_azp, jwks_ttl_secs, leeway_secs, http_timeout_secs |
| Keycloak / OAuth2 | keycloak_base_url, keycloak_realm, oauth2_client_id, oauth2_client_secret, base_path |
| Sessions and cookies | application_secret_key, session_cookie, cookie_https_only, cookie_same_site, validate_csrf_token |
| Redirects | default_callback_uri, default_signin_redirect_uri, default_logout_redirect_uri, safe_redirect_domains |
| Profiles | auth_profile_provider, create_initial_profile, require_realm_role |
| MockAuth | mock_sub, mock_username, mock_email, mock_org_id, mock_org_name, mock_tenant, mock_realm_access, mock_org_codes, [[riverbase.auth.mock_users]] |
Env overrides include RIVERBASE_AUTH_PROVIDER, RIVERBASE_AUTH_ISSUER, RIVERBASE_OIDC_ISSUER,
RIVERBASE_OIDC_AUDIENCE, RIVERBASE_OIDC_DISCOVERY_URL, RIVERBASE_AUTH_KEYCLOAK_REALM,
RIVERBASE_AUTH_OAUTH2_CLIENT_ID, and RIVERBASE_AUTH_OAUTH2_CLIENT_SECRET.
Routes
mount_auth_routes() (JSON, under api_base):
/api/auth/inforesolved authorization context/api/auth/homebrowser bounce to the SPA or sign-in/api/auth/sign-instart the IdP flow/api/auth/profilesprofiles of the signed-in user/api/auth/switch-profile/{profile_id}change the active profilemount_auth() adds the browser OAuth2 flow under /auth (sign-in, callback, sign-out, and the
MockAuth picker when MockAuth is active).
Principal and context
| Type | Holds |
|---|---|
Principal | sub, preferred_username, email, profile-store roles, realm roles, claims |
AuthClaims | Validated token claims |
EngineContext | What engines see: actor, profile, tenant, roles, server-resolved claims |
In a custom handler, principal_from_request(&req) returns the Principal the middleware attached.
Profiles
AuthProfileProvider lists and switches profiles. The built-in implementations are
DefaultAuthProfileProvider, used with Keycloak, and EmptyAuthProfileProvider. Supply your own
with mount_auth_routes_with(Arc::new(provider)). The active profile is resolved from the
X-Profile header, then the token or session, then the stored current profile, then the first active
profile.
Error codes
| Code | Meaning |
|---|---|
AUT-001 | Missing or invalid credentials |
AUT-002 | JWT validation failed |
AUT-146 | Token expired |
AUT-147 | Authorized party (azp) not accepted |
AUT-172 | Wrong scheme for the active provider (for example Bearer under MockAuth) |
AUT-195 | Anonymous request to /auth/info |