mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 06:15:51 +00:00
feat: 添加登录认证增强(workspace key、host guard、auth status)
- hostGuard: workspace API key 仅限 api.anthropic.com,OAuth 限定 subscription plane - saveWorkspaceKey: sk-ant-api03- 前缀校验,安全写入缓存 - AuthPlaneSummary/WorkspaceKeyInput: 登录 UI 组件 - getAuthStatus: 认证状态查询 Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
This commit is contained in:
95
src/services/auth/hostGuard.ts
Normal file
95
src/services/auth/hostGuard.ts
Normal file
@@ -0,0 +1,95 @@
|
||||
/**
|
||||
* Host guard utilities for multi-auth routing.
|
||||
*
|
||||
* These guards enforce that workspace API key requests only go to Anthropic's
|
||||
* API host and that subscription OAuth requests stay on the subscription plane.
|
||||
* This prevents credential leakage to third-party hosts.
|
||||
*
|
||||
* Design: ~/.claude/rules/deep-debug/security.md §2 (read-only investigation first,
|
||||
* then minimal guard at earliest detection point).
|
||||
*/
|
||||
|
||||
import { logError } from '../../utils/log.js'
|
||||
|
||||
/** The canonical Anthropic API host for workspace (non-subscription) endpoints. */
|
||||
const WORKSPACE_API_HOST = 'api.anthropic.com'
|
||||
|
||||
/**
|
||||
* Asserts that `url` points to Anthropic's workspace API host.
|
||||
*
|
||||
* Called before every workspace API key request (agents, vaults, memory_stores,
|
||||
* skills) to prevent the API key from being sent to a third-party host.
|
||||
*
|
||||
* @throws {Error} if the URL does not resolve to api.anthropic.com
|
||||
*/
|
||||
export function assertWorkspaceHost(url: string): void {
|
||||
let hostname: string
|
||||
try {
|
||||
hostname = new URL(url).hostname
|
||||
} catch {
|
||||
throw new Error(
|
||||
`assertWorkspaceHost: invalid URL "${url}". Workspace API key requests must target ${WORKSPACE_API_HOST}.`,
|
||||
)
|
||||
}
|
||||
|
||||
if (hostname !== WORKSPACE_API_HOST) {
|
||||
throw new Error(
|
||||
`assertWorkspaceHost: refusing to send workspace API key to non-Anthropic host "${hostname}". ` +
|
||||
`Workspace API key requests must target ${WORKSPACE_API_HOST}. ` +
|
||||
`If you are using a custom base URL, workspace endpoints are only available on the Anthropic API.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that `url` points to the Anthropic subscription base URL.
|
||||
*
|
||||
* Called before subscription-OAuth requests (schedule, ultrareview, teleport)
|
||||
* to ensure they only target the expected host. Less strict than assertWorkspaceHost —
|
||||
* it still allows the configured BASE_API_URL which may vary in test/staging.
|
||||
*
|
||||
* @throws {Error} if the URL does not resolve to api.anthropic.com
|
||||
*/
|
||||
export function assertSubscriptionBaseUrl(url: string): void {
|
||||
let hostname: string
|
||||
try {
|
||||
hostname = new URL(url).hostname
|
||||
} catch {
|
||||
throw new Error(
|
||||
`assertSubscriptionBaseUrl: invalid URL "${url}". Subscription OAuth requests must target ${WORKSPACE_API_HOST}.`,
|
||||
)
|
||||
}
|
||||
|
||||
if (hostname !== WORKSPACE_API_HOST) {
|
||||
throw new Error(
|
||||
`assertSubscriptionBaseUrl: refusing subscription OAuth request to non-Anthropic host "${hostname}". ` +
|
||||
`Subscription OAuth requests must target ${WORKSPACE_API_HOST}.`,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Warns (but does not throw) when Anthropic API environment variables are set
|
||||
* alongside OpenAI-compat configuration.
|
||||
*
|
||||
* This prevents silent credential confusion when a user has both
|
||||
* ANTHROPIC_API_KEY and OPENAI_API_KEY / CLAUDE_CODE_USE_OPENAI set.
|
||||
* The warning is informational — the calling code decides what to do.
|
||||
*/
|
||||
export function assertNoAnthropicEnvForOpenAI(): void {
|
||||
const hasOpenAIMode =
|
||||
process.env['CLAUDE_CODE_USE_OPENAI'] === '1' ||
|
||||
Boolean(process.env['OPENAI_API_KEY'])
|
||||
const hasAnthropicKey = Boolean(process.env['ANTHROPIC_API_KEY'])
|
||||
|
||||
if (hasOpenAIMode && hasAnthropicKey) {
|
||||
logError(
|
||||
new Error(
|
||||
'assertNoAnthropicEnvForOpenAI: Both ANTHROPIC_API_KEY and OpenAI-compat mode are set. ' +
|
||||
'ANTHROPIC_API_KEY is for Anthropic workspace endpoints (/v1/agents, /v1/vaults, /v1/memory_stores). ' +
|
||||
'OpenAI-compat mode routes /v1/messages to a third-party provider. ' +
|
||||
'These are separate credential planes and will not interfere, but verify this is intentional.',
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user