Download
depot / docs / authentication

Four ways in

DepotDownloader talks to Steam as either nobody, you-with-a-password, you-with-a-phone, or you-from-last-time. Each has a place. I've run all four across Windows, Linux and my Steam Deck, and this page is the reference for them — plus the parts people rightly worry about: what touches the disk, what Steam Guard does to your workflow, and the one switch that kills every stored session.

01The four methods at a glance

MethodFlagsReachUse it when
AnonymousnoneFree apps, dedicated serversServers, free games — the default when you pass no -username.
Password-username (+ optional -password)Everything your account ownsYour own machine, interactive use.
QR-qrEverything your account ownsAny box you don't fully trust — no password ever typed.
Remembered session-username + -remember-passwordEverything your account ownsRepeat runs, scripts — interactive once, then hands-free.

02Anonymous — the default

Pass no credentials and DepotDownloader logs into Steam's actual anonymous account. That account genuinely owns things: every released dedicated server, free games, demos — the whole anonymous package that powers the server workflow. Two limits to know. The obvious one: nothing paid. The subtle one: anonymous sessions see a deliberately trimmed slice of manifest history — old builds can refuse a request code anonymously yet issue one to a logged-in owner of the same content, which is why "retry with -username" is step one of the 401 diagnostic. The tool itself hints at this in its error output.

03Password login & the Steam Guard dance

The interactive default is the right habit: give it the username only, type the password at the hidden prompt.

$ ./DepotDownloader -app 440 -username you Enter account password for "you": _

A -password flag exists for non-interactive contexts, with the obvious tax: the password lands in your shell history and in the process list while running. The mistake I made the first time was reaching for it in a script; I've since stopped, and recommend you do too. If you're reaching for it in a script, what you actually want is a remembered session (section 05) — one interactive login, zero passwords in scripts. Quirk worth knowing before you blame the tool: passwords longer than 64 characters or containing non-ASCII symbols break the login — a Steam protocol limitation that surfaces as a generic failure.

With Steam Guard on a modern account, submitting the password triggers a confirmation push in the Steam mobile app — approve it there and the login completes. Prefer typing the rotating six-digit code instead (phone-free servers, muscle memory)? That's the -no-mobile flag. Email-Guard accounts get the classic code-by-mail prompt. Whatever the variant, the credential flow underneath is SteamKit2 speaking Steam's own protocol directly to Valve — no third party in the path, the same handshake the official client does. The safety page walks that chain if you want it spelled out.

04QR sign-in — never type the password at all

$ ./DepotDownloader -app 440 -qr

The terminal renders a QR code; scan it with the Steam mobile app, approve, and the session is yours — the machine running DepotDownloader never sees the password. It mirrors the QR login on the official client, and it's the method I'd point anyone to on a machine they don't fully control: a borrowed laptop, a rented server with a desktop session, a friend's PC. Combine it with -remember-password and even the phone is only needed once.

05Staying logged in: what -remember-password actually stores

The flag's name is a small historical lie, and the truth is better: it remembers a refresh token, never the password. After one successful login, subsequent runs with -username you -remember-password reuse the token — no password prompt, no Steam Guard round-trip. That's the backbone of every scripted workflow on this site.

On disk this lives in a small file, account.config, written via .NET's per-user isolated storage. Its contents are exactly three things — login tokens per account, Steam Guard data, and a cache of content-server performance — and notably not your password, which is used once for the handshake and never written. The safety page covers the trust implications; the operational implication is that the token is a bearer credential: anyone with that file can act as your Steam session until it's revoked. Fine on your own machine, a bad idea on shared ones.

Running several instances? You need -loginid Two DepotDownloader processes logging in as the same identity will kick each other off in a LogonSessionReplaced loop. The fix is shipping in the box: give each concurrent instance its own -loginid (any unique 32-bit decimal number). Required reading for anyone parallelizing downloads in CI.

06Revoking everything

Two levers, server-side and local. The server-side one is absolute: in your Steam account's security settings, "deauthorize all devices" — or simply changing your password — instantly invalidates every refresh token ever issued, including DepotDownloader's. That's the lever to pull if a machine with a remembered session is lost, sold or compromised. My rule of thumb: before I hand off or wipe any box that ever ran a remembered session, I deauthorize server-side first and delete the local file second. Locally, deleting account.config from the isolated-storage folder removes the stored tokens from that machine — good hygiene when decommissioning a box, but remember it only cleans that copy; revocation is the server-side lever's job.

07When login fails

Login failures arrive as SteamKit result codes, and the names mostly say it: InvalidPassword (also what an over-long or non-ASCII password produces), TwoFactorCodeMismatch (typo or clock drift on the 2FA code), RateLimitExceeded (too many attempts — wait it out, hammering makes it worse), AccountLogonDenied (email Guard wants its code). The full decoder table for every code lives in login errors, decoded. One disambiguation worth repeating because it lands people on the wrong page: a login that succeeds followed by a 401 on the manifest isn't an authentication problem at all — that's request-code gating, and no amount of re-logging fixes it.