accounts sessions and permissions - degoya/rDownloader GitHub Wiki

Accounts, sessions and permissions

rDownloader has one administrator account. There is deliberately no multi-user or role model: separate identities for scripts, assistants and dashboards are handled by tokens, scoped to what they actually need.

This page covers signing in, the second factor, passkeys, sessions and the seven permission areas.

Signing in

The sign-in screen with its single password field

The password

Hashed with Argon2id, minimum 10 characters, set during the setup wizard.

Changing the password

Settings โ†’ Security on its Sign-in tab, beside Sessions and Reachability & reverse proxy: changing the administrator password, with the local access card below

Settings โ†’ Security โ†’ Sign-in โ†’ Administrator password. Enter the Current password, the New password (at least ten characters) and Repeat the new password, then Change password. Do it whenever the password may have ended up somewhere it should not be โ€” a note, a chat, a screenshot.

  • You need the current password. The web interface has no way around it, and setup still cannot be run a second time; a forgotten password is reset on the computer rDownloader runs on (see A forgotten password). Enrol a passkey if you want a second way in, and keep recovery codes if you switch the authenticator code on.
  • A wrong current password is answered exactly like a wrong sign-in, and counts towards the same lockout. The new password's length is checked first, so a refusal never reveals whether the old one was right.
  • Every session ends. The window you made the change in stays signed in with a fresh session; every other browser and device has to sign in again. The confirmation says how many sessions were ended. A change made with an API token ends every session and opens none.
  • The second factor is not asked for again and is left as it is, recovery codes included โ€” it was checked when this session was opened.
  • API tokens keep working, because they do not hang off the password. Anyone who knew the old password could have issued themselves some, so check the token list under Settings โ†’ Clients & API โ†’ API & MCP afterwards and revoke what you do not recognise.

The change is recorded in the audit log as Password changed โ€” who, from where, and how many sessions it ended โ€” whether it succeeded or not. Neither password appears in it.

Disable admin login under Settings โ†’ Security โ†’ Sign-in lets in without a password only a request from this computer's loopback address that no proxy forwarded. Every other machine โ€” on the LAN, through a port mapping, a container or a reverse proxy โ€” still signs in.

A forgotten password

On the computer rDownloader runs on, as the user it runs as:

rdownloader auth reset-password

It prints a new, random password once โ€” copy it, sign in with it, then replace it under Settings โ†’ Security โ†’ Sign-in โ†’ Administrator password. It does not expire and you are not forced to change it, so do. --prompt lets you type the new password instead (twice, not shown; Linux and macOS only), and --database points at a database outside the default place.

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

It works with rDownloader running (it asks the service over the local control token, the same way rdownloader stop does) and with it stopped (it writes the database; the new password counts from the next start).

  • Every session ends, and the lockout you may have run into while guessing is cleared.
  • Passkeys and API tokens keep working. Check the token list afterwards if you suspect someone else.
  • The authenticator code stays switched on. If you lost the phone as well, add --disable-totp: it removes the authenticator app and its recovery codes; passkeys stay.
  • If you switched the password sign-in off for an identity provider, it stays off โ€” the command tells you, and rdownloader auth password-login on turns it back on.

Nothing over the network can do this โ€” no session, no API token, no other computer, nothing behind a reverse proxy. Whoever can open rDownloader's data folder already holds the installation (the password's hash is in the database there), so the data folder is what protects it: keep it readable by the service's user only, which rDownloader sets up itself. The audit log records the reset as Password reset on the host, with whether the service was running โ€” never the password.

The second factor (TOTP)

Optional, off until switched on, under Settings โ†’ Security โ†’ Sign-in. RFC 6238, any authenticator app.

There is nobody to prove your identity to if you are locked out, so:

  • Enrolment happens in two steps. The code does not gate sign-in until one code from it has been accepted once, so a bad scan cannot lock you out.
  • Ten single-use recovery codes are issued at that same moment. They can be re-issued at any time.
  • The key is shown as text beside the QR code, for an authenticator without a camera.
  • The second factor is switched off with the password, not with a code, so a lost device is not permanent.
  • The prompt appears only after the password was accepted, so a wrong password discloses nothing about the account.

The seed lives in the encrypted secret store, never in the database, and never travels in a settings backup.

Passkeys (WebAuthn)

A passkey is an alternative to the password, not an addition to it: the authenticator verifies a PIN or a fingerprint before signing, so one step carries both factors.

Several can be enrolled, named and revoked individually. The sign-in screen offers them above the password field.

They are independent of the second factor in both directions:

  • Enrolling a passkey does not switch the code prompt on.
  • Switching the code prompt off does not delete passkeys.
  • The password keeps working alongside both.

So no single loss is unrecoverable.

A passkey is bound to the external URL configured for the installation, never to a header the caller supplies โ€” that is what makes it unphishable. localhost works unconfigured; an IP address or a domain with no external URL set is refused with the reason and a pointer to the setting. See Reverse proxy.

An identity provider (OpenID Connect)

The administrator can also sign in through Authentik, Authelia, Keycloak, Pocket ID or another OpenID Connect provider โ€” one linked account there, the password kept as the way back, and rdownloader auth password-login on on the machine itself once the password form was switched off. See Sign in with an identity provider.

Sessions

  • Sessions survive a restart.
  • Only a SHA-256 digest of a session is stored, so a copied database or a backup hands over nothing usable.
  • The cookie is HttpOnly and SameSite=Strict, and is kept for the maximum lifetime below.

How long a sign-in lasts

Settings โ†’ Security โ†’ Sessions โ†’ How long a sign-in lasts sets two limits, and a sign-in ends at whichever it reaches first:

Setting Default Range
Without activity โ€” hours without a request 12 hours 1 to 720 (30 days)
Maximum lifetime โ€” hours from signing in, even in the middle of work 30 days 1 to 2160 (90 days)

A shorter value ends the sign-ins already past it at once; a longer one applies from the next sign-in. Changing either needs the administration area and is recorded in the audit log.

When a sign-in has expired, the whole interface says so. The first request refused for want of a session returns you to the sign-in screen with Sign-in expired โ€” Your session has run out or was ended. Sign in again to carry on., rather than each view failing on its own.

Settings โ†’ Security โ†’ Sessions lists every open sign-in with its device, address, when it was last used and when it lapses, with the browser you are sitting at marked as such. Any of them can be ended.

"Sign out everywhere else" ends the rest and keeps yours.

Signing out is in the sidebar footer, beside the connection indicator.

Login rate limiting

The lockout is per address, not per account, so nobody can lock you out by failing on purpose.

A second, gentler counter slows every attempt down while an attack is running โ€” capped at two seconds, and it never refuses anyone. Getting the password right clears both.

An IPv6 client counts by its /64, so a fresh address from the same network is still the same client. An attempt counts as failed until its verdict is in, so attempts sent in parallel cannot slip past a lockout.

A forwarded address is believed only from a proxy that has been named. With nothing configured, the address rDownloader actually sees is the one it uses, whatever the headers say. See Reverse proxy.

Everything here leaves a record

Sign-ins, refused sign-ins, sign-outs, password changes, a password reset on the host, a token being used for the first time, and every token created, revoked or rescoped are written to the audit log โ€” Audit log in the sidebar โ€” with the actor, the address and the outcome.

A refused sign-in records the stage that refused โ€” "password", "password and code", "locked out" โ€” never the value that was wrong. See Diagnostics and maintenance.

Permission areas

Seven areas, one per kind of delegation:

Area Reaches
api:read Queue, progress, post-processing and storage status
api:intake Adding links, files and containers
api:queue Controlling queued and running work
api:config Configuration that carries no credential
api:secrets Stored credentials and the resources built on them
api:admin Plugins, setup, reconnect, power, whole-configuration import and export, clearing the log, the audit log, the statistics, the notification history and the download history, script subscriptions, a notification target's own Apprise program, and the administrator-only settings
api:metrics The Prometheus metrics endpoint, and nothing else

Two properties that are enforced, not merely intended

  1. Nothing confers api:secrets or api:admin โ€” not even administration confers credentials.
  2. Everything that acts can also look: a token that controls the queue can also read it.

The administrator-only settings sit inside the settings document that api:config otherwise reaches: the administrator login switch, the trusted proxies, the executables the service runs and how long a sign-in lasts. Changing one of them needs api:admin as well โ€” over REST and over MCP alike โ€” and a refused attempt is audited.

A script subscription needs api:admin to be created, changed, switched on or off, or run, because it starts a program on this machine. See Subscriptions.

api:metrics is off the ladder

A token for a Prometheus scrape target reaches the metrics endpoint alone. It confers nothing else, nothing but api:* confers it, and api:read does not reach that route.

The read surface is deliberately narrow

So that a token pasted into a status page cannot enumerate the installation, the LinkGrabber, the script and upload destination lists, run histories and the provider table stay out of api:read.

Issuing a token

Settings โ†’ Clients & API โ†’ API & MCP. Choose the areas the token needs from a list that shows how many operations each one reaches, and flags the two โ€” stored credentials and administration โ€” that nothing else confers.

The form opens on reading alone. An unknown permission is refused rather than quietly dropped.

The plaintext is shown once; only a SHA-256 digest is stored. Tokens are revocable and carry a label you choose, and the list records when each one was last used, so a token nothing has touched for months is visible as such.

A token can expire. Expires offers Never โ€” the default โ€” or 7, 30, 90 or 365 days; the same choice appears when you pair a capture agent or the browser extension. An expired token is refused exactly like a revoked one, stays in the list marked Expired until you revoke it, and is replaced by issuing a new one.

A token can be limited. Calls per minute (empty: no limit) caps what an API token may call โ€” REST, MCP and the SABnzbd/qBittorrent APIs together. A call above it is answered 429 with api.token_rate_limited and a Retry-After, and the next minute admits again. Change it with the pencil in the token list; the change is recorded in the audit log as Token limits changed.

Clients that want the header ready to paste โ€” a desktop assistant asking for an environment variable, for instance โ€” are offered the complete Bearer <TOKEN> form.

api:* is the spelling of every area at once. The SABnzbd and qBittorrent compatibility APIs need api:intake, api:queue and api:read โ€” give the download client a token with exactly those three; api:* works there too. A token request that names no area receives api:read.

Changes come only from rDownloader's own pages. A request that changes something is refused with request.cross_site_refused when the browser reports it came from a page of another site โ€” also with the administrator login switched off, where it would otherwise run as the administrator. Scripts and command-line clients are not affected; behind a reverse proxy see Reverse proxy.

Refusals

A refusal names the permission that was missing, as a stable auth.scope_insufficient code.

Presenting a browser-capture token on an API route answers "your credential does not cover this" rather than "please log in".

The event stream follows the same rules

A monitoring token receives queue and progress events and never account, proxy, credential or plugin changes.

Capture tokens versus API tokens

They are strictly separated and cannot be used interchangeably:

Capture token API token
Issued under Settings โ†’ Clients & API โ†’ Desktop or Browser Settings โ†’ Clients & API โ†’ API & MCP
Can push links into the LinkGrabber Yes With api:intake
Can read the capture event stream Yes โ€”
Can pause and resume the whole queue Only if paired with May control the queue (capture:queue), which also lets the tray add everything from the LinkGrabber and game mode hold a pause With api:queue
Can install rDownloader's offered update Only if paired with May install server updates (capture:server_update) With api:admin
Can reach /api/v1 No Yes, within its areas
Can reach /mcp No Yes, with any API area
Can be minted as the other kind No No

Both are random, revocable, and stored only as SHA-256 digests.

Related pages

โš ๏ธ **GitHub.com Fallback** โš ๏ธ