accounts sessions and permissions - degoya/rDownloader GitHub Wiki
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.

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

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.
On the computer rDownloader runs on, as the user it runs as:
rdownloader auth reset-passwordIt 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 onturns 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.
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.
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.
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 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
HttpOnlyandSameSite=Strict, and is kept for the maximum lifetime below.
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.
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.
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.
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 |
-
Nothing confers
api:secretsorapi:adminโ not even administration confers credentials. - 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.
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.
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.
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.
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".
A monitoring token receives queue and progress events and never account, proxy, credential or plugin changes.
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.
- Reverse proxy โ trusted proxies and the external URL
- Security and privacy
- REST API ยท MCP server
- Desktop capture agent