fix(anthropic): support ANTHROPIC_AUTH_TOKEN as alternative to ANTHROPIC_API_KEY (#853)

* fix(anthropic): support ANTHROPIC_AUTH_TOKEN as alternative to ANTHROPIC_API_KEY

Anthropic SDK supports two mutually exclusive auth methods: apiKey (sent as
x-api-key header) and authToken (sent as Authorization: Bearer header). Detect
either env var during provider detection and credential validation, and pass
authToken to createAnthropic when only ANTHROPIC_AUTH_TOKEN is set.

* docs(anthropic): document ANTHROPIC_AUTH_TOKEN and refine error message

- Add ANTHROPIC_AUTH_TOKEN to env.example and the en/cn/ja provider docs
- Reword the missing-credential error to "Either ... or ..." for readability

---------

Co-authored-by: duyunjie <duyunjie@zhuanzhuan.com>
Co-authored-by: dayuan.jiang <jdy.toh@gmail.com>
This commit is contained in:
waterystone
2026-06-02 18:26:27 +08:00
committed by GitHub
parent 7b6eb39fa5
commit 277ad83552
5 changed files with 60 additions and 9 deletions

View File

@@ -53,6 +53,13 @@ ANTHROPIC_API_KEY=your_api_key
AI_MODEL=claude-sonnet-4-5-20250514 AI_MODEL=claude-sonnet-4-5-20250514
``` ```
或者使用 Bearer 认证令牌(例如通过会下发 OAuth 风格 token 的网关时)。`ANTHROPIC_AUTH_TOKEN` 会作为 `Authorization: Bearer <token>` 头发送,而 `ANTHROPIC_API_KEY` 会作为 `x-api-key` 头发送。两者互斥,只能设置其中之一:
```bash
ANTHROPIC_AUTH_TOKEN=your_auth_token
AI_MODEL=claude-sonnet-4-5-20250514
```
可选的自定义端点: 可选的自定义端点:
```bash ```bash

View File

@@ -68,6 +68,13 @@ ANTHROPIC_API_KEY=your_api_key
AI_MODEL=claude-sonnet-4-5-20250514 AI_MODEL=claude-sonnet-4-5-20250514
``` ```
Or use a Bearer auth token instead of an API key (e.g. when going through a gateway that issues OAuth-style tokens). `ANTHROPIC_AUTH_TOKEN` is sent as `Authorization: Bearer <token>`, while `ANTHROPIC_API_KEY` is sent as `x-api-key`. The two are mutually exclusive — set only one:
```bash
ANTHROPIC_AUTH_TOKEN=your_auth_token
AI_MODEL=claude-sonnet-4-5-20250514
```
Optional custom endpoint: Optional custom endpoint:
```bash ```bash

View File

@@ -53,6 +53,13 @@ ANTHROPIC_API_KEY=your_api_key
AI_MODEL=claude-sonnet-4-5-20250514 AI_MODEL=claude-sonnet-4-5-20250514
``` ```
または、Bearer 認証トークンを使用することもできますOAuth スタイルのトークンを発行するゲートウェイ経由で利用する場合など)。`ANTHROPIC_AUTH_TOKEN``Authorization: Bearer <token>` ヘッダーで送信され、`ANTHROPIC_API_KEY``x-api-key` ヘッダーで送信されます。両者は排他的なので、いずれか一方のみを設定してください:
```bash
ANTHROPIC_AUTH_TOKEN=your_auth_token
AI_MODEL=claude-sonnet-4-5-20250514
```
任意のカスタムエンドポイント: 任意のカスタムエンドポイント:
```bash ```bash

View File

@@ -25,7 +25,8 @@ AI_MODEL=global.anthropic.claude-sonnet-4-5-20250929-v1:0
# OPENAI_REASONING_SUMMARY=detailed # Optional: Override reasoning summary (none/brief/detailed) # OPENAI_REASONING_SUMMARY=detailed # Optional: Override reasoning summary (none/brief/detailed)
# Anthropic (Direct) Configuration # Anthropic (Direct) Configuration
# ANTHROPIC_API_KEY=sk-ant-... # ANTHROPIC_API_KEY=sk-ant-... # Sent as `x-api-key` header
# ANTHROPIC_AUTH_TOKEN= # Alternative to ANTHROPIC_API_KEY; sent as `Authorization: Bearer` header (mutually exclusive)
# ANTHROPIC_BASE_URL=https://your-custom-anthropic/v1 # ANTHROPIC_BASE_URL=https://your-custom-anthropic/v1
# ANTHROPIC_THINKING_TYPE=enabled # Optional: Anthropic extended thinking (enabled) # ANTHROPIC_THINKING_TYPE=enabled # Optional: Anthropic extended thinking (enabled)
# ANTHROPIC_THINKING_BUDGET_TOKENS=12000 # Optional: Budget for extended thinking in tokens # ANTHROPIC_THINKING_BUDGET_TOKENS=12000 # Optional: Budget for extended thinking in tokens

View File

@@ -573,7 +573,15 @@ function detectProvider(): ProviderName | null {
// Skip ollama - it doesn't require credentials // Skip ollama - it doesn't require credentials
continue continue
} }
if (process.env[envVar]) { // Anthropic accepts ANTHROPIC_AUTH_TOKEN (Bearer auth) as alternative to ANTHROPIC_API_KEY
const hasCredential =
provider === "anthropic"
? !!(
process.env.ANTHROPIC_API_KEY ||
process.env.ANTHROPIC_AUTH_TOKEN
)
: !!process.env[envVar]
if (hasCredential) {
// Azure requires additional config (baseURL or resourceName) // Azure requires additional config (baseURL or resourceName)
if (provider === "azure") { if (provider === "azure") {
const hasBaseUrl = !!process.env.AZURE_BASE_URL const hasBaseUrl = !!process.env.AZURE_BASE_URL
@@ -615,13 +623,26 @@ function validateProviderCredentials(
return return
} }
// Use custom env var name if provided, otherwise use default // Anthropic accepts ANTHROPIC_AUTH_TOKEN (Bearer auth) as alternative to ANTHROPIC_API_KEY
const requiredVar = customApiKeyEnv || PROVIDER_ENV_VARS[provider] if (provider === "anthropic" && !customApiKeyEnv) {
if (requiredVar && !process.env[requiredVar]) { const hasCredential = !!(
throw new Error( process.env.ANTHROPIC_API_KEY || process.env.ANTHROPIC_AUTH_TOKEN
`${requiredVar} environment variable is required for ${provider} provider. ` +
`Please set it in your .env.local file.`,
) )
if (!hasCredential) {
throw new Error(
`Either ANTHROPIC_API_KEY or ANTHROPIC_AUTH_TOKEN environment variable is required for anthropic provider. ` +
`Please set one in your .env.local file.`,
)
}
} else {
// Use custom env var name if provided, otherwise use default
const requiredVar = customApiKeyEnv || PROVIDER_ENV_VARS[provider]
if (requiredVar && !process.env[requiredVar]) {
throw new Error(
`${requiredVar} environment variable is required for ${provider} provider. ` +
`Please set it in your .env.local file.`,
)
}
} }
// Azure requires either AZURE_BASE_URL or AZURE_RESOURCE_NAME in addition to API key // Azure requires either AZURE_BASE_URL or AZURE_RESOURCE_NAME in addition to API key
@@ -845,8 +866,16 @@ export function getAIModel(overrides?: ClientOverrides): ModelConfig {
serverBaseUrl, serverBaseUrl,
"https://api.anthropic.com/v1", "https://api.anthropic.com/v1",
) )
// Anthropic supports two auth methods (mutually exclusive):
// - apiKey: sends as `x-api-key` header
// - authToken: sends as `Authorization: Bearer <token>` header
// Prefer apiKey if present (including client overrides); fall back
// to ANTHROPIC_AUTH_TOKEN env var only when no apiKey is available.
const authToken = !apiKey
? process.env.ANTHROPIC_AUTH_TOKEN
: undefined
const customProvider = createAnthropic({ const customProvider = createAnthropic({
apiKey, ...(authToken ? { authToken } : { apiKey }),
baseURL, baseURL,
headers: ANTHROPIC_BETA_HEADERS, headers: ANTHROPIC_BETA_HEADERS,
}) })