mirror of
https://github.com/coder/coder.git
synced 2026-06-03 13:08:25 +00:00
47b3846bca
## Description Introduces a new `X-Coder-Token` header for authenticating requests from AI Proxy to AI Bridge. Previously, the proxy overwrote the `Authorization` header with the Coder token, which prevented the original authentication headers from flowing through to upstream providers. With this change, AI Proxy sets the Coder token in a separate header, preserving the original `Authorization` and `X-Api-Key` headers. AI Bridge uses this header for authentication and removes it before forwarding requests to upstream providers. For requests that don't come through AI Proxy, AI Bridge continues to use `Authorization` and `X-Api-Key` for authentication. ## Changes * Add `HeaderCoderAuth` constant and update `ExtractAuthToken` to check headers in the following order: `X-Coder-Token` > `Authorization` > `X-Api-Key` * Update AI Proxy to set `X-Coder-Token` instead of overwriting `Authorization` * Remove `X-Coder-Token` in AI Bridge before forwarding to upstream providers * Add tests for header handling and token extraction priority Related to: https://github.com/coder/internal/issues/1235
34 lines
1.1 KiB
Go
34 lines
1.1 KiB
Go
// Package aibridge provides utilities for the AI Bridge feature.
|
|
package aibridge
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
// HeaderCoderAuth is an internal header used to pass the Coder token
|
|
// from AI Proxy to AI Bridge for authentication. This header is stripped
|
|
// by AI Bridge before forwarding requests to upstream providers.
|
|
const HeaderCoderAuth = "X-Coder-Token"
|
|
|
|
// ExtractAuthToken extracts an authorization token from HTTP headers.
|
|
// It checks X-Coder-Token first (set by AI Proxy), then falls back
|
|
// to Authorization header (Bearer token) and X-Api-Key header, which represent
|
|
// the different ways clients authenticate against AI providers.
|
|
// If none are present, an empty string is returned.
|
|
func ExtractAuthToken(header http.Header) string {
|
|
if token := strings.TrimSpace(header.Get(HeaderCoderAuth)); token != "" {
|
|
return token
|
|
}
|
|
if auth := strings.TrimSpace(header.Get("Authorization")); auth != "" {
|
|
fields := strings.Fields(auth)
|
|
if len(fields) == 2 && strings.EqualFold(fields[0], "Bearer") {
|
|
return fields[1]
|
|
}
|
|
}
|
|
if apiKey := strings.TrimSpace(header.Get("X-Api-Key")); apiKey != "" {
|
|
return apiKey
|
|
}
|
|
return ""
|
|
}
|