From 4a563def5cf706d797ed0237200ed03a1c94541e Mon Sep 17 00:00:00 2001 From: Stefan Hausotte Date: Wed, 23 Sep 2026 21:37:00 +0200 Subject: [PATCH 1/2] docs: document OAuth2 SSO enforcement and RP-initiated logout Covers the oauth2.enforced and oauth2.auto_redirect settings added in kellnr/kellnr#1384, plus the RP-initiated logout that shipped with them. - Config value cards for both settings, with their TOML keys, environment variables and defaults - A new SSO-Only Login part in the OAuth2/OIDC section listing exactly which paths are refused under enforcement, and noting that Cargo API tokens are unaffected - A warning that admin_group_claim and admin_group_value must be configured before enabling enforcement on a fresh instance, since the local admin can no longer log in and SSO users are otherwise never promoted - The startup behaviour when enforcement is on and the OIDC handler cannot be initialized - Skipping the login page with auto_redirect, and the requires-chain between auto_redirect, enforced and enabled - Logout via end_session_endpoint, including the post-logout redirect URI that has to be registered with the provider - The two new CLI flags in the arguments table - Two feature bullets in the OAuth2 overview --- src/views/DocumentationV6View.vue | 91 +++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/src/views/DocumentationV6View.vue b/src/views/DocumentationV6View.vue index 82f6dff..500de5e 100644 --- a/src/views/DocumentationV6View.vue +++ b/src/views/DocumentationV6View.vue @@ -892,6 +892,12 @@ const mobileNavOpen = ref(false); description="Group name that grants read-only access (e.g., 'kellnr-readonly')." /> + + Toolchain Server @@ -954,6 +960,8 @@ const mobileNavOpen = ref(false);
  • Automatic user provisioning on first login
  • Group-based admin and read-only role assignment
  • Customizable login button text
  • +
  • Optional SSO-only mode that disables password login entirely
  • +
  • RP-initiated logout, ending the session at the identity provider as well
  • @@ -1041,6 +1049,79 @@ const mobileNavOpen = ref(false); read_only_group_value = "kellnr-readonly" + + SSO-Only Login
    + By default, the SSO button sits next to the username and password form, so both login methods stay + available. Set enforced to make SSO the only way in: +
    + + + [oauth2] + enabled = true + enforced = true + + + + With enforcement on, Kellnr rejects every path that relies on a local password: +
      +
    • The login endpoint refuses username and password credentials
    • +
    • Changing your own password and resetting another user's password are refused
    • +
    • Creating a local user is refused, since users come from the identity provider
    • +
    • HTTP Basic authentication against the registry API is refused
    • +
    + The web UI hides the matching forms and buttons, so the password form, the Change Password tab, the + Add User form and the password reset action disappear.
    +
    + Cargo API tokens are unaffected. They are independent of how a user logs in, so + cargo publish and cargo add keep working exactly as before. +
    + + + Configure admin_group_claim and admin_group_value before enabling enforced on a + fresh instance. The local admin account can no longer log in, and without a group mapping no user + provisioned through SSO is ever promoted, which leaves the instance without an administrator. Kellnr + logs a warning at startup when it detects this combination. + + + + Kellnr also refuses to start when enforced is set but the OIDC handler cannot be initialized, + for example because the provider is unreachable or the issuer URL is malformed. Starting anyway would + serve a registry that nobody can log into, so the process exits with status code 1 and logs the reason + instead. + + + + Skipping the Login Page
    + Once SSO is the only login method, the login page holds a single button. Set auto_redirect to + send users straight to the identity provider instead: +
    + + + [oauth2] + enabled = true + enforced = true + auto_redirect = true + + + + auto_redirect requires enforced, and enforced requires enabled. Kellnr + rejects a configuration that sets one without the other, rather than silently disabling all login. + + + + Logout
    + When your provider advertises an end_session_endpoint in its discovery document (RP-Initiated + Logout 1.0), logging out of Kellnr also ends the session at the provider. Kellnr redirects the browser + to that endpoint with the ID token as id_token_hint, and the provider redirects back to Kellnr + afterwards. Add your Kellnr URL to the provider's list of allowed post-logout redirect URIs, otherwise + the provider refuses the redirect: +
      +
    • https://your-kellnr-host/
    • +
    + Providers without an end_session_endpoint only have the local Kellnr session cleared, so the + provider may sign the user straight back in on the next login attempt. +
    + The client secret should be kept confidential. It is recommended to set it via the KELLNR_OAUTH2__CLIENT_SECRET environment variable rather than storing it in the config file. @@ -1474,6 +1555,16 @@ const mobileNavOpen = ref(false); Enable OAuth2/OIDC authentication false + + --oauth2-enforced + Make SSO the only way to log in + false + + + --oauth2-auto-redirect + Skip the login page and redirect to the identity provider + false + From 56e6364fa1ad96d9f2f8b25bc61fadfe541b4503 Mon Sep 17 00:00:00 2001 From: Stefan Hausotte Date: Wed, 23 Sep 2026 22:02:06 +0200 Subject: [PATCH 2/2] docs: note the post-logout redirect prefix and the ID token cookie limit Two gaps in the SSO enforcement docs. The post-logout redirect URI is built from origin.base_url, so a deployment with origin.path set has to register the prefixed URL with its provider. Only the bare host was listed. RP-initiated logout depends on the ID token surviving in a cookie. Browsers cap a single cookie at roughly 4 KB, so a token carrying many group memberships is dropped and the provider session is no longer ended, with the local session still cleared. The page presented provider logout as unconditional whenever end_session_endpoint is advertised. --- src/views/DocumentationV6View.vue | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/views/DocumentationV6View.vue b/src/views/DocumentationV6View.vue index 500de5e..5026370 100644 --- a/src/views/DocumentationV6View.vue +++ b/src/views/DocumentationV6View.vue @@ -1117,11 +1117,20 @@ const mobileNavOpen = ref(false); the provider refuses the redirect:
    • https://your-kellnr-host/
    • +
    • https://your-kellnr-host/your-prefix/ when origin.path is set
    Providers without an end_session_endpoint only have the local Kellnr session cleared, so the provider may sign the user straight back in on the next login attempt. + + Kellnr keeps the ID token in a cookie to pass it back as id_token_hint. Browsers cap a single + cookie at roughly 4 KB, so a very large ID token, typically one carrying many group memberships, is + dropped and the provider session is no longer ended on logout. The local Kellnr session is still + cleared, so the only visible symptom is that the provider signs the user straight back in. If you hit + this, trim the claims your provider puts in the ID token. + + The client secret should be kept confidential. It is recommended to set it via the KELLNR_OAUTH2__CLIENT_SECRET environment variable rather than storing it in the config file.