-
-
Notifications
You must be signed in to change notification settings - Fork 0
Usage Authentication
Part of the Usage reference. · ← Previous: Global behavior · Next: Library →
Authenticate with Steam and persist the session.
aurelia login [-u <USERNAME>] [-p <PASSWORD>] [-g <GUARD_CODE>] [-c] [-q] [-o]
aurelia login -w [JSON] # --web-token: store a browser web token (web-only access)
aurelia login -H # --health: report session status (no login)
aurelia login -r # --reconnect: rebuild the daemon's shared session
| Option | Description |
|---|---|
-u, --username <USERNAME> |
Steam account name. Prompted if omitted. |
-p, --password <PASSWORD> |
Account password. Prompted securely if omitted. |
-g, --guard <GUARD_CODE> |
Steam Guard code (email or mobile authenticator), supplied up front. |
-c, --code (alias --pin) |
Enter the Steam Guard code interactively when prompted, instead of approving in the Steam Mobile app. Conflicts with -g. |
-q, --qr |
Log in by scanning a QR code with the Steam Mobile app (no username/password needed). Conflicts with the credential options. |
-o, --openid |
Verify your identity in the browser on the official Steam sign-in page (OpenID). Identity-only, see below. Conflicts with the credential options. |
-w, --web-token [JSON] |
Store a browser web token enabling the web-surface commands (inventory, wallet, market listings) without a client login. Pass the clientjstoken JSON as the value, or omit it to be prompted. See Web-only access. Conflicts with the other login options. |
-H, --health |
Report current session status without logging in (see below). Conflicts with all login options. |
-r, --reconnect |
Rebuild the daemon's shared session from the stored token. Conflicts with all login options. |
If you are already logged in and run login without -u, Aurelia warns on stderr before
the username prompt: Warning: already logged in as <name> — logging in again replaces that session. Logging in again replaces the stored session.
There are three ways to authenticate (plus a browser-based identity check):
-
Password + Steam Guard. Provide
-u/-p(or be prompted). Then, depending on your account: pass-g <CODE>up front, use--code/--pinto type the code when prompted, or (the default) approve the login in your Steam Mobile app. -
--code/--pin. Forces interactive Steam Guard code entry: after you submit credentials, Steam asks for the code (email or authenticator) and you type it in. -
--qr. Renders a QR code in the terminal (with ahttps://s.team/…link as a fallback). Scan it with the Steam Mobile app to approve. No password is entered. -
--openid(identity check only). Opens the official Steam sign-in page (steamcommunity.com) in your browser. After you sign in there, Steam redirects back to a localhost-only callback with a signed OpenID assertion, which Aurelia verifies directly with Steam. Your password is only ever typed on Steam's own page, never in Aurelia.
Why
--openidcan't be a full login. Steam's browser sign-in for third parties is OpenID 2.0 (Valve offers no OAuth2/OpenID Connect endpoint), and it attests identity only: Steam never issues a client session/refresh token through it. So--openidproves who you are (your SteamID64, cross-checked against the stored session's account) but cannot create a session. Commands that need one still require aloginvia password or--qr. For keeping the password out of Aurelia entirely and getting a session,--qris the recommended flow. The browser left signed in by--openidcan, however, hand over a web token, see--web-tokenbelow.
While Valve issues no client tokens to browsers, a signed-in browser session does carry a
short-lived web-audience token: https://steamcommunity.com/chat/clientjstoken returns
{"logged_in":true,"steamid":…,"account_name":…,"token":…} for whoever is signed in on
steamcommunity.com. aurelia login --web-token stores that token (pasted as the flag's
value, or at a prompt), after which the web-surface commands (inventory,
wallet, market listings) work with no client login.
The OpenID success page links to the clientjstoken URL directly, so
login --openid → copy JSON → login --web-token is a complete browser-only setup.
Limits, so there are no surprises:
-
Web surface only. CM-backed commands (library, install, launch, friends, cloud) are
unaffected. They still need a full
login/--qrsession. -
Short-lived (~24 h), no refresh token. When it expires, reload the
clientjstokenpage in the (still signed-in) browser and re-runlogin --web-token. The command prints the expiry when the token carries one. Steam issues both JWT-format tokens (readable expiry) and opaque ones (expiry known only to Steam, shown asunknown). -
Accepted pastes: the full
clientjstokenJSON (recommended), a bare token value, or asteamLoginSecurecookie value (<steamid>||<token>,%7C%7Caccepted). A bare opaque (non-JWT) token carries no identity of its own, so it binds to the stored session's account. With no stored session, paste the full JSON instead. -
Account-safe. The paste's identity is cross-checked (JSON/cookie
steamidvs. a JWT token'ssubclaim) and refused if it belongs to a different account than the stored session. - A full
loginsupersedes the stored web token (a CM session mints fresh web tokens itself), andlogoutdeletes it along with the rest of the session.
For a GUI driver (e.g. Heroic): render login --openid in your own webview. Once signed in,
fetch clientjstoken with the webview's session and feed the JSON to
aurelia login --web-token --json (see the NDJSON table below). Keeping the webview profile
persistent lets you silently re-fetch a fresh token whenever the stored one expires.
aurelia login --web-token # prompts for the pasted JSON
aurelia login --web-token '{"logged_in":true,"steamid":"…","account_name":"…","token":"…"}'
aurelia wallet # now works without a client loginA single log line (shown even without -v) reports which method is being awaited, e.g.
Login method awaited: QR code — scan it with the Steam Mobile app or
Login method awaited: Steam Guard code. The password may also be supplied via the
AURELIA_PASSWORD environment variable.
# Interactive password login (recommended)
aurelia login
# Type the Steam Guard code interactively instead of approving in the app
aurelia login --code # or: aurelia login --pin
# Scan a QR code with the Steam Mobile app (no password)
aurelia login --qr
# Verify your identity on the official Steam page in the browser (no session)
aurelia login --openid
# Fully non-interactive
aurelia login -u myname -p 'secret' -g ABCDE
AURELIA_PASSWORD='secret' aurelia login -u mynameThese two flags inspect or refresh the session rather than logging in, and are aimed at a
front-end that drives the daemon:
-
aurelia login --healthreports whether a session is currently authenticated, without performing a login. When a daemon is in use it reads the daemon's shared session state (no new logon). Standalone it does a one-off live restore check. Output (--json):{ "logged_in", "account", "steam_id", "web_token", "daemon" }, withdaemonindicating whether the answer came from the shared daemon session,web_tokenwhether a browser web token is stored (--web-token).account/steam_idare reported from the persisted session even whenlogged_inis false (e.g. a web-token-only sign-in), so a driver can show who is signed in. A poller can use this to decide whetherloginis needed. -
aurelia login --reconnecttears down the daemon's shared session and re-establishes it from the stored token. Use it if the live connection dropped (e.g. after a network blip) and commands start failing with auth errors. It returns the same status object as--health. Without a running daemon it errors (there is no shared session to rebuild: startaurelia daemonfirst, or just re-run the failing command standalone).
aurelia login --health # human-readable status
aurelia login --health --json # {"logged_in":true,"account":"me","steam_id":...,"daemon":true}
aurelia login --reconnect --json # rebuild the shared session, then report statusWith --json, login becomes a machine-drivable handshake with no TTY prompts: a
driver (e.g. a GUI front-end) supplies credentials via flags/AURELIA_PASSWORD and exchanges
NDJSON lines on stdout/stdin:
-
Password:
aurelia login --json -u <user> -p <pass>. The first line emitted is always{"event":"awaiting_confirmation","message":"…"}, sent before the login attempt blocks, so the driver can immediately tell the user to approve the sign-in on their device (otherwise nothing prints until the attempt completes or times out). Then, if Steam needs a Guard code, a{"event":"guard_required","type":"email"|"device"}line follows. Write the code as a single line to the process's stdin and login retries. Accounts that use mobile-app approval instead emit{"event":"guard_required","type":"device_confirmation"}. -
QR:
aurelia login --qr --jsonstreams{"event":"qr_challenge","url":"https://s.team/…"}(re-emitted whenever Steam rotates the code). Render the URL as a QR and wait. -
OpenID:
aurelia login --openid --jsonemits{"event":"openid_challenge","url":"https://steamcommunity.com/openid/login?…"}, after which the driver opens the URL in a browser (Aurelia does not auto-open one in--jsonmode) and waits while the user signs in on the Steam page. -
Web token:
aurelia login --web-token --json(no value) first checks theAURELIA_WEB_TOKENenvironment variable for theclientjstokenJSON, the recommended driver channel, immune to shell/argv quoting of the embedded JSON quotes. Without it, the command emits{"event":"web_token_required","url":"https://steamcommunity.com/chat/clientjstoken"}and reads the JSON as one line from stdin. Passing the JSON as the flag's value also works where quoting is under control.--web-tokenalways runs locally (never through the daemon), so the env var is reliably visible. -
Result: password and QR logins end with
{"logged_in":true,"account":"<name>"}on success.--openidends with{"openid_verified":true,"steam_id":…,"matches_stored_session":true|false|null,"logged_in":false}:logged_inis alwaysfalsebecause the OpenID flow verifies identity without creating a session (matches_stored_sessionisnullwhen no session is stored). Failures always end with{"error":"…","type":"…"}and a non-zero exit (see Exit codes). Invalid credentials and a missing Guard code areauth_required(exit 77), and Steam's login throttling israte_limited(exit 75).
The complete NDJSON event sequence a driver may observe, in order:
| Event line | When | Driver action |
|---|---|---|
{"event":"awaiting_confirmation","message":"…"} |
Immediately, on password login, before the attempt blocks. | Show the message. Prompt the user to approve on their device if asked. |
{"event":"qr_challenge","url":"…"} |
QR login, re-emitted on each code rotation. | Render url as a QR code and wait. |
{"event":"openid_challenge","url":"…"} |
OpenID identity check, once at the start. | Open url in a browser. The user signs in on the Steam page. |
{"event":"web_token_required","url":"…"} |
--web-token without a value. |
Fetch url with the signed-in browser/webview session, write the JSON as one line to the child's stdin. |
{"event":"guard_required","type":"email"|"device"} |
A typed Steam Guard code is needed. | Read a code from the user, write it as one line to the child's stdin. |
{"event":"guard_required","type":"device_confirmation"} |
The account approves via the Steam Mobile app. | Tell the user to approve in the app. The command then completes or times out. |
{"logged_in":true,"account":"<name>"} |
Terminal: success (password/QR). | Done. The session is persisted. |
{"openid_verified":true,"steam_id":…,"logged_in":false} |
Terminal: success (--openid). |
Identity verified. No session was created. |
{"web_token_saved":true,"steam_id":…,"expires_at":…,"logged_in":…} |
Terminal: success (--web-token). |
Web commands now work until expires_at. logged_in reflects whether a full client session also exists. |
{"error":"…","type":"…"} |
Terminal: failure (non-zero exit). | Surface the error. Branch on type (e.g. wait on rate_limited). |
In --json mode the username/password must be provided up front (no interactive prompt), and
only the Guard code is exchanged over stdin.
The session lives in session.json in the config directory.
Since v0.1.37, it is encrypted automatically, with no password and no prompt:
- On the first successful login, Aurelia creates a random key and stores it in the OS
keyring (Secret Service on Linux, Credential Manager on Windows, Keychain on macOS) under
service
aurelia, accountsession-key.session.jsonis then written as a ChaCha20-Poly1305 envelope keyed by it. - The CLI and the session daemon both read the key from the keyring themselves, so nothing has to be passed between them.
- On Linux the keyring is reached over D-Bus (Secret Service), so a D-Bus session and a
Secret Service provider (GNOME Keyring, KWallet, KeePassXC, …) must be running. The Nix
flake ships
dbusfor this since v0.1.37-2. - Without a reachable keyring (e.g. a headless box with no Secret Service), the session stays
plaintext with owner-only file permissions, and a warning is logged. Set
AURELIA_DISABLE_KEYRING=1to choose this on purpose. - The envelope keeps the account's display name in plaintext, so the "already logged in" warning works without touching the keyring.
- If the keyring entry is lost, the session can't be decrypted. Run
aurelia loginagain.
Upgrading from v0.1.36: the old password-based encryption (
config session-passwordandAURELIA_SESSION_PASSWORD) is gone. Asession.jsonencrypted with a session password can't be read any more. Aurelia tells you to runaurelia loginagain, which re-keys it to the OS keyring.
Clear the stored session.
aurelia logoutUsers
-
Usage
- Global behavior
- Authentication
- Library
- Store & discovery
- Collections
- Install & maintenance
- Launching
- Depots & branches
- Downgrade & pinning
- Steam Cloud
- Steam Workshop
- Friends & chat
- Inventory & market
- Configuration
- Proton & Wine
- Windows Steam runtime
- Luxtorpeda plugin
- umu-launcher plugin
- Launch scripts
- Session daemon
- Files & locations
- Exit codes & logging
- Windows Steam Runtime
Maintainers
Architecture