Skip to content

Add GOTIFY_LOCALAUTH_ENABLED to disable local authentication - #1027

Closed
MichielMak wants to merge 1 commit into
gotify:masterfrom
MichielMak:michielmak-oidc-disable-local-login
Closed

Add GOTIFY_LOCALAUTH_ENABLED to disable local authentication#1027
MichielMak wants to merge 1 commit into
gotify:masterfrom
MichielMak:michielmak-oidc-disable-local-login

Conversation

@MichielMak

Copy link
Copy Markdown

Closes #1007

Adds an option to turn off Gotify's built-in username/password authentication, so an instance can rely on OIDC only. Implemented following @jmattheis' design in #1007.

The option

GOTIFY_LOCALAUTH_ENABLED (localauth.enabled), default true. Existing installations are unaffected.

When it is false:

  • HTTP basic auth with a username/password is rejected on every endpoint. Client tokens, application tokens and OIDC sessions keep working.
  • POST /auth/local/login returns 403 with a clear error.
  • The default admin user is not created on startup.
  • The WebUI hides the login form and the register button, leaving only the OIDC button.

Gotify refuses to start when both local auth and OIDC are disabled, since that would leave no way to log in.

Why basic auth had to change

Blocking the login endpoint alone is not enough — Gotify also accepts a username and password directly via HTTP basic auth on the regular API endpoints. If only the login route were blocked, someone could keep using local credentials there and the option would be cosmetic.

The fix is a single guard in auth/authentication.go. handleUser() is the only place a password is checked for basic auth, and all six middlewares (RequireAdmin, RequireClient, RequireElevatedClient, RequireApplicationToken, RequireApplicationOrClient, Optional) go through it, so one guard covers them all. handleClient and handleApplication are untouched, which is why token auth is unaffected.

Only two places in the codebase verify a password: this one, and SessionAPI.Login behind the now-403 route. So with the option off there is no remaining password login path. There is a test (TestLocalAuthDisabledRejectsBasicAuth) that fails if the guard is removed.

/gotifyinfo

Gained an additive localauth boolean so the UI knows whether to show the login form. Clients that ignore it are unaffected. docs/spec.json is regenerated with make update-swagger.

Two notes for review

1. Refusing to start. You asked for log.Fatal(). I used the existing futureFatal mechanism in config.Get() instead, which is how other config errors are reported — same result (fatal message, exit 1), but it stays unit-testable, whereas log.Fatal() calls os.Exit. Happy to switch to a literal log.Fatal() if you prefer.

2. Deliberately left alone. Two things are out of scope here, tell me if you want either included:

  • With GOTIFY_REGISTRATION=true and local auth off, POST /user still creates accounts with a password that can never be used. Arguably it should be refused for the same reason the default admin is skipped.
  • An OIDC user can still change their password via the API. It is a dead write today, but it may be intentional so an operator can re-enable local auth later.

The docs repo probably needs a matching entry for the new option.

Testing

go build ./... and go test ./... pass, plus tsc, eslint and prettier on the UI. New tests cover the config parsing and start-up refusal, the 403 on the login route, basic auth rejection, and that no default user is created.

Adds a config option to turn off the built-in username/password
authentication, so a Gotify instance can rely on OIDC only.

When GOTIFY_LOCALAUTH_ENABLED is false:

- username/password credentials are no longer accepted for HTTP basic auth
  on any endpoint, so local credentials cannot be used to bypass the
  disabled login,
- POST /auth/local/login responds with 403,
- the default admin user is not created on startup,
- the WebUI hides the login form and the register button.

Client tokens, application tokens and OIDC sessions are unaffected.

The option defaults to true, so existing installations do not change. Gotify
refuses to start when both local authentication and OIDC are disabled,
because no way to authenticate would remain.

Closes gotify#1007

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@MichielMak
MichielMak requested a review from a team as a code owner August 11, 2026 16:07
@jmattheis

Copy link
Copy Markdown
Member

Hey thanks for the contribution. Another user created a PR for this feature: #1020, and this PR is already reviewed and nearly merged. Therefore, I'll close this one.

@jmattheis jmattheis closed this Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Option to disable local login when OIDC is enabled

2 participants