Skip to content

Authentication

Wallace Ricardo edited this page Sep 17, 2026 · 4 revisions

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.

HTTP Environments and Headers

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 prod

For more on .gqlcli.json, see Configuration.

One-Off Auth Headers

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.

gqlcli login — HTTP Login Flow

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.

One-Time Setup

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 data payload

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.token

This will:

  1. POST the Login mutation to the prod environment URL
  2. Parse the response and walk data.login.token
  3. Store the token in .gqlcli.json under environments.prod.headers.Authorization as Bearer <token>
  4. Remember the mutation + token path under environments.prod.login

Afterwards, any gqlcli command that uses --env prod will automatically send the Authorization header.

Subsequent Logins

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.

Custom Header Name or Prefix

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.

Automatic Re-Login on Token Expiry

--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-creds

With credentials saved, every subsequent gqlcli command against that environment (query, mutation, queries, batch, ...) checks the saved token before making its request:

  1. If the header is missing or empty (deleted via logout, or a fresh checkout of .gqlcli.json), skip straight to re-login below.
  2. Otherwise decode the token as a JWT (unverified — no signature check, just reading claims) and read its exp claim.
  3. If exp is 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.
  4. If a present token isn't a JWT, has no exp claim, is still valid, or no credentials were saved — nothing happens; the existing header is used as-is, exactly like before --save-creds existed.

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.

gqlcli logout — Clear an Environment Token

To remove a saved auth header from an environment:

gqlcli logout --env prod

This deletes the header (by default Authorization) from environments.prod.headers. You can also specify a different header:

gqlcli logout --env prod --header X-Auth-Token

If the header is not present, logout is a no-op.

Environment Variables and --url

Auth configured via .gqlcli.json headers works alongside URL selection:

  • --env selects an environment: URL + headers
  • GRAPHQL_URL or --url can override just the URL

Precedence for URL selection (highest wins):

  1. --url
  2. GRAPHQL_URL env var
  3. .gqlcli.json environment URL
  4. 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.

Inline Mode Authentication (Library)

When embedding gqlcli via InlineCommandSet, you can:

  • Use TokenStore to persist a JWT at ~/.{appName}/token
  • Add login, logout, and whoami commands via WithLogin
  • Use WithContextEnricher on the InlineExecutor to inject the token into the GraphQL context

See Library-Inline-Mode for a complete example of wiring inline auth.

Clone this wiki locally