Skip to content

API Keys

The default api runtime makes direct HTTP calls to a provider. Set credentials as environment variables.

ProviderEnvironment VariableNotes
Z.ai GLMZ_AI_API_KEYglm-5.3 is the default for the Z.ai route. Uses Z.ai’s Anthropic-compatible Messages API.
Alibaba QwenQWEN_API_KEYUse --model qwen3.8-max or 0SEC_MODEL=qwen3.8-max. Uses Alibaba Model Studio’s OpenAI-compatible endpoint.
Moonshot KimiKIMI_API_KEYUse --model k3. Uses Moonshot’s Anthropic-compatible Coding endpoint.
xAI GrokXAI_API_KEYUse --model grok-4.6. Uses xAI’s OpenAI-compatible endpoint. Override the host with XAI_BASE_URL. Cost note: our price table carries xAI’s short-context rates, so spend on prompts over 200k tokens is under-reported — reconcile against the xAI console.
OpenCode ZenOPENCODE_API_KEYUse --model muse-spark-1.3-contributor-free, or explicitly select opencode/<model-id>. Zen preserves each upstream protocol: GPT/Grok/Muse Spark use Responses, Claude/Qwen use Messages, Gemini uses Google generateContent, and DeepSeek/GLM/Kimi/MiniMax plus the free tier use chat completions. Override the host with OPENCODE_BASE_URL.
ChatGPT Codex0SEC_CHATGPT_ACCESS_TOKEN, 0SEC_CHATGPT_OAUTH_REFRESH_TOKENOAuth subscription auth, not an API key. Both tokens are accepted; the access token is read first, the refresh token is refreshed on demand. This is the one provider that can also authenticate from a file — see ChatGPT Codex authentication below.
DeepSeekDEEPSEEK_API_KEYDirect DeepSeek API access. Endpoint override: DEEPSEEK_BASE_URL.
OpenRouterOPENROUTER_API_KEYAccess to many hosted model families through one API.
AnthropicANTHROPIC_API_KEYDirect access to Claude models. Endpoint override: ANTHROPIC_BASE_URL.
Azure OpenAIAZURE_OPENAI_API_KEYAzure-hosted OpenAI models. See Azure configuration below for additional settings.
OpenAIOPENAI_API_KEYDirect access to GPT models. Endpoint override: OPENAI_BASE_URL.

These eleven are the only providers the runtime detects from the environment. Model families with no direct path (Meta, Mistral) are reachable through OpenRouter. Gemini is also reachable through opencode/gemini-* when OPENCODE_API_KEY is configured.

Set --model <id> or run a command through env 0SEC_MODEL=<id> 0sec <command> when more than one credential is present. 0sec routes recognized families to the configured provider:

  • glm-* / z-ai/* → Z.ai
  • qwen* → Alibaba Qwen
  • k3 / kimi* → Moonshot Kimi
  • grok* / xai/* → xAI Grok
  • muse-spark* / mimo* / ling* / big-pickle / nemotron* / minimax* → OpenCode Zen
  • opencode/<model-id> → OpenCode Zen, using that model family’s documented wire
  • claude* / anthropic/* → Anthropic, then OpenRouter when direct Anthropic credentials are absent
  • gpt-* / o* → ChatGPT Codex subscription when configured, otherwise OpenAI. 0SEC_SELECTED_PROVIDER explicitly pins either provider for the current chat or run.

Without an explicit model, 0sec picks an available fallback. Pin a model rather than relying on ambient credential order.

Terminal window
# Set the provider key.
export Z_AI_API_KEY="..."
export QWEN_API_KEY="..."
# Select its matching model at run time.
0sec scan --target https://api.example.com --scope ./scope.json --model glm-5.3
0sec scan --target https://api.example.com --scope ./scope.json --model qwen3.8-max
# Or use OpenRouter.
export OPENROUTER_API_KEY="sk-or-v1-..."
# ChatGPT Codex subscription auth. `0SEC_*` names begin with a digit, so
# pass the token with `env` rather than a shell `export`.
env 0SEC_CHATGPT_OAUTH_REFRESH_TOKEN="..." \
0sec review ./authorized-repo --runtime api
# Or use 0SEC_CHATGPT_ACCESS_TOKEN; it is read first when both are present.

Add the key as a repository secret and pass it as env on the step. The dedicated composite action is still planned, so today you invoke the CLI through the container image:

- run: |
docker run --rm -v "$PWD:/work" -w /work \
-e OPENROUTER_API_KEY \
ghcr.io/0sec-labs/0sec:latest review .
env:
OPENROUTER_API_KEY: ${{ secrets.OPENROUTER_API_KEY }}

ChatGPT Codex is the only provider that can authenticate from a file instead of an env var. When neither 0SEC_CHATGPT_ACCESS_TOKEN nor 0SEC_CHATGPT_OAUTH_REFRESH_TOKEN is supplied for a run, the runtime reads the tokens from ~/.codex/auth.json (the file codex login writes). Override the path with 0SEC_CHATGPT_AUTH_FILE; an account id comes from 0SEC_CHATGPT_ACCOUNT_ID or the same file. (0SEC_CODEX_AUTH_JSON_PATH is a deprecated spelling — prefer 0SEC_CHATGPT_AUTH_FILE.)

In OpenTUI chat, run /providers (or /connect) and choose ChatGPT Codex. 0sec runs the official codex login --device-auth lifecycle, streams the device instructions in the pane, and reloads ~/.codex/auth.json only after success. It never asks for an OpenAI API key or a pasted OAuth token. Choose OpenAI separately when you want OPENAI_API_KEY direct API access.

Every 0sec run loads that file into the environment before any subcommand runs, so a codex-login file is picked up everywhere — the console /providers view, 0sec doctor, and scans/reviews/audits. An explicit environment value always wins, and a missing or malformed file is ignored quietly. One caveat: the /providers table never checks the filesystem, so anything that reads it without the CLI’s startup load (for example, if you embed it in your own tool) shows “not configured” — a display quirk, not a broken setup.

The console credential store is for API-key providers only. Run /providers to open the chat-owned OpenTUI connection pane, then select a provider to paste its API key. ChatGPT Codex never uses this generic key path: it uses device OAuth and the Codex auth file instead. Each API-key row shows configured via <VAR> or not configured, reflecting the real environment.

Keys are written to credentials.json in the state directory (~/.0sec/ by default), re-tightened to owner-only (0600 file, 0700 dir) on every save.

An explicit environment value always wins over the stored value — the store only fills a variable the environment doesn’t already carry. This keeps “which key did that run use?” answerable when a request 401s or a metered key overspends.

Stored credentials are not encrypted. They’re plaintext, protected only by file permissions. Treat credentials.json like an exported secret in a shell profile.

Picking a model whose provider has no credentials won’t fail at startup — the /model picker lists every model 0sec can price, not every one it can actually call. The request fails later instead (a zero-token turn reporting a missing key). Run /providers first to confirm the provider is configured.

Use OpenRouter to reach a model family with no direct provider credential. It’s not required for Z.ai GLM, Alibaba Qwen, Moonshot Kimi, Anthropic, OpenAI, Azure, OpenCode Zen, or DeepSeek.

Azure is stricter — the API key alone isn’t enough. 0sec needs an Azure base URL and a deployment/model name, either from env vars or reused from ~/.codex/config.toml when Codex is already configured against Azure.

VariableRequiredDescription
AZURE_OPENAI_API_KEYYesYour Azure OpenAI API key
AZURE_OPENAI_BASE_URLYes, unless 0sec can read it from Codex configBase URL for your Azure deployment. For the Responses API this should include /openai/v1.
AZURE_OPENAI_MODELYes, unless 0sec can read it from Codex configAzure deployment/model name (not just a generic model family string)
AZURE_OPENAI_WIRE_APINoWire API format: chat_completions (default) or responses
Terminal window
export AZURE_OPENAI_API_KEY="your-azure-key"
export AZURE_OPENAI_BASE_URL="https://your-resource.openai.azure.com/openai/v1"
export AZURE_OPENAI_MODEL="gpt-4o"
export AZURE_OPENAI_WIRE_API="responses"

If you rely on Codex config, make sure ~/.codex/config.toml points at Azure with a usable base URL and model/deployment. Incomplete Azure config stops with a configuration error rather than a broken scan.

To skip API keys entirely, use CLI runtimes. Claude runs live scans through its subscription loop; Codex and Gemini are source-review oriented:

Terminal window
# Use Claude Code CLI for an authorized live target
0sec scan --target https://api.example.com/chat --scope ./scope.json --runtime claude
# Use Codex CLI for source review
0sec review ./my-repo --runtime codex
# Use Gemini CLI
0sec review ./my-repo --runtime gemini

Source-review CLI runtimes need no API key — the CLI handles auth. Codex live scans use the direct ChatGPT Codex provider, so they need 0SEC_CHATGPT_OAUTH_REFRESH_TOKEN rather than the Codex CLI.