Skip to content

WebUI Authentication

This page describes Torrentarr's WebUI authentication options: token-only, local username/password, and OpenID Connect (OIDC). For a quick overview and links, see WebUI Configuration. For a step-by-step OIDC example with Authentik, see OIDC with Authentik.


Overview

  • AuthDisabled = true (default for existing configs): No login screen. The WebUI and API are protected only by the Token (or are public until Torrentarr has run once and auto-generated a token). Use this when you rely on the API token or a reverse proxy for access control.

  • AuthDisabled = false: Browser users must log in or present the Bearer token. At least one of LocalAuthEnabled or OIDCEnabled should be true so the login page offers a sign-in method. The API token still works for /api/* (Bearer or ?token= on GET). After a successful login (local or OIDC), a session cookie grants access to the WebUI and /web/token returns the API token for the frontend. Use Log out in the app bar (or GET/POST /web/logout) to sign out and return to the login page.

New installs: When Torrentarr runs for the first time and creates the config file (it did not exist before), the generated config has AuthDisabled = false and LocalAuthEnabled = true by default. The user is shown a welcome screen to create an admin username and password before accessing the rest of the WebUI. Existing configs (file already present) are unchanged and keep AuthDisabled = true unless you edit the auth settings.


Settings reference

AuthDisabled

AuthDisabled = true

Type: Boolean Default: true when loading an existing config that does not set this key. When Torrentarr creates a new config file (first run, no config existed), the generated config uses false so new installs require auth and a one-time username/password setup.

When true, authentication is disabled for browser access: no login screen, and protection is via Token only (or public if Token is empty before first run). When false, unauthenticated browser requests to /ui and other protected paths are redirected to the login page unless the request includes a valid Bearer token.


LocalAuthEnabled

LocalAuthEnabled = false

Type: Boolean Default: false

When true (and AuthDisabled is false), users can log in with a username and password via the login page or POST /web/login. Requires Username and PasswordHash to be set. The password is never stored in config in plain form; it is set via the login page "Set password" or POST /web/auth/set-password.


OIDCEnabled

OIDCEnabled = false

Type: Boolean Default: false

When true (and AuthDisabled is false), the login page offers "Sign in with OIDC." Requires a [WebUI.OIDC] block with at least Authority and ClientId (and ClientSecret for confidential clients).


Username

Username = ""

Type: String Default: ""

Single admin username for local auth. Used with PasswordHash when LocalAuthEnabled is true. Set via config or when calling the set-password flow.


PasswordHash

PasswordHash = ""

Type: String Default: ""

BCrypt hash of the local-auth password. Never store a plain password in config.

Setting the password:

  • First-time: Leave PasswordHash empty. Open the login page and use "Set password," or send username and password to POST /web/auth/set-password. Torrentarr hashes the password and writes it to config; if AuthDisabled was true, it will also set AuthDisabled = false and LocalAuthEnabled = true. Note: When PasswordHash is empty, anyone who can reach POST /web/auth/set-password can set the admin password (“first hit wins”). For deployments where the app is network-reachable before the admin visits (e.g. Docker with a published port), use network isolation or a reverse proxy that restricts access until setup is complete.
  • Reset: Set the environment variable TORRENTARR_SETUP_TOKEN to a secret value. Call POST /web/auth/set-password with the same value in the setupToken field along with the new username and password. Torrentarr will update the hash in config.

Legacy AuthMode

Older configs may use a single AuthMode key instead of AuthDisabled, LocalAuthEnabled, and OIDCEnabled. Torrentarr maps them as follows:

AuthMode value AuthDisabled LocalAuthEnabled OIDCEnabled
Disabled true false false
TokenOnly false false false
Local false true false
OIDC false false true
Other true false false

New configs should use the boolean keys. If your config already has AuthMode, you can leave it; the loader will derive the three booleans. When saving config, Torrentarr writes the boolean keys.


[WebUI.OIDC]

When OIDCEnabled is true, add a [WebUI.OIDC] table with your identity provider’s settings.

Key Type Default Description
Authority string "" IdP issuer URL (no trailing slash). Example: https://auth.example.com/application/o/torrentarr.
ClientId string "" OAuth2 client id.
ClientSecret string "" OAuth2 client secret (required for confidential clients).
Scopes string "openid profile" Space-separated scopes.
CallbackPath string "/signin-oidc" Path Torrentarr uses for the OIDC callback. Must match the redirect URI configured at the IdP.
RequireHttpsMetadata boolean true Whether to require HTTPS when fetching IdP metadata. Set false only for local HTTP IdPs (e.g. dev).

When Torrentarr is behind a reverse proxy, the redirect URI the IdP must allow is the public URL, e.g. https://torrentarr.example.com/signin-oidc (same scheme, host, and path as users use to reach Torrentarr).

Running behind a reverse proxy: Login and set-password rate limiting (and any IP-based logging) use the connection’s remote IP. Behind a reverse proxy (e.g. Nginx, Traefik), that is usually the proxy’s IP, so all clients share one “IP” and rate limiting applies globally. Configure forwarded headers so Torrentarr sees the real client IP: enable X-Forwarded-For and X-Forwarded-Proto in your proxy and, if you run Torrentarr with forwarded-headers support, configure ForwardedHeaders (e.g. UseForwardedHeaders) so rate limiting and logs are per client. See your proxy’s documentation for setting these headers.

For a step-by-step example with one IdP, see OIDC with Authentik. For Authentik’s OAuth2/OIDC provider details, see the Authentik OAuth 2.0 provider documentation.


Config examples

Auth disabled (default)

[WebUI]
AuthDisabled = true
LocalAuthEnabled = false
OIDCEnabled = false
Token = ""  # Optional; auto-generated at startup if empty
# ... Host, Port, LiveArr, etc.

Local auth only

[WebUI]
AuthDisabled = false
LocalAuthEnabled = true
OIDCEnabled = false
Username = "admin"
# PasswordHash set via login page or POST /web/auth/set-password
Token = ""
# ...

OIDC only

[WebUI]
AuthDisabled = false
LocalAuthEnabled = false
OIDCEnabled = true
Token = ""
# ...

[WebUI.OIDC]
Authority = "https://auth.example.com/application/o/myapp"
ClientId = "your-client-id"
ClientSecret = "your-client-secret"
Scopes = "openid profile"
CallbackPath = "/signin-oidc"
RequireHttpsMetadata = true

Local + OIDC

[WebUI]
AuthDisabled = false
LocalAuthEnabled = true
OIDCEnabled = true
Username = "admin"
# PasswordHash set via set-password flow
Token = ""
# ...

[WebUI.OIDC]
Authority = "https://auth.example.com/application/o/myapp"
ClientId = "your-client-id"
ClientSecret = "your-client-secret"
Scopes = "openid profile"
CallbackPath = "/signin-oidc"
RequireHttpsMetadata = true

Troubleshooting

401 Unauthorized

  • API (/api/*): Ensure the Token is set (or was auto-generated at startup). Prefer sending it as Authorization: Bearer <token>. The ?token=<token> query parameter is supported for GET requests only; avoid it on untrusted or shared links, as tokens in URLs can leak via Referer, server logs, and browser history.
  • Browser: If AuthDisabled is false, either log in (local or OIDC) or send the Bearer token. For local auth, ensure PasswordHash has been set (via the login page or set-password).
  • Clear browser cache and cookies and check logs for auth-related errors.

OIDC redirect or callback errors

  • Redirect URI: The URI registered at the IdP must match exactly: same scheme, host, and path as Torrentarr’s public URL (e.g. https://torrentarr.example.com/signin-oidc). No trailing slash on the path unless CallbackPath includes it.
  • Authority: Use the IdP issuer URL without a trailing slash (Torrentarr trims it).
  • HTTPS: If RequireHttpsMetadata is true, the IdP’s metadata URL must be HTTPS. For local or HTTP-only IdPs, set RequireHttpsMetadata = false (dev only).

Deployment and security

  • CORS: The WebUI server may allow cross-origin requests (e.g. AllowAnyOrigin in development). In sensitive deployments, restrict CORS to trusted origins via your reverse proxy or application configuration so that only your intended UI origin can call the API.
  • HTTPS: In production, serve Torrentarr over HTTPS (e.g. behind a reverse proxy with TLS). Session cookies use SecurePolicy=SameAsRequest, so they are only sent over HTTPS when the request is HTTPS.

Security pass (release checklist)

Before tagging a release, the following are verified:

  • Login: BCrypt verification runs before username check to avoid timing-based username enumeration; same generic "Unauthorized" on failure. Rate limit: 10 attempts per 15 minutes per IP.
  • Set-password: Setup token compared with constant-time TokenEquals; rate limit: 5 attempts per 15 minutes per IP. No token or password in logs.
  • API token: Bearer and ?token= (GET only) compared with constant-time TokenEquals. Prefer Authorization: Bearer; query token can leak via Referer or server logs.
  • OIDC: Public paths /signin-oidc and /web/auth/oidc/challenge allow GET only; POST to these paths requires authentication. Authority and ClientId are validated before challenge.
  • Cookies: Session cookie is HttpOnly, SameSite=Lax, SecurePolicy=SameAsRequest.
  • Rate limit key: Uses Connection.RemoteIpAddress. When behind a reverse proxy, configure forwarded headers so the client IP is set correctly (see "Running behind a reverse proxy" above).

See also