Repository navigation
Authentication
gqlcli supports authentication in both HTTP mode (the standalone CLI) and inline mode (when embedded as a library).
This page focuses on HTTP mode and .gqlcli.json environments. For inline authentication with InlineCommandSet, see Library-Inline-Mode.
The primary way to configure auth for the CLI is via .gqlcli.json environments. Each environment can specify a url and arbitrary HTTP headers:
{
"default": "local",
"environments": {
"local": {
"url": "http://localhost:8080/graphql",
"headers": {
"Authorization": "Bearer dev-token"
}
},
"prod": {
"url": "https://api.example.com/graphql",
"headers": {
"Authorization": "Bearer prod-token"
}
}
}
}At runtime you select an environment with --env:
# Use the default env (from .gqlcli.json)
gqlcli queries
# Explicitly target prod
gqlcli queries --env prodFor more on .gqlcli.json, see Configuration.
Use --header/-H when you need a temporary token, tenant override, trace ID, or preview header without editing .gqlcli.json:
gqlcli query '{ viewer { id } }' --env prod \
-H 'Authorization=Bearer temporary-token' \
-H 'X-Request-Id=debug-123'For persistent credentials, prefer .gqlcli.json or gqlcli login.
The login command runs a GraphQL mutation against an environment, extracts a token from the response, and writes it into that environment's headers in .gqlcli.json.
You provide:
- A login mutation (as a GraphQL string)
- A variables JSON object (e.g. email/password)
- A token path describing where the token lives in the
datapayload
Example:
gqlcli login --env prod \
--mutation 'mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token } }' \
--variables '{"email":"you@example.com","password":"secret"}' \
--token-path login.tokenThis will:
- POST the
Loginmutation to theprodenvironment URL - Parse the response and walk
data.login.token - Store the token in
.gqlcli.jsonunderenvironments.prod.headers.AuthorizationasBearer <token> - Remember the mutation + token path under
environments.prod.login
Afterwards, any gqlcli command that uses --env prod will automatically send the Authorization header.
Once environments.<name>.login is populated, you can omit --mutation and --token-path and just pass new variables:
gqlcli login --env prod --variables '{"email":"you@example.com","password":"secret"}'gqlcli will reuse the saved mutation and token path.
By default, login writes Authorization: Bearer <token>. You can customize this:
gqlcli login --env prod \
--mutation 'mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token } }' \
--variables '{"email":"you@example.com","password":"secret"}' \
--token-path login.token \
--header X-Auth-Token \
--prefix ''This writes X-Auth-Token: <token> instead of Bearer auth.
--save-creds persists the --variables you logged in with (e.g. email/password) under
environments.<name>.login.credentials, in plaintext, in .gqlcli.json:
gqlcli login --env prod \
--mutation 'mutation Login($email: String!, $password: String!) { login(email: $email, password: $password) { token } }' \
--variables '{"email":"you@example.com","password":"secret"}' \
--token-path login.token \
--save-credsWith credentials saved, every subsequent gqlcli command against that environment (query,
mutation, queries, batch, ...) checks the saved token before making its request:
- If the header is missing or empty (deleted via
logout, or a fresh checkout of.gqlcli.json), skip straight to re-login below. - Otherwise decode the token as a JWT (unverified — no signature check, just reading claims)
and read its
expclaim. - If
expis in the past, re-run the saved login mutation with the saved credentials, extract a fresh token from the response, update the header for the current command, and persist the new token back into.gqlcli.json. - If a present token isn't a JWT, has no
expclaim, is still valid, or no credentials were saved — nothing happens; the existing header is used as-is, exactly like before--save-credsexisted.
This is why --token-path/--mutation alone (without --save-creds) do not get automatic
re-login: there is no safe way to re-authenticate without the original credentials.
.gqlcli.json is written with 0600 permissions whenever any environment has saved credentials.
Even so, an attacker who reads the file gets your actual credentials, not just a token — able to
log back in indefinitely, not just reuse one session. Only use --save-creds on a machine you
trust, and prefer per-environment revocable app passwords over your primary account password
where the API supports them.
To remove a saved auth header from an environment:
gqlcli logout --env prodThis deletes the header (by default Authorization) from environments.prod.headers. You can also specify a different header:
gqlcli logout --env prod --header X-Auth-TokenIf the header is not present, logout is a no-op.
Auth configured via .gqlcli.json headers works alongside URL selection:
-
--envselects an environment: URL + headers -
GRAPHQL_URLor--urlcan override just the URL
Precedence for URL selection (highest wins):
--url-
GRAPHQL_URLenv var -
.gqlcli.jsonenvironment URL - Built-in default (
http://localhost:8080/graphql)
Headers come from .gqlcli.json for the selected environment and can be overridden per request with repeatable --header/-H KEY=VALUE flags. CLI-provided headers win over environment headers with the same key.
When embedding gqlcli via InlineCommandSet, you can:
- Use
TokenStoreto persist a JWT at~/.{appName}/token - Add
login,logout, andwhoamicommands viaWithLogin - Use
WithContextEnricheron theInlineExecutorto inject the token into the GraphQL context
See Library-Inline-Mode for a complete example of wiring inline auth.