Authentication

goopdl talks to Google Play as an Android device, so every request needs a token. You have two ways to get one:

Mode You need Best for
Anonymous (default) Nothing Most downloads
Google account A throwaway account, signed in with goopdl auth login Apps the anonymous accounts can't reach, or when the dispenser rate-limits you

goopdl auth status shows which mode is active.

Anonymous (default)

By default goopdl asks Aurora Store's public token dispenser (https://auroraoss.com/api/auth) for an anonymous token. You don't need a Google account.

bash
goopdl auth token                    # arm64 token
goopdl auth token --arch armv7       # token for older 32-bit devices
goopdl auth token --country IN       # register the device with India's MCC/MNC
goopdl auth clear-cache              # delete every cached token and device record

You don't have to run auth token first. Other commands fetch a token when they need one. See auth token for every flag.

Where tokens live

Tokens are cached in goopdl's config directory, the first of these that applies:

  1. $GOOPDL_CONFIG_DIR, if it is an absolute path. ~ is expanded.
  2. $XDG_CONFIG_HOME/goopdl, if XDG_CONFIG_HOME is an absolute path.
  3. ~/.config/goopdl.

A relative path in either variable is ignored, so the cache never ends up in the current directory. On Linux and macOS the directory is created with permissions 0700 and token files are written 0600.

NoteUp to 1.4.x goopdl always used ~/.config/goopdl. If XDG_CONFIG_HOME is set to somewhere else, goopdl now uses $XDG_CONFIG_HOME/goopdl and fetches new tokens the first time. To keep the old location, set GOOPDL_CONFIG_DIR=~/.config/goopdl.

File in that directory Contents
auth-{arch}[-{country}][-profile-{key}].json Token from the last auth token run
token-pool-{arch}[-{country}][-profile-{key}].json Pool of up to 5 tokens used by download, latest, and fast-download
direct-device-{account}-{arch}[-{country}]-profile-{key}.json Google account mode only: the registered device, no token
account.json The saved Google account: email, and the AAS token unless it is in the system keyring

The -profile-{key} part appears when you pin a device with --profile, so each profile keeps its own tokens. goopdl auth logout deletes all of these files. goopdl auth clear-cache deletes all but account.json. goopdl auth token prints the path it saved the token to, and goopdl auth status shows the directory and how many files it holds.

Tokens expire after 50 minutes. How it works explains the pool.

Custom dispenser

Point any command at a self-hosted dispenser with --dispenser / -d:

bash
goopdl auth token -d https://my-dispenser.example.com/api/auth
goopdl download com.whatsapp -d https://my-dispenser.example.com/api/auth

Google account

Sign in once and goopdl skips the dispenser and signs in to Google directly:

bash
goopdl auth login              # opens a browser and saves the account
goopdl download com.whatsapp   # uses it
goopdl auth status             # shows the account in use, never the token
goopdl auth logout             # removes it and every cached token

You can also pass the account in two variables, for example in CI or a container:

bash
export GOOPDL_ACCOUNT_EMAIL="account@example.com"
export GOOPDL_AAS_TOKEN="aas_et/..."
goopdl download com.whatsapp

WarningAn AAS token is a long-lived credential with full Play Store access to the account. Use a throwaway Google account, never your main one. goopdl auth login saves the token in the system keyring, or on disk if there is none; use --print if you'd rather keep it in a secret manager. Changing the account password revokes the token.

Where the account is saved

goopdl auth login keeps the AAS token in the system keyring:

System Keyring
macOS Keychain
Windows Credential Manager
Linux Secret Service over D-Bus (GNOME Keyring, KWallet)

The entry has the service name goopdl and the email as user name. account.json, in the config directory, then holds only the email and "storage": "keyring".

goopdl reads the token back right after saving it. If there is no keyring, or it fails or returns nothing, goopdl warns and writes the token to account.json instead. Expect that on servers, in containers, and over SSH without a desktop session. --insecure-storage skips the keyring and always uses the file:

bash
goopdl auth login                     # keyring, or account.json if there is none
goopdl auth login --insecure-storage  # always account.json

goopdl auth status shows where the token is: Storage : system keyring with the backend's name, or Storage : file. If account.json points to the keyring but the token isn't there, or the keyring can't be opened, commands exit with code 2. Run goopdl auth login again, or use the variables.

NoteThe keyring keeps the token out of backups, synced folders, and copies of your disk. It doesn't protect it from other programs running as you: on Linux and Windows any of them can read it without asking. A token in account.json has neither protection.

About account.json, with or without the token:

What account mode saves

Signing in registers an Android device on the account. So that every command doesn't add another one, goopdl saves the device it registered and reuses it in later runs and in other processes:

File in the config directory Contents
direct-device-{account}-{arch}[-{country}]-profile-{key}.json The device registration: GSF ID, check-in consistency token, and device config token

Getting an AAS token

Pick whichever is easiest:

goopdl auth login saves the account. Add --print to get only the token on stdout instead, for the variables or a secret manager:

bash
TOKEN=$(goopdl auth login --print)

Prompts and messages go to stderr, so only the token lands in TOKEN. goopdl no longer signs in with a password: Google rejects both account passwords and app passwords with BadAuthentication.

bash
goopdl auth login

goopdl opens Chrome, Edge, Chromium, or Brave with a fresh temporary profile. Sign in and select I agree. goopdl captures the email and the one-time oauth_token, closes the browser, deletes the profile, and exchanges the oauth_token for an AAS token.

If goopdl can't find your browser, set GOOPDL_BROWSER to its executable path or use --manual.

Manual sign-in

bash
goopdl auth login --manual

goopdl opens Google EmbeddedSetup in your usual browser. Use a private window if it is signed in to another Google account.

  1. Sign in and select I agree.
  2. Open developer tools (F12).
  3. In Chrome or Edge, go to Application → Cookies → https://accounts.google.com.
  4. Copy the oauth_token cookie. It starts with oauth2_4/.
  5. Back in the terminal, enter the same email and paste the token. The token isn't shown as you paste it.

The oauth_token works once and expires quickly, so paste it right away.

Edit this page on GitHub ↗