opencode
opencode copied to clipboard
[FEATURE]: Header-Based Credential Injection
Feature hasn't been suggested before.
- [x] I have verified this feature I'm about to request hasn't been suggested before.
Describe the enhancement you want to request
Overview
Add the ability to pass LLM provider credentials via HTTP headers when using OpenCode's server mode. This enables dynamic, per-request credential injection without requiring pre-configured API keys.
Requirements
Functional Requirements
FR-1: Header-Based Credential Injection
-
FR-1.1: The server SHALL accept provider credentials via the
X-Provider-AuthHTTP header - FR-1.2: The header value SHALL be a Base64-encoded JSON object
-
FR-1.3: The JSON payload SHALL contain:
-
provider(required): Provider identifier string (e.g., "openrouter", "anthropic", "openai") -
key(required): API key string for the specified provider
-
- FR-1.4: Only ONE provider credential can be sent per request
FR-2: Credential Priority
-
FR-2.1: If
X-Provider-Authheader is present and valid, it SHALL be used (mandatory) - FR-2.2: If header is absent, the system SHALL fall back to existing credential mechanisms (env vars, config files, etc.)
- FR-2.3: If header is present but invalid, the request SHALL fail with an appropriate error
FR-3: Provider Support
- FR-3.1: All currently supported providers MUST work with header-based credentials
-
FR-3.2: Supported providers include (but not limited to):
- OpenAI
- Anthropic (Claude)
- Google (Gemini)
- Azure OpenAI
- OpenRouter
- Groq
- Mistral
- Amazon Bedrock
- Google Vertex AI
- xAI
- Cerebras
- Cohere
- DeepInfra
- Perplexity
- TogetherAI
- Any OpenAI-compatible providers
FR-4: Validation
-
FR-4.1: The system SHALL validate that the
providervalue matches a supported provider name - FR-4.2: Invalid provider names SHALL result in a clear error response
- FR-4.3: The API key itself is NOT validated by OpenCode - provider APIs will validate
Non-Functional Requirements
NFR-1: Availability
- NFR-1.1: Feature SHALL be always enabled when server mode is active
- NFR-1.2: No configuration flag required to enable this feature
NFR-2: Backwards Compatibility
- NFR-2.1: Existing credential mechanisms SHALL continue to work unchanged
- NFR-2.2: Requests without the header SHALL behave exactly as before
NFR-3: Security
- NFR-3.1: Credentials SHALL NOT be logged in plaintext
- NFR-3.2: Base64 encoding provides safe header transport (not encryption)
Header Specification
Header Name
X-Provider-Auth
Header Value Format
Base64-encoded JSON:
Base64({ "provider": "<provider_id>", "key": "<api_key>" })
Example
JSON Payload:
{
"provider": "openrouter",
"key": "sk-or-v1-xxxxxxxxxxxx"
}
Encoded Header:
X-Provider-Auth: eyJwcm92aWRlciI6ICJvcGVucm91dGVyIiwgImtleSI6ICJzay1vci12MS14eHh4eHh4eHh4eHgifQ==
Full Request Example:
curl -X POST http://localhost:3000/api/session/chat \
-H "Content-Type: application/json" \
-H "X-Provider-Auth: eyJwcm92aWRlciI6ICJvcGVucm91dGVyIiwgImtleSI6ICJzay1vci12MS14eHh4eHh4eHh4eHgifQ==" \
-d '{"message": "Hello"}'
Error Handling
| Scenario | HTTP Status | Error Message |
|---|---|---|
| Invalid Base64 encoding | 400 | "Invalid X-Provider-Auth header: malformed Base64" |
| Invalid JSON structure | 400 | "Invalid X-Provider-Auth header: invalid JSON" |
Missing provider field |
400 | "Invalid X-Provider-Auth header: missing provider" |
Missing key field |
400 | "Invalid X-Provider-Auth header: missing key" |
| Unsupported provider | 400 | "Invalid X-Provider-Auth header: unsupported provider '{name}'" |
| Provider API auth failure | 401/403 | Pass through provider's error |
Provider Identifier Mapping
The provider field should accept these identifiers:
| Provider | Identifier(s) |
|---|---|
| OpenAI | openai |
| Anthropic | anthropic |
| Google AI | google |
| Azure OpenAI | azure |
| OpenRouter | openrouter |
| Groq | groq |
| Mistral | mistral |
| Amazon Bedrock | bedrock, amazon-bedrock |
| Google Vertex | vertex, google-vertex |
| xAI | xai |
| Cerebras | cerebras |
| Cohere | cohere |
| DeepInfra | deepinfra |
| Perplexity | perplexity |
| TogetherAI | togetherai, together |