auth.json
Understand where agent-qa stores saved LLM credentials and how to create auth.json safely for CI.
auth.json stores saved LLM credentials for named configs in registry.llms.
By default, agent-qa writes it outside the project:
~/.agent-qa/auth.jsonIf XDG_DATA_HOME is set, the path changes to:
$XDG_DATA_HOME/agent-qa/auth.jsonThe file is written with mode 0600 when agent-qa saves credentials.
Credential keys
Entries are keyed by the LLM config name, not by the provider name.
registry:
llms:
- name: codex
provider: openai-subscription
model: gpt-5.5
- name: remote-openai
provider: openai-compatible
model: gpt-5.1
baseURL: https://api.openai.com/v1
use:
llm: codexThe matching auth.json keys are codex and remote-openai.
File shape
{
"remote-openai": {
"type": "api",
"provider": "openai-compatible",
"key": "sk-project-restricted-token"
},
"remote-anthropic": {
"type": "bearer",
"provider": "anthropic-compatible",
"token": "restricted-bearer-token"
},
"codex": {
"type": "oauth",
"provider": "openai-subscription",
"tokens": {
"access": "access-token",
"refresh": "refresh-token",
"expires": 1799999999999,
"accountId": "acct_123"
}
}
}Description: JSON object keyed by LLM config name.
Possible values: api, bearer, and oauth credential objects.
Required: only for LLM configs that need saved credentials.
Default: no saved credentials.
type api
{
"remote-openai": {
"type": "api",
"provider": "openai-compatible",
"key": "sk-project-restricted-token"
}
}Description: API key credential.
Provider constraints: supported for openai-compatible, anthropic-compatible, and gemini.
Required fields: type, provider, and key.
Default: none.
type bearer
{
"remote-anthropic": {
"type": "bearer",
"provider": "anthropic-compatible",
"token": "restricted-bearer-token"
}
}Description: Bearer token credential.
Provider constraints: supported for anthropic-compatible.
Required fields: type, provider, and token.
Default: none.
type oauth
{
"codex": {
"type": "oauth",
"provider": "openai-subscription",
"tokens": {
"access": "access-token",
"refresh": "refresh-token",
"expires": 1799999999999,
"accountId": "acct_123"
}
}
}Description: OAuth tokens from an auth plugin.
Provider constraints: used by subscription auth plugins such as openai-subscription and anthropic-subscription.
Required fields: type, provider, and tokens.
Default: none.
tokens.access
{
"tokens": {
"access": "access-token"
}
}Description: Access token used by the plugin-backed fetch wrapper.
Required: yes for OAuth credentials.
Default: none.
tokens.refresh
{
"tokens": {
"refresh": "refresh-token"
}
}Description: Refresh token used when the plugin refreshes credentials.
Required: yes for OAuth credentials.
Default: none.
tokens.expires
{
"tokens": {
"expires": 1799999999999
}
}Description: Expiration timestamp in milliseconds.
Required: yes for OAuth credentials.
Default: none.
tokens.accountId
{
"tokens": {
"accountId": "acct_123"
}
}Description: Optional account identifier.
Required: no.
Default: not set.
Managing auth locally
Use the CLI or dashboard rather than editing auth.json by hand when you are working locally.
For Anthropic-compatible bearer tokens:
For subscription providers, declare the auth plugin in agent-qa.config.yaml, install it, then authenticate from the dashboard or use the plugin-backed login flow when supported.
CI runtime auth
For CI, create auth.json at runtime from CI secrets. Do not commit it.
mkdir -p "$HOME/.agent-qa"
chmod 700 "$HOME/.agent-qa"
node -e '
const { writeFileSync } = require("node:fs");
const path = `${process.env.HOME}/.agent-qa/auth.json`;
const auth = {
"remote-openai": {
type: "api",
provider: "openai-compatible",
key: process.env.AGENT_QA_OPENAI_API_KEY
}
};
writeFileSync(path, JSON.stringify(auth, null, 2), { mode: 0o600 });
'
npx agent-qa run --suite suites/web-release.suite.yamlWhen CI uses an alternate data directory, set XDG_DATA_HOME and write to $XDG_DATA_HOME/agent-qa/auth.json.
Use CI secret values with the same discipline as test secrets: restricted scopes, disposable credentials when possible, and rotation-ready setup.