How to Set Up Dual-Key Authentication in CCX: PROXY_ACCESS_KEY vs ADMIN_ACCESS_KEY
To configure dual-key authentication in CCX, define PROXY_ACCESS_KEY for proxy API endpoints and optionally set ADMIN_ACCESS_KEY for management interfaces, enabling separate security credentials for proxy traffic and administrative operations.
CCX supports a robust dual-key authentication model that isolates proxy API access from administrative control. This architecture allows you to secure your chat completion endpoints (/v1/*) with one credential while protecting the web dashboard and management APIs (/api/*, /admin/*) with another. The implementation resides in the Go backend, specifically within backend-go/internal/config/env.go and backend-go/internal/middleware/auth.go.
Understanding the Dual-Key Architecture
CCX distinguishes between two distinct access keys, each serving a specific security domain.
PROXY_ACCESS_KEY for Proxy APIs
The PROXY_ACCESS_KEY serves as the primary credential for all proxy endpoints, including /v1/* and /v1beta/*. According to the source code in backend-go/internal/config/env.go (lines 59-61), this value is read from the PROXY_ACCESS_KEY environment variable with a default placeholder of your‑proxy‑access‑key. However, the application enforces a critical safety check in backend-go/main.go (lines 552-555): if you attempt to start CCX in production using this default value, the service will fail immediately with a "forbidden default value" error.
ADMIN_ACCESS_KEY for Management
The ADMIN_ACCESS_KEY controls access to the web UI and administrative endpoints under /api/* and /admin/*. As implemented in backend-go/internal/config/env.go (lines 111-116), the GetAdminAccessKey() function returns the configured admin key when set, but gracefully falls back to the PROXY_ACCESS_KEY value if ADMIN_ACCESS_KEY is undefined. This fallback ensures backward compatibility while allowing operators to enable true dual-key authentication by explicitly setting both variables.
Configuration Steps
Setting up dual-key authentication requires specific environment variables and adherence to production security protocols.
Environment Variable Setup
Create or modify your .env file (typically in the project root or backend-go/.env) to include both credentials:
# Required: Proxy access key for /v1/* endpoints
PROXY_ACCESS_KEY=sk-proxy-1234567890abcdef
# Optional: Separate admin key for /api/* and /admin/* endpoints
ADMIN_ACCESS_KEY=sk-admin-0987654321fedcba
When both variables are defined, CCX automatically routes proxy requests through PROXY_ACCESS_KEY validation while requiring ADMIN_ACCESS_KEY for management operations.
Production Safety Requirements
CCX implements strict safeguards against default credentials. In backend-go/main.go (lines 552-555), the application checks whether PROXY_ACCESS_KEY still contains the default value your‑proxy‑access‑key in production mode. If detected, the service exits immediately. You must explicitly override this value with a cryptographically secure key before deploying to production environments.
Authentication Flow Implementation
The dual-key system operates through distinct middleware paths depending on the endpoint type.
Web UI and Management API Authentication
middleware.WebAuthMiddleware handles security for administrative routes. As defined in backend-go/internal/middleware/auth.go (lines 51-55), this middleware intercepts requests to paths starting with /api or /admin, extracts the x-api-key header or Authorization: Bearer <key> token, and validates it against envCfg.GetAdminAccessKey(). If the provided key matches the configured admin key, access is granted; otherwise, the request returns a 401 Unauthorized response.
Proxy API Authentication
Proxy endpoints (/v1/*, /v1beta/*) follow a different pattern. These routes typically pass through initial middleware checks before reaching upstream handlers. In backend-go/internal/utils/headers.go (lines 143-144), the SetAuthenticationHeader function injects the appropriate API key into upstream requests. While the proxy endpoints may appear to "directly放行" (pass through) initial checks, downstream validation ensures that only requests bearing valid PROXY_ACCESS_KEY credentials in their headers succeed.
Practical Code Examples
Environment Configuration
Store your dual keys securely:
PROXY_ACCESS_KEY=sk-proxy-live-abc123xyz789
ADMIN_ACCESS_KEY=sk-admin-secure-def456uvw321
Accessing Proxy Endpoints
Use the proxy key for chat completions:
curl -H "Authorization: Bearer sk-proxy-live-abc123xyz789" \
http://localhost:8000/v1/chat/completions \
-d '{"model":"gpt-4","messages":[{"role":"user","content":"Hello"}]}'
Accessing Management APIs
Use the admin key for configuration endpoints:
curl -H "x-api-key: sk-admin-secure-def456uvw321" \
http://localhost:8000/api/channels/list
Programmatic Key Access
When extending CCX functionality, access keys through the configuration API:
cfg, _ := config.LoadEnvConfig()
proxyKey := cfg.ProxyAccessKey
adminKey := cfg.GetAdminAccessKey() // Returns ADMIN_ACCESS_KEY or falls back to PROXY_ACCESS_KEY
fmt.Println("Proxy key:", proxyKey[:10]+"...")
fmt.Println("Admin key:", adminKey[:10]+"...")
Implementing Custom Middleware
Reuse the built-in authentication logic in custom routes:
r := gin.Default()
envCfg, _ := config.LoadEnvConfig()
r.Use(middleware.WebAuthMiddleware(envCfg, nil))
// Routes defined here automatically respect dual-key authentication
Summary
- Dual-key architecture: CCX supports separate
PROXY_ACCESS_KEYfor proxy APIs andADMIN_ACCESS_KEYfor management interfaces, implemented inbackend-go/internal/config/env.go. - Fallback behavior: If
ADMIN_ACCESS_KEYis unset,GetAdminAccessKey()returns the proxy key, maintaining backward compatibility. - Production enforcement: The application refuses to start in production if
PROXY_ACCESS_KEYretains its default valueyour‑proxy‑access‑key. - Middleware separation:
WebAuthMiddlewarevalidates admin keys for/api/*and/admin/*routes, while proxy endpoints utilize key injection viaSetAuthenticationHeaderinbackend-go/internal/utils/headers.go.
Frequently Asked Questions
What happens if I only set PROXY_ACCESS_KEY and not ADMIN_ACCESS_KEY?
CCX will operate in single-key mode. The GetAdminAccessKey() function in backend-go/internal/config/env.go detects the empty admin key and returns the proxy key value instead. Both proxy endpoints and management interfaces will use the same credential, which simplifies setup but reduces security isolation.
Why does CCX refuse to start with the default PROXY_ACCESS_KEY?
This is a deliberate safety mechanism defined in backend-go/main.go (lines 552-555) to prevent accidental deployment with insecure default credentials. The code explicitly checks if the key equals your‑proxy‑access‑key and exits with an error if found in production environments, forcing operators to generate cryptographically secure keys.
Which HTTP headers should I use for each key?
For proxy endpoints (/v1/*), use Authorization: Bearer <PROXY_ACCESS_KEY>. For management endpoints (/api/*, /admin/*), you can use either x-api-key: <ADMIN_ACCESS_KEY> or Authorization: Bearer <ADMIN_ACCESS_KEY>. The WebAuthMiddleware in backend-go/internal/middleware/auth.go (lines 51-55) accepts both header formats for administrative access.
Can I rotate these keys without restarting CCX?
Based on the current implementation in backend-go/internal/config/env.go, configuration values are loaded at startup via LoadEnvConfig(). To rotate keys, you must update your environment variables and restart the CCX service to reload the configuration. There is no hot-reload mechanism for authentication credentials in the current codebase.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →