fix: fix checking if provider is authenticated

This commit is contained in:
Nathan Flurry 2026-02-06 19:40:45 -08:00
parent b76d83577a
commit 80ce95f886
13 changed files with 801 additions and 6 deletions

133
docs/credentials.mdx Normal file
View file

@ -0,0 +1,133 @@
---
title: "Credentials"
description: "How sandbox-agent discovers and uses provider credentials."
icon: "key"
---
Sandbox-agent automatically discovers API credentials from environment variables and agent config files. Credentials are used to authenticate with AI providers (Anthropic, OpenAI) when spawning agents.
## Credential sources
Credentials are extracted in priority order. The first valid credential found for each provider is used.
### Environment variables (highest priority)
| Variable | Provider |
|----------|----------|
| `ANTHROPIC_API_KEY` | Anthropic |
| `CLAUDE_API_KEY` | Anthropic (fallback) |
| `OPENAI_API_KEY` | OpenAI |
| `CODEX_API_KEY` | OpenAI (fallback) |
### Agent config files
If no environment variable is set, sandbox-agent checks agent-specific config files:
| Agent | Config path | Provider |
|-------|-------------|----------|
| Amp | `~/.amp/config.json` | Anthropic |
| Claude Code | `~/.claude.json`, `~/.claude/.credentials.json` | Anthropic |
| Codex | `~/.codex/auth.json` | OpenAI |
| OpenCode | `~/.local/share/opencode/auth.json` | Both |
OAuth tokens are supported for Claude Code, Codex, and OpenCode. Expired tokens are automatically skipped.
## Provider requirements by agent
| Agent | Required provider |
|-------|-------------------|
| Claude Code | Anthropic |
| Amp | Anthropic |
| Codex | OpenAI |
| OpenCode | Anthropic or OpenAI |
| Mock | None |
## Error handling behavior
Sandbox-agent uses a **best-effort, fail-forward** approach to credentials:
### Extraction failures are silent
If a config file is missing, unreadable, or malformed, extraction continues to the next source. No errors are thrown. Missing credentials simply mean the provider is marked as unavailable.
```
~/.claude.json missing → try ~/.claude/.credentials.json
~/.claude/.credentials.json missing → try OpenCode config
All sources exhausted → anthropic = None (not an error)
```
### Agents spawn without credential validation
When you send a message to a session, sandbox-agent does **not** pre-validate credentials. The agent process is spawned with whatever credentials were found (or none), and the agent's native error surfaces if authentication fails.
This design:
- Lets you test agent error handling behavior
- Avoids duplicating provider-specific auth validation
- Ensures sandbox-agent faithfully proxies agent behavior
For example, sending a message to Claude Code without Anthropic credentials will spawn the agent, which will then emit its own "ANTHROPIC_API_KEY not set" error through the event stream.
## Checking credential status
### API endpoint
The `GET /v1/agents` endpoint includes a `credentialsAvailable` field for each agent:
```json
{
"agents": [
{
"id": "claude",
"installed": true,
"credentialsAvailable": true,
...
},
{
"id": "codex",
"installed": true,
"credentialsAvailable": false,
...
}
]
}
```
### TypeScript SDK
```typescript
const { agents } = await client.listAgents();
for (const agent of agents) {
console.log(`${agent.id}: ${agent.credentialsAvailable ? 'authenticated' : 'no credentials'}`);
}
```
### OpenCode compatibility
The `/opencode/provider` endpoint returns a `connected` array listing providers with valid credentials:
```json
{
"all": [...],
"connected": ["claude", "mock"]
}
```
## Passing credentials explicitly
You can override auto-discovered credentials by setting environment variables before starting sandbox-agent:
```bash
export ANTHROPIC_API_KEY=sk-ant-...
export OPENAI_API_KEY=sk-...
sandbox-agent daemon start
```
Or when using the SDK in embedded mode:
```typescript
const client = await SandboxAgentClient.spawn({
env: {
ANTHROPIC_API_KEY: process.env.MY_ANTHROPIC_KEY,
},
});
```

View file

@ -70,6 +70,7 @@
"cli",
"inspector",
"session-transcript-schema",
"credentials",
"gigacode",
{
"group": "AI",

View file

@ -805,12 +805,17 @@
"required": [
"id",
"installed",
"credentialsAvailable",
"capabilities"
],
"properties": {
"capabilities": {
"$ref": "#/components/schemas/AgentCapabilities"
},
"credentialsAvailable": {
"type": "boolean",
"description": "Whether the agent's required provider credentials are available"
},
"id": {
"type": "string"
},