Credentials

How stella stores and finds API keys — the credential chain and the credentials.toml file.

stella finds an API key for your selected provider by checking a fixed list of places in order. It can also save keys in a locked-down file, so you're only asked once.

The credential chain

The credential chain1--api-key flag (needs an explicit --model)2the provider's env var, plus its aliases3settings.json — providers.<id>.api_key4~/.stella/credentials.toml5interactive prompt — saved, so it asks oncekey resolvedfirst hit wins — the rest are skippednothing below the first hit is ever read

For the selected provider, stella checks these places in order. The first one that has a key wins, and stella never reads the ones below it:

  1. --api-key flag. Checked first. You must also pass an explicit --model provider/... — a bare key alone doesn't say which provider it belongs to.
  2. Provider env var. For example ANTHROPIC_API_KEY, plus aliases like GOOGLE_API_KEY for Gemini. A providers.<id>.api_key_env entry in settings.json can rename the main variable. The named variable is then checked first, and the provider's original env var still works as an alias — handy for team key rotation (MY_TEAM_ZAI_KEY) without touching anyone's shell profile. Project dotenv files load into the environment before this step runs, so a repo's .env.local reaches it. An exported shell value always wins over the dotenv value.
  3. settings.jsonproviders.<id>.api_key (an empty string counts as unset; see settings.json).
  4. ~/.stella/credentials.toml — the stored-keys file described below.
  5. Interactive prompt — on a terminal, if you named a provider with --model provider/model_id (for example --model anthropic/claude-fable-5), stella asks for the key and saves it to credentials.toml, so you're only asked once. Running stella with no --model uses auto-detection, which does not prompt — it shows an error telling you to name a provider instead.

Here is each one, the way you'd actually use it:

# 1. The flag — needs an explicit provider, and lands in your shell history.
stella --model anthropic/claude-fable-5 --api-key sk-ant-... run "…"

# 2. The env var — the CI-friendly one.
export ANTHROPIC_API_KEY=sk-ant-...
stella run "…"

# 5. The prompt — name a provider on a TTY and Stella asks once, then stores it.
stella --model anthropic/claude-fable-5 run "…"

Prefer an env var, settings.json, or credentials.toml over --api-key for anything long-lived. A flag value shows up in shell history and in ps output.

credentials.toml

You can store keys in ~/.stella/credentials.toml. It's a flat table, keyed by provider id:

~/.stella/credentials.toml
[credentials]
zai = "sk-..."
anthropic = "sk-ant-..."
openai = "sk-..."
# config-defined provider ids work too — key matches your settings.json entry
together = "..."
  • The file is written with owner-only (0600) permissions — it holds secrets in plain text, the same risk as ~/.ssh/config.

  • Writes are atomic (a temp file is renamed into place), so a reader never sees a half-written file.

  • When you enter a key at the interactive prompt, stella writes it here automatically.

  • The file might arrive some other way: hand-written, restored from a backup, or checked out from a dotfiles repo. If its permissions let your group or anyone else read it, stella warns at startup and reads it anyway:

    ⚠ credentials: ~/.stella/credentials.toml is mode 0644 — its plaintext provider keys
      are readable beyond your account. stella did not create it this way; fix it with
      `chmod 600 ~/.stella/credentials.toml` (the keys were still read for this run).

    stella doesn't refuse to read the file — that would lock you out of your own keys. It also won't silently chmod a file it didn't create. Run the suggested chmod command and the warning goes away.

Managing stored keys

You don't have to edit the file by hand. Use stella auth to write to credentials.toml:

stella auth set <provider>

Store or replace a provider's key. If you skip both --key and --stdin, it asks for the key with hidden input. This is the safest way to run it.

stella auth set <provider> --stdin

Read the key from standard input, one line, trimmed. Good for scripts — it keeps the secret out of your shell history and ps.

stella auth set <provider> --key <KEY>

Pass the key directly on the command line. This is visible in shell history and ps output — use --stdin instead unless you have a reason not to.

stella auth remove <provider>

Drop a provider's stored key from credentials.toml.

stella auth list

List every provider with a stored key. Shows a redacted preview and which link in the chain is actually supplying it.

# Masked prompt — nothing lands in history.
stella auth set anthropic

# From a secret manager, without the value ever becoming an argument.
op read "op://Private/Anthropic/api-key" | stella auth set anthropic --stdin

# Rotate: overwrite in place, then confirm which source now answers.
printf '%s' "$NEW_ZAI_KEY" | stella auth set zai --stdin
stella auth list

# Revoke locally.
stella auth remove openai

stella auth set works the same for a provider id you defined in settings as it does for a built-in one — the key just has to match the id you used in settings.json.

Active key

stella config

This prints the provider, model, and a redacted preview of the active key: a few characters at the start and end, with the middle hidden. You can confirm which key is in use without seeing the full secret. It also shows the base URL, the wire dialect, the workspace root, and which .env* files loaded.

Cloud provider credentials

Some providers need more than one value. The extra values go through the same chain the key does:

Vertex AI

The access token goes through the normal credential chain. So do the project id and the location. Export them, or store them with stella auth set vertex. A missing project id shows a clear error instead of silently falling back to a default.

Key
VERTEX_ACCESS_TOKEN
Project
VERTEX_PROJECT_ID → GOOGLE_CLOUD_PROJECT
Location
VERTEX_LOCATION (default: global)
Amazon Bedrock

SigV4 signing needs the secret key. If you set only AWS_ACCESS_KEY_ID, stella shows a clear error right away instead of letting the request fail later.

Key
AWS_ACCESS_KEY_ID
Secret
AWS_SECRET_ACCESS_KEY
Session
AWS_SESSION_TOKEN (temporary creds only)
Region
AWS_REGION → AWS_DEFAULT_REGION → us-east-1
# Vertex — a short-lived token from gcloud, minted per session.
export VERTEX_ACCESS_TOKEN="$(gcloud auth print-access-token)"
export VERTEX_PROJECT_ID=my-gcp-project
export VERTEX_LOCATION=us-central1
stella --model vertex/gemini-3-pro run "summarize the changes since the last tag"

See Providers & models for the full matrix.