-
-
Notifications
You must be signed in to change notification settings - Fork 0
Authentication
Trove's default mode is still simple: if OIDC is not configured, the dashboard and read APIs are open. In that mode, keep the server on a trusted LAN, VPN, tailnet, or behind an authenticating reverse proxy.
For native login, Trove supports OpenID Connect (OIDC). This protects the dashboard and read-only APIs without changing the agent ingest path.
When OIDC is enabled, these routes require a valid OIDC browser session or the optional API bearer token:
| Method | Path | Notes |
|---|---|---|
GET |
/ |
Dashboard. Browser users are redirected to the IdP. |
GET |
/api/v1/services |
Service inventory. |
GET |
/api/v1/agents |
Agent heartbeat/status data. |
GET |
/api/v1/events |
State-change event feed. |
GET |
/api/v1/me |
Current auth state used by the dashboard user chip. |
GET |
/metrics |
Prometheus metrics. |
When OIDC is enabled, these routes are registered but stay unauthenticated:
| Method | Path | Why |
|---|---|---|
POST |
/api/v1/report |
Agent ingest uses each agent's own bearer token. |
GET |
/healthz |
Health checks need to work before auth. |
GET |
/oauth2/login |
Starts login. |
GET |
/oauth2/callback |
Receives the IdP callback. |
POST |
/oauth2/logout |
Clears the local session and redirects through IdP logout when available. |
| Variable | Required | Purpose |
|---|---|---|
TROVE_OIDC_ISSUER |
Yes | OIDC issuer/discovery URL, for example https://auth.example.com/application/o/trove/. |
TROVE_OIDC_CLIENT_ID |
Yes | OAuth2/OIDC client ID. |
TROVE_OIDC_CLIENT_SECRET |
Yes | OAuth2/OIDC client secret. |
TROVE_OIDC_REDIRECT_URL |
Yes | Callback URL, for example https://trove.example.com/oauth2/callback. |
TROVE_API_TOKEN |
No | Static bearer token for scripts that cannot use browser OIDC. |
TROVE_OIDC_SESSION_MAX_AGE |
No | Dashboard session lifetime. Default is 8h. Uses Go duration syntax. |
Example:
TROVE_OIDC_ISSUER=https://auth.example.com/application/o/trove/
TROVE_OIDC_CLIENT_ID=trove
TROVE_OIDC_CLIENT_SECRET=OIDC_CLIENT_SECRET_VALUE
TROVE_OIDC_REDIRECT_URL=https://trove.example.com/oauth2/callback
TROVE_API_TOKEN=TROVE_API_TOKEN_VALUE
TROVE_OIDC_SESSION_MAX_AGE=8hThe session cookie is named trove_session. It is signed, HttpOnly, SameSite=Lax, and marked Secure when the configured redirect URL uses HTTPS.
Create an OAuth2/OpenID provider for Trove.
Recommended settings:
| Setting | Value |
|---|---|
| Provider type | OAuth2/OpenID Provider |
| Client type | Confidential |
| Redirect URI | https://trove.example.com/oauth2/callback |
| Scopes |
openid, profile, email
|
Also allow the dashboard root as a post-logout redirect/return URI:
https://trove.example.com/oauth2/callback
https://trove.example.com/
That second URL matters for logout. Without it, the provider may reject Trove's post_logout_redirect_uri or leave the browser stranded after IdP logout.
- A browser requests the dashboard or a read API.
- Trove sees no valid
trove_sessioncookie and redirects to/oauth2/login. - Trove redirects to the provider authorization endpoint.
- The provider redirects back to
/oauth2/callback. - Trove validates the state cookie, exchanges the code, verifies the ID token, and sets a signed session cookie.
- The browser returns to the requested path.
API-style requests get 401 JSON instead of a browser redirect when they send an Authorization header or do not request text/html.
The dashboard logout button submits a real POST form to /oauth2/logout.
On logout, Trove:
- clears the local
trove_sessioncookie; - reads the provider's discovered OIDC
end_session_endpoint; - redirects the browser there with
client_idandpost_logout_redirect_uri; - falls back to the dashboard root if the provider does not publish a valid logout endpoint.
With Authentik, that redirect usually looks like this:
https://auth.example.com/application/o/trove/end-session/?client_id=trove&post_logout_redirect_uri=https%3A%2F%2Ftrove.example.com%2F
This prevents the old "logout boomerang" where Trove cleared its cookie, redirected home, then Authentik silently logged the user straight back in because the upstream SSO session still existed.
Set TROVE_API_TOKEN and pass it as a bearer token:
TROVE_API_TOKEN=TROVE_API_TOKEN_VALUE \
curl --oauth2-bearer "$TROVE_API_TOKEN" \
https://trove.example.com/api/v1/servicesThis token only bypasses OIDC for dashboard/read APIs. Agents still use their own per-agent tokens for POST /api/v1/report.
Unauthenticated browser request should redirect:
curl -I -H 'Accept: text/html' https://trove.example.com/Unauthenticated API request should return 401:
curl -i https://trove.example.com/api/v1/servicesBearer-token API request should return JSON:
TROVE_API_TOKEN=TROVE_API_TOKEN_VALUE \
curl --oauth2-bearer "$TROVE_API_TOKEN" \
https://trove.example.com/api/v1/servicesLogout should redirect to the provider end-session endpoint:
curl -i -X POST https://trove.example.com/oauth2/logoutLook for 303 See Other and a Location header pointing at the provider logout endpoint.
Make sure TROVE_OIDC_REDIRECT_URL exactly matches the provider's redirect URI. Scheme, host, path, and trailing slash behaviour all count.
Check that the provider publishes end_session_endpoint in discovery metadata and allows the dashboard root as a post-logout redirect URI.
curl https://auth.example.com/application/o/trove/.well-known/openid-configurationSend an Authorization header with TROVE_API_TOKEN, or at least send Accept: application/json so Trove treats the request as an API request.
Point health checks at /healthz. It is intentionally unauthenticated.
Check all four required variables together. Trove validates provider discovery at startup, so an unreachable issuer, wrong issuer URL, or invalid discovery document prevents the server from starting with half-working authentication. Check docker compose logs server or journalctl -u trove-server -e for the exact discovery error.