docs(start): correct headless credential handoff to the SQLite auth store (#131024)

This commit is contained in:
Peter Steinberger
2026-08-27 09:40:27 -07:00
committed by GitHub
parent 59488aa80b
commit ff3cf3de3b
31 changed files with 121 additions and 89 deletions
+20 -20
View File
@@ -323,16 +323,16 @@ troubleshooting, see the main [FAQ](/help/faq).
**No API key found for provider after adding a new agent**
A new agent has an empty auth store — auth is per-agent, stored at:
A new agent can read shared auth profiles without copying them. Its
own profiles live in `~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite`
and override the shared read-through base. See
[Auth credential semantics](/auth-credential-semantics#agent-copy-portability).
```text
~/.openclaw/agents/<agentId>/agent/auth-profiles.json
```
Fix: run `openclaw agents add <id>` and configure auth in the wizard, or
copy only portable static `api_key`/`token` profiles from the main
agent's store. For OAuth, sign in from the new agent when it needs its
own account. See [Multi-Agent Routing](/concepts/multi-agent) for the
Fix: run `openclaw models auth login --provider <providerId> --agent <agentId>`
on the Gateway host when the agent needs its own credentials. You can also
configure auth when creating an agent with `openclaw agents add <id>`.
For OAuth, sign in separately when the agent needs its own account.
See [Multi-Agent Routing](/concepts/multi-agent) for the
full `agentDir` reuse and credential-sharing rules — never reuse
`agentDir` across agents.
@@ -391,14 +391,14 @@ troubleshooting, see the main [FAQ](/help/faq).
**Fix checklist:**
- Confirm where profiles live — current:
`~/.openclaw/agents/<agentId>/agent/auth-profiles.json`; legacy:
`~/.openclaw/agent/*` (migrated by `openclaw doctor`).
- Confirm where profiles live: shared and agent-local SQLite auth stores.
Run `openclaw doctor --fix` if an older install still has
`auth-profiles.json`; it is a migration source, not the runtime store.
- Confirm the Gateway loads your env var. `ANTHROPIC_API_KEY` set only in
your shell won't reach a Gateway run via systemd/launchd — put it in
`~/.openclaw/.env` or enable `env.shellEnv`.
- Confirm you're editing the right agent — multi-agent setups have
multiple `auth-profiles.json` files.
- Confirm you're configuring the right agent — use `--agent <agentId>`
with `openclaw models auth login` to select its local store.
- Run `openclaw models status` to see configured models and provider
auth state.
@@ -445,12 +445,12 @@ Related: [/concepts/oauth](/concepts/oauth) (OAuth flows, token storage, multi-a
<AccordionGroup>
<Accordion title="What is an auth profile?">
A named credential record (OAuth or API key) tied to a provider, stored
at:
```text
~/.openclaw/agents/<agentId>/agent/auth-profiles.json
```
A named credential record (API key, token, or OAuth) tied to a provider,
stored in SQLite. Agent-local profiles in
`~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite` override the
shared read-through base in `~/.openclaw/state/openclaw.sqlite`.
Older installs keep the shared store in the main agent's database until
`openclaw doctor --fix` relocates it.
Inspect saved profiles without dumping secrets: `openclaw models auth
list` (optionally `--provider <id>` or `--json`). See
+10 -5
View File
@@ -462,17 +462,22 @@ First-run Q&A - install, onboard, auth routes, subscriptions, initial failures -
| Path | Purpose |
| ------------------------------------------------------------------ | ------------------------------------------------------------------ |
| `$OPENCLAW_STATE_DIR/openclaw.json` | Main config (JSON5) |
| `$OPENCLAW_STATE_DIR/credentials/oauth.json` | Legacy OAuth import (copied into auth profiles on first use) |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/agent/auth-profiles.json` | Auth profiles (OAuth, API keys, optional `keyRef`/`tokenRef`) |
| `$OPENCLAW_STATE_DIR/credentials/oauth.json` | Legacy OAuth migration source for `openclaw doctor --fix` |
| `$OPENCLAW_STATE_DIR/state/openclaw.sqlite` | Shared SQLite state, including shared auth profiles |
| `$OPENCLAW_STATE_DIR/secrets.json` | Optional file-backed secret payload for `file` SecretRef providers |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/agent/auth.json` | Legacy compatibility file (static `api_key` entries scrubbed) |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/agent/auth.json` | Legacy auth migration source for `openclaw doctor --fix` |
| `$OPENCLAW_STATE_DIR/credentials/` | Provider state (for example `whatsapp/<accountId>/creds.json`) |
| `$OPENCLAW_STATE_DIR/agents/` | Per-agent state (agentDir + legacy/archive session artifacts) |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/agent/openclaw-agent.sqlite` | Per-agent SQLite state, including session rows and transcripts |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/agent/openclaw-agent.sqlite` | Per-agent SQLite state, including local auth profiles, sessions, and transcripts |
| `$OPENCLAW_STATE_DIR/agents/<agentId>/sessions/` | Legacy session migration sources and archive/support artifacts |
Legacy single-agent path `~/.openclaw/agent/*` is migrated by `openclaw doctor`.
Legacy `auth-profiles.json` files are imported by `openclaw doctor --fix`;
new logins write SQLite. Agent-local profiles override the shared read-through
base. Older installs keep that shared store in the main agent's database until
doctor relocates it; see [Auth credential semantics](/auth-credential-semantics#agent-copy-portability).
Your **workspace** (AGENTS.md, memory files, skills, etc.) is separate, configured via `agents.defaults.workspace` (default: `~/.openclaw/workspace`).
</Accordion>
@@ -1571,7 +1576,7 @@ Model Q&A - defaults, selection, aliases, switching, failover, auth profiles - l
<AccordionGroup>
<Accordion title='What is the default model for Anthropic with an API key?'>
Credentials and model selection are separate. Setting `ANTHROPIC_API_KEY` (or storing an Anthropic API key in auth profiles) enables authentication, but the actual default model is whatever you configure in `agents.defaults.model.primary` (for example `anthropic/claude-sonnet-4-6` or `anthropic/claude-opus-4-6`). `No credentials found for profile "anthropic:default"` means the Gateway could not find Anthropic credentials in the expected `auth-profiles.json` for the running agent.
Credentials and model selection are separate. Setting `ANTHROPIC_API_KEY` (or storing an Anthropic API key in auth profiles) enables authentication, but the actual default model is whatever you configure in `agents.defaults.model.primary` (for example `anthropic/claude-sonnet-4-6` or `anthropic/claude-opus-4-6`). `No credentials found for profile "anthropic:default"` means the Gateway could not find Anthropic credentials in the SQLite auth stores available to the running agent.
</Accordion>
</AccordionGroup>
+5 -5
View File
@@ -667,10 +667,10 @@ Live tests discover credentials the same way the CLI does. Practical implication
- If the CLI works, live tests should find the same keys.
- If a live test says "no creds", debug the same way you'd debug `openclaw models list` / model selection.
- Per-agent auth profiles: `~/.openclaw/agents/<agentId>/agent/auth-profiles.json` (this is what "profile keys" means in the live tests)
- Per-agent auth profiles: SQLite credential rows in `~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite` (this is what "profile keys" means in the live tests)
- Config: `~/.openclaw/openclaw.json` (or `OPENCLAW_CONFIG_PATH`)
- Legacy OAuth dir: `~/.openclaw/credentials/` (copied into the staged live home when present, but not the main profile-key store)
- Local live runs copy the active config (with `agents.*.workspace` / `agentDir` overrides stripped) and each agent's `auth-profiles.json` - not the rest of that agent's directory, so `workspace/` and `sandboxes/` data never reaches the staged home - plus the legacy `credentials/` dir and supported external CLI auth files/dirs (`.claude.json`, `.claude/.credentials.json`, `.claude/settings*.json`, `.claude/backups`, `.codex/auth.json`, `.codex/config.toml`, `.gemini`, `.minimax`) into a temp test home.
- Local live runs copy the active config (with `agents.*.workspace` / `agentDir` overrides stripped) and stage each agent's canonical SQLite auth credential/state rows through the auth-store reader/writer APIs, not by copying its database or the rest of its directory. Agent sessions, `workspace/`, and `sandboxes/` data are not staged. The runner also copies the legacy `credentials/` dir and supported external CLI auth files/dirs (`.claude.json`, `.claude/.credentials.json`, `.claude/settings*.json`, `.claude/backups`, `.codex/auth.json`, `.codex/config.toml`, `.gemini`, `.minimax`) into a temp test home.
If you want to rely on env keys, export them before local tests or use the
Docker runners below with an explicit `OPENCLAW_PROFILE_FILE`.
@@ -703,7 +703,7 @@ Docker runners below with an explicit `OPENCLAW_PROFILE_FILE`.
- Scope:
- Enumerates every registered image-generation provider plugin
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in SQLite auth stores do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs each configured provider through the shared image-generation runtime:
- `<provider>:generate`
@@ -751,7 +751,7 @@ request. Plugin dependencies are expected to be present before runtime load.
- Exercises the shared bundled music-generation provider path
- Currently covers `fal`, `google`, `minimax`, and `openrouter`
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in SQLite auth stores do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs both declared runtime modes when available:
- `generate` with prompt-only input
@@ -773,7 +773,7 @@ request. Plugin dependencies are expected to be present before runtime load.
- Defaults to the release-safe smoke path: one text-to-video request per provider, one-second lobster prompt, and a per-provider operation cap from `OPENCLAW_LIVE_VIDEO_GENERATION_TIMEOUT_MS` (`180000` by default)
- Skips FAL by default because provider-side queue latency can dominate release time; pass `OPENCLAW_LIVE_VIDEO_GENERATION_PROVIDERS="fal"` (or clear the skip list) to run it explicitly
- Uses already-exported provider env vars before probing
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in `auth-profiles.json` do not mask real shell credentials
- Uses live/env API keys ahead of stored auth profiles by default, so stale test keys in SQLite auth stores do not mask real shell credentials
- Skips providers with no usable auth/profile/model
- Runs only `generate` by default
- Set `OPENCLAW_LIVE_VIDEO_GENERATION_FULL_MODES=1` to also run declared transform modes when available: