sign in with an identity provider - degoya/rDownloader GitHub Wiki

Sign in with an identity provider

If you already run an identity provider in your home lab — Authentik, Authelia, Keycloak, Pocket ID or anything else that speaks OpenID Connect — the administrator can sign in there instead of typing rDownloader's own password, with whatever second factor the provider asks for. It is optional and off until you set it up; without it nothing changes.

There is still one administrator. The provider vouches for exactly one account there, the one you link; every other account at the provider is refused. The password stays as the way back.

What you need

  • An external URL. The provider sends your browser back to one fixed address, and rDownloader builds it from the external URL under Settings → Security → Reachability & reverse proxy — never from what a request says. Without an external URL the provider cannot be switched on. See Reverse proxy.
  • A provider reachable over https (plain http only on the same machine), offering the authorization code flow with PKCE (S256) and signing its ID tokens with RS256, PS256, ES256 or EdDSA. rDownloader is a confidential client: it gets a client ID and a client secret.
  • If the provider's certificate comes from your own CA, add the CA under Settings → Network → Proxies & TLS (custom CA) — rDownloader trusts the system's roots plus that.

The redirect URI

Open Settings → Security → Sign-in → Sign in through an identity provider. The card shows the redirect URI to register at the provider, with a copy button. It is always

<external URL>/api/v1/auth/oidc/callback

— https://downloads.example.com/api/v1/auth/oidc/callback, or https://example.com/downloads/api/v1/auth/oidc/callback under a mount point. If you change the external URL later, register the new address at the provider too.

Setting up the provider

Create one client (an application, a provider) for rDownloader at your provider. Whatever it is called there, you need three things back: the issuer, the client ID and the client secret.

Authentik

  1. Applications → Providers → Create → OAuth2/OpenID Provider.
  2. Client type: Confidential. Redirect URIs/Origins: Strict, the redirect URI above.
  3. Signing Key: choose a certificate (the self-signed one is fine). Without one Authentik signs with the client secret (HS256), which rDownloader never accepts.
  4. Create an Application for the provider and note its slug. The issuer is https://auth.example.com/application/o/<slug>/ — with the trailing slash.

Authelia

Add a client under identity_providers.oidc.clients:

- client_id: rdownloader
  client_name: rDownloader
  client_secret: '$pbkdf2-sha512$...'   # the hash; rDownloader gets the plain secret
  public: false
  authorization_policy: two_factor
  require_pkce: true
  pkce_challenge_method: S256
  redirect_uris:
    - https://downloads.example.com/api/v1/auth/oidc/callback
  scopes: [openid, profile, groups]
  grant_types: [authorization_code]
  response_types: [code]
  token_endpoint_auth_method: client_secret_basic

The issuer is Authelia's own address, https://auth.example.com — without a trailing slash.

Keycloak

  1. Clients → Create client, type OpenID Connect, a client ID such as rdownloader.
  2. Client authentication: On, Standard flow: On; nothing else is needed.
  3. Valid redirect URIs: the redirect URI above.
  4. Advanced → Proof Key for Code Exchange Code Challenge Method: S256.
  5. The secret is on the Credentials tab. The issuer is https://keycloak.example.com/realms/<realm>.

For a group condition, add a client scope named groups with a Group Membership mapper (token claim name groups, Full group path off) and assign it to the client.

Pocket ID

  1. OIDC Clients → Add OIDC Client, a name, the redirect URI as Callback URL.
  2. Leave Public client off; PKCE is used either way.
  3. Copy the client ID and secret. The issuer is Pocket ID's own address, https://id.example.com.

Configuring rDownloader

In the card, fill in:

  • Issuer — exactly as the provider states it; the trailing slash is part of it. rDownloader reads <issuer>/.well-known/openid-configuration and refuses a document that names another issuer.
  • Client ID and Client secret. The secret goes into the encrypted secret store and is never shown again; leave the field empty later to keep it.
  • Name on the sign-in button — Authentik, Pocket ID, whatever you recognise.
  • Group claim and Group (optional) — see below.
  • Sign out at the provider too (optional) — see below.

Type the password and Save. The provider is asked for its discovery document right away, so a provider that cannot be used — another issuer, no PKCE, no accepted signing algorithm, not reachable — is refused now, with the reason, and not at your first sign-in.

Linking your account

Saving is not enough: the provider has to show once which account is yours. Type the password and press Link an account. Your browser goes to the provider; sign in there with the account that should be the administrator, and you come back to the card with Account linked. From then on the sign-in screen offers Sign in with . If the session that started the link is signed out, revoked or ended by a password change before the provider answers, nothing is linked.

rDownloader remembers the account by the provider's issuer, the client ID and the account's permanent identifier there — never by its email address or name, which can change and which two providers can hand out alike. Changing the issuer or the client ID therefore ends the link; link again afterwards.

A group condition

With Group claim groups and Group rdownloader-admins, the linked account must also be in that group at the provider — remove it from the group and it can no longer sign in here. A group never makes anybody the administrator on its own. rDownloader asks for the claim's name as a scope, which is what Authelia, Authentik and Pocket ID call it; in Keycloak, name the client scope the same.

Signing out at the provider too

Off by default: signing out of rDownloader then ends only the session here, and your other services stay signed in. Switched on, signing out also sends the browser to the provider's sign-out page; some providers ask before they end their own session.

Signing in

Press Sign in with on the sign-in screen, sign in at the provider, and you land where you were. rDownloader opens its own session, with the limits under Settings → Security → Sessions — not the provider's. Nothing the provider issues is kept. A sign-in through the provider does not ask for rDownloader's authenticator code; the provider's own second factor counts.

If somebody signs in at the provider with another account, the sign-in screen says that this account is not the administrator and names the account the provider reported, so you can tell which one it was.

Switching the password sign-in off

Once the provider works, you can take the password form off the sign-in screen. It has to be done from a session the provider opened — the proof that the round trip works — so sign in through the provider first, then press Switch password sign-in off in the card and type the password.

While it is off:

  • Signing in works through the provider and with a passkey.
  • The password still confirms changes in the settings.
  • Removing the provider, changing its issuer, client ID or group condition, and unlinking are refused, because each would leave you without the provider.

The way back

There is no button that turns the password sign-in back on — a session or an API token could press it. Only the computer rDownloader runs on can:

rdownloader auth password-login on

It works with rDownloader running (it asks the running service over the local control token, which opens nothing else from another machine) and with it stopped (it writes the setting into the database for the next start). Pass --database if your database is not in the default place.

  • Docker: docker exec rdownloader rdownloader auth password-login on
  • Windows (installed): run it from the installation folder, like rdownloader stop.

Use it when the provider is down, its certificate expired, or the client was deleted. The audit log records it as Password sign-in switched.

What rDownloader checks

  • The provider's discovery document names the configured issuer byte for byte, and every address in it is https (or on this machine).
  • The authorization code is redeemed once, with the PKCE verifier and the client secret, and only for the browser that started the sign-in — a sign-in link opened in another browser, or one from the history, is refused.
  • The ID token is signed with RS256, PS256, ES256 or EdDSA by a key the provider publishes, never with none or an HMAC; it names the issuer, this client and this sign-in's nonce, and its times are current within a minute either way.
  • The account is the linked one, and in the group when a group condition is set.
  • A provider that rotates its keys needs no restart; an unknown key makes rDownloader fetch the key set again at most once every five minutes.

When it does not work

The message says What to check
needs the external URL Set the external URL under Security → Reachability & reverse proxy.
speaks for another issuer The issuer field: copy it from the provider's discovery document, trailing slash and all.
does not offer PKCE with S256 Switch PKCE (S256) on for the client at the provider.
signs with no algorithm rDownloader accepts Give the client a signing key (Authentik: Signing Key); HS256 is never accepted.
could not be reached The provider's address from the rDownloader host; a private CA under Network → Proxies & TLS.
did not accept the sign-in code The client ID and secret, and that the redirect URI registered is exactly the one shown.
did not pass the checks The rDownloader host's clock, and that the token is meant for this client. The service log names which check failed.
has expired or was started in another browser Start the sign-in again from the same browser, within ten minutes.
is not the administrator You are signed in at the provider with another account — sign out there first.

Every sign-in through the provider, accepted or refused, is in the audit log (Audit log in the sidebar), by the step that refused it. No code, token or other account's identifier ever is.

Related pages

⚠️ **GitHub.com Fallback** ⚠️