You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the app container reaches Keycloak via an internal Docker hostname (e.g. keycloak:8180) while the browser reaches it via localhost:8180, Keycloak's --hostname flag causes it to return all endpoint URLs (including token_endpoint and jwks_uri) using the external hostname in every discovery document — even when the document is fetched from the internal URL.
The app then tries to POST to http://localhost:8180/token from inside its container → Connection refused.
Additionally, the openidconnect crate's discover_async enforces that the discovery URL's origin matches the issuer, making it impossible to use separate internal/external hostnames without a workaround.
2. No way to create entries or bootstrap a database through the web UI
The web interface was read-only. Users had to manage the .kdbx file on the desktop and restart the stack to add entries.
Fix
OIDC Docker fix
New optional discovery_url config field: fetch the OIDC discovery document from an internal URL (e.g. http://keycloak:8180/...) while validating tokens against the external issuer (e.g. http://localhost:8180/...).
After fetching, server-to-server endpoint URLs (token_endpoint, jwks_uri, userinfo_endpoint, etc.) are rewritten to use the internal host so the app can reach them. Browser-facing URLs (authorization_endpoint, end_session_endpoint) are left pointing at the external host.
The JWKS is fetched explicitly from the (rewritten) jwks_uri since raw JSON deserialization of the discovery document does not populate the JWKS (openidconnect marks it #[serde(skip)]).
Keycloak test realm updated to include http://localhost:8088/callback_user_auth as a valid redirect URI.
Auto-create database
If the configured .kdbx path does not exist when the user first unlocks the vault, a new empty KeePass 4 database is created with the provided master password and written to that path automatically.
Entry CRUD + save to disk
POST /api/v1/entry — create a new entry in a group
PUT /api/v1/entry — update an existing entry
DELETE /api/v1/entry — delete an entry
POST /api/v1/save_db — flush the current in-memory database back to the .kdbx file (requires re-entering the master password)
Frontend: New Entry inline form in the group panel, Delete button per entry, Save button in the navbar.
Config example
OIDC:
issuer: 'http://localhost:8180/realms/keepass'# Only needed in Docker where app and browser reach the provider via different hostnames:discovery_url: 'http://keycloak:8180/realms/keepass/.well-known/openid-configuration'client_id: 'keepass4web'client_secret: 'secret'
Done across #315 and #326: discovery_url with the endpoint rewriting that keeps the browser facing endpoints on the external host, a database created when none exists, and entry CRUD. #315 also checks that a document fetched from discovery_url declares the configured issuer, so the fetch address stays an internal detail rather than deciding which keys tokens are verified with.
Activity
feat: OIDC Docker split-brain fix, auto-create KDBX, entry CRUD (lixm…
fix: add group id to EntryGroup, password gen and show/hide in new en…
feat: OIDC Docker split-brain fix, auto-create KDBX, entry and group …
feat: OIDC Docker split-brain fix, auto-create KDBX, entry and group …
feat: reach OIDC behind Docker, auto-create the database, entry and g…
lixmal commentedon Aug 27, 2026
Done across #315 and #326: discovery_url with the endpoint rewriting that keeps the browser facing endpoints on the external host, a database created when none exists, and entry CRUD. #315 also checks that a document fetched from discovery_url declares the configured issuer, so the fetch address stays an internal detail rather than deciding which keys tokens are verified with.