Authentication
Status: Draft, not implemented: no gdt auth command exists yet, and paid assets are refused with exit code 6. Based on the Asset Store’s public OpenAPI document (https://store.godotengine.org/api/v1/openapi.json, API version 1.1.0) read on 2026-10-30. Items marked unverified need an account to confirm.
What the Asset Store API offers
Section titled “What the Asset Store API offers”- One security scheme: an HTTP bearer API key (
Authorization: Bearer <token>). GET /api/v1/auth/introspectionreturns whether the request is authenticated, the method, the user id and name. Use it to validate a token.POST /api/v1/auth/tokencreates a new API key with adescriptionand alifespanin seconds, so keys can expire. It requires being authenticated already, so the first key must come from the website.DELETE /api/v1/auth/tokenrevokes a key.- There is no OAuth or device-code flow in the document.
- Reading assets and their releases (
GET /api/v1/assets/...,GET /api/v1/releases/{publisher}/{asset}/) needs no token. A release hasversion,stable,size,min_godot_version,max_godot_versionand adownload_url. - For a free asset the
download_urlis a presigned storage URL valid for about 10 minutes, and a plain GET works without a token (checked on a free asset). - A release carries no checksum. Assets also expose
price_centandlicense_type. - Unverified: whether a purchased asset’s
download_urlis only returned when the bearer token is sent, and how a paid asset behaves without one. - Unverified: the page where a user creates an API key.
Commands
Section titled “Commands”gdt auth login store # opens the token page, then asks for the token (input hidden)gdt auth login store --with-token < file # read the token from stdin (scripts)gdt auth status # which services are signed in, as which usergdt auth logout store [--revoke] # forget the token; with --revoke also delete it on the serverlogin checks the token with introspection before saving it. The token is never accepted as a command-line argument (it would end up in shell history and in the process list); only through the hidden prompt or stdin.
The group is auth, not addon store, because other services will need credentials too (for example a GitHub token). This follows gh auth and cargo login.
Where the token lives
Section titled “Where the token lives”First match wins when gdt needs it:
- The environment variable
GDT_STORE_TOKEN. This is for CI: set it as the platform’s secret. It is never written to disk. - The operating system’s credential store, through the
keyringcrate: Windows Credential Manager, macOS Keychain, Secret Service (libsecret) on Linux. - A file
credentials.tomlin the config directory with owner-only permissions (0600), used only when no credential store is available (for example a headless Linux box).gdtprints a warning when it does this.
Rules:
- The token is sent only to
store.godotengine.org. It is never sent to the storage host of the presigned download URL (that would also invalidate the signature), nor to any other host. - It is never printed, never logged (also not with
--verbose) and never written togdt.toml,gdt.lockor the project folder. - Prefer tokens with an expiry (
lifespan) and a description such asgdt on <machine>.
Using it in CI
Section titled “Using it in CI”CI platforms hand secrets to a job as environment variables, and GDT_STORE_TOKEN is the first place gdt looks, so a pipeline never needs gdt auth login:
# GitHub Actions- run: gdt sync env: GDT_STORE_TOKEN: ${{ secrets.GDT_STORE_TOKEN }} GH_TOKEN: ${{ secrets.ADDONS_READ_TOKEN }} # only if an addon comes from a private repositorygdt auth login store --with-token is for local scripts and for machines where a credential store exists. A CI runner has none, so using it there would only fall back to a file for no benefit.
Good practice for the token: a dedicated key with an expiry, stored as an encrypted secret, never echoed. Secrets are not passed to workflows triggered by pull requests from forks, so those runs install free assets only.
Private GitHub repositories
Section titled “Private GitHub repositories”A github: source in a private repository needs a token with read access to it. gdt reads GH_TOKEN or GITHUB_TOKEN and sends it only to api.github.com; the repository is fetched as an archive through the API, so no git credentials are involved.
- The
GITHUB_TOKENthat GitHub Actions provides only reaches the repository running the workflow, not other private repositories. For those, create:- a fine-grained personal access token limited to the repositories needed, with the single permission Contents: read, and store it as a secret; or, better for organizations,
- a GitHub App installation token (short-lived), minted in the workflow.
- Public repositories need no token; one only raises the rate limit.
- Other hosts (GitLab, a private server) are reached with
git, using whatever credentials the machine already has (SSH key, credential helper, deploy key).
Behavior
Section titled “Behavior”- Free assets never need a token;
gdt addon addworks signed out. - A paid asset (
price_centabove zero) is refused before anything is downloaded: the error says so, shows the asset’sstore_urland exits with code 6 (implemented).gdtnever buys anything. Using a token to download a purchased asset is not implemented yet. - With a token, it is sent when requesting releases of a paid asset (unverified that this is what the API expects; to be confirmed with an account before implementing).
Independent community project. Not affiliated with, endorsed by or sponsored by the Godot Foundation or the Godot Engine project. “Godot” is a trademark of the Godot Foundation; this site does not use the Godot logo.