# What is PROXYACCESSKEY in CCX? Secure Proxy Authentication Explained

> Understand PROXYACCESSKEY in CCX. Learn how this environment variable secures your proxy layer and authorizes requests to downstream AI endpoints using API keys and bearer tokens.

- Repository: [Benedict King/ccx](https://github.com/BenedictKing/ccx)
- Tags: how-to-guide
- Published: 2026-05-29

---

**PROXYACCESSKEY is the environment variable that acts as the master API key for the CCX proxy layer, authorizing requests via the `x-api-key` header or `Authorization: Bearer` token before they reach downstream AI endpoints.**

CCX (BenedictKing/ccx) is an open-source AI gateway that routes requests to various language models while centralizing authentication. Unlike complex OAuth flows, CCX uses a single, configurable secret—`PROXYACCESSKEY`—to protect its public HTTP endpoints. This lightweight mechanism ensures that only clients possessing the correct key can traverse the proxy and access the underlying AI APIs.

## Where PROXYACCESSKEY is Defined

In the CCX codebase, the proxy access key is declared in the backend environment configuration files.

- **Example configuration file**: `backend-go/.env.example`
- **Runtime configuration**: `backend-go/.env` (created by copying the example)

The variable is read at application startup using Go's `os.Getenv()` and stored in memory for request validation.

## How the Proxy Authentication Middleware Works

The core validation logic resides in [`backend-go/internal/middleware/auth.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/middleware/auth.go). Here, the `ProxyAuthMiddleware()` function implements constant-time comparison to prevent timing attacks.

### The Middleware Logic

```go
// backend-go/internal/middleware/auth.go
func ProxyAuthMiddleware() gin.HandlerFunc {
    // Load the secret from the environment (set in .env or the container)
    proxyKey := os.Getenv("PROXYACCESSKEY")

    return func(c *gin.Context) {
        // Accept the key via header "x-api-key" or Bearer token
        incoming := c.GetHeader("x-api-key")
        if incoming == "" {
            if authHeader := c.GetHeader("Authorization"); strings.HasPrefix(authHeader, "Bearer ") {
                incoming = strings.TrimPrefix(authHeader, "Bearer ")
            }
        }

        // Reject if the key is missing or does not match the stored secret
        if incoming == "" || subtle.ConstantTimeCompare([]byte(incoming), []byte(proxyKey)) != 1 {
            c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{
                "error": "invalid proxy access key",
            })
            return
        }

        // Continue to the next handler when the key is valid
        c.Next()
    }
}

```

Key implementation details from the source:

- **`subtle.ConstantTimeCompare`** ensures the comparison takes constant time regardless of where the strings differ, mitigating timing-based key enumeration attacks.
- **Dual header support**: The middleware checks `x-api-key` first, then falls back to parsing the `Authorization` header for Bearer tokens.
- **401 Unauthorized**: Any request lacking the key or presenting a mismatch is immediately rejected with a JSON error response.

## Route Protection Implementation

The `ProxyAuthMiddleware()` is wired into the Gin router in [`backend-go/main.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/main.go) and applied to public-facing handlers. According to the source analysis, protected routes include those defined in:

- [`backend-go/internal/handlers/frontend.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/handlers/frontend.go)
- [`backend-go/internal/handlers/conversation_handler.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/handlers/conversation_handler.go)

This means all chat completion and frontend API requests must present the `PROXYACCESSKEY` before reaching the downstream AI provider logic.

## Configuring PROXYACCESSKEY

To enable proxy authentication in your deployment:

1. **Copy the example environment file**:

   ```bash
   cp backend-go/.env.example backend-go/.env
   ```

2. **Generate and set a strong secret** in `backend-go/.env`:

   ```dotenv
   PROXYACCESSKEY=your-very-secret-32-char-token
   ```

   Use a cryptographically secure random string (minimum 32 characters recommended).

3. **Restart the service** to load the new environment variable. In development mode, the hot-reload mechanism will detect the change; in production, restart the container or binary.

## Verifying Your Configuration

Test the middleware using `curl`:

**Valid request (returns 200 or downstream response):**

```bash
curl -H "x-api-key: your-very-secret-32-char-token" \
     http://localhost:8080/v1/chat/completions

```

**Invalid request (returns 401 Unauthorized):**

```bash
curl http://localhost:8080/v1/chat/completions

```

The second command should return a JSON error: `{"error":"invalid proxy access key"}`.

## Summary

- **PROXYACCESSKEY** (no underscore) is the canonical environment variable name in the CCX Go backend, despite the common alternate spelling `PROXY_ACCESS_KEY`.
- It serves as the **single source of truth** for proxy-layer authentication, replacing complex OAuth with a simple API key.
- The middleware in [`backend-go/internal/middleware/auth.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/middleware/auth.go) validates every incoming request using **constant-time comparison** against this key.
- Routes in [`backend-go/internal/handlers/frontend.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/handlers/frontend.go) and conversation handlers are protected by default; requests without the key receive a **401 Unauthorized** response.

## Frequently Asked Questions

### Is PROXYACCESSKEY the same as PROXY_ACCESS_KEY?

No. The CCX source code specifically looks for the environment variable `PROXYACCESSKEY` without underscores. While documentation or Issue trackers might refer to it as `PROXY_ACCESS_KEY` colloquially, the actual implementation in [`backend-go/internal/middleware/auth.go`](https://github.com/BenedictKing/ccx/blob/main/backend-go/internal/middleware/auth.go) uses `os.Getenv("PROXYACCESSKEY")`. Always use the non-underscore version in your `.env` files.

### What happens if I leave PROXYACCESSKEY empty or unset?

If the variable is undefined or empty, the `ProxyAuthMiddleware()` will compare incoming requests against an empty string. Consequently, only requests with an empty `x-api-key` header would pass (which is functionally useless), or more likely, all requests will fail validation and return **401 Unauthorized**. Always define a non-empty value before exposing the service to the internet.

### How should I generate a secure PROXYACCESSKEY?

Generate a cryptographically secure random string of at least 32 characters. You can use OpenSSL:

```bash
openssl rand -hex 32

```

Treat this key like a password: store it in a secrets manager, avoid committing it to version control, and rotate it if you suspect compromise.

### Can I rotate PROXYACCESSKEY without downtime?

Rotation requires restarting the CCX backend service because the value is read once at startup and held in memory. To rotate without downtime, deploy a new instance with the new key, update your client configurations, then decommission the old instance. There is no hot-reload mechanism for this specific secret in the current codebase.