How ANTHROPIC_AUTH_TOKEN Authentication Works in Free-Claude-Code: A Complete Guide
Free-Claude-Code validates HTTP requests using an Anthropic-style API key sourced from the ANTHROPIC_AUTH_TOKEN environment variable, supporting three authentication header formats while gracefully degrading to open access when the token is unset.
The authentication system in the Alishahryar1/free-claude-code repository provides a lightweight yet configurable security layer for self-hosted instances. It combines Pydantic-based configuration management with FastAPI dependency injection to enforce token-based access across protected endpoints.
Configuration and Token Resolution
The authentication token is defined in config/settings.py as a Pydantic field within the Settings class. According to lines 200-203, anthropic_auth_token reads directly from the environment variable ANTHROPIC_AUTH_TOKEN using Pydantic's env-file support.
The system implements specific precedence rules to handle configuration conflicts:
-
Dotenv Override Logic: The
prefer_dotenv_anthropic_auth_token()method (lines 76-82) ensures that values explicitly defined in a.envfile take precedence over tokens exported in the shell environment. This prevents accidental credential leakage from shell history while encouraging explicit configuration. -
Source Tracking: The
uses_process_anthropic_auth_token()helper (lines 84-88) returns a boolean indicating whether the active token originated from the process environment rather than the dotenv file.
Authentication Enforcement and Header Parsing
Request validation occurs in api/dependencies.py through the require_api_key FastAPI dependency (lines 55-86). This dependency implements a flexible token extraction mechanism that accepts credentials through three distinct methods:
x-api-keyheader – Direct API key transmissionAuthorization: Bearer <token>– Standard OAuth-style bearer tokenanthropic-auth-tokenheader` – Legacy Anthropic-style header
When ANTHROPIC_AUTH_TOKEN is empty or undefined, require_api_key becomes a no-op, immediately returning None and allowing unauthenticated access. This design supports local development without mandatory credential configuration. If the header token does not match the configured value, the dependency raises a 401 Unauthorized HTTP exception with a descriptive error message.
Runtime Warnings and Environment Validation
To promote secure configuration practices, the application startup sequence in api/app.py calls _warn_if_process_auth_token() (lines 41-50). This function checks uses_process_anthropic_auth_token() and logs a warning when the token is sourced from the shell environment rather than a .env file, encouraging users to move sensitive credentials into version-controlled configuration files.
Practical Implementation Examples
Configuring the Authentication Token
Create a .env file in the project root for production deployments:
# .env file (recommended)
ANTHROPIC_AUTH_TOKEN=sk-ant-token-very-secret
For temporary local testing, export the variable directly:
export ANTHROPIC_AUTH_TOKEN=sk-ant-token-very-secret
uv run python -m free_claude_code.api.app
Making Authenticated Requests
Send requests using Python's httpx library with the x-api-key header:
import httpx
url = "http://localhost:8082/v1/chat/completions"
headers = {"x-api-key": "sk-ant-token-very-secret"}
payload = {
"model": "opus",
"messages": [{"role": "user", "content": "Hello"}]
}
response = httpx.post(url, json=payload, headers=headers)
print(response.json())
Alternatively, use the Bearer token format:
headers = {"Authorization": "Bearer sk-ant-token-very-secret"}
Protecting FastAPI Routes
Apply the authentication dependency to specific routes using FastAPI's Depends pattern:
from fastapi import APIRouter, Depends
from api.dependencies import require_api_key
router = APIRouter()
@router.post("/v1/chat/completions", dependencies=[Depends(require_api_key)])
async def chat_completion(request: ChatRequest):
...
Summary
- Token Source:
ANTHROPIC_AUTH_TOKENis read via Pydantic settings inconfig/settings.py, with.envfiles taking precedence over shell environment variables. - Header Flexibility: The system accepts authentication via
x-api-key,Authorization: Bearer, oranthropic-auth-tokenheaders. - Optional Security: When
ANTHROPIC_AUTH_TOKENis unset, therequire_api_keydependency permits unauthenticated requests, enabling zero-config local development. - Configuration Warnings: Runtime checks in
api/app.pywarn against relying on shell-exported tokens, promoting.envfile usage. - Route Protection: FastAPI dependencies enforce authentication selectively, returning
401 Unauthorizedfor mismatched or missing tokens.
Frequently Asked Questions
What happens if ANTHROPIC_AUTH_TOKEN is not set?
When the environment variable is empty or undefined, the require_api_key dependency in api/dependencies.py silently passes through without validation, allowing all requests to proceed unauthenticated. This behavior supports local development but should not be used in production environments.
Which HTTP headers can I use to send the authentication token?
Free-Claude-Code accepts three header formats: x-api-key for direct token transmission, Authorization: Bearer <token> for OAuth compatibility, and anthropic-auth-token for Anthropic API consistency. All three are checked in order within the require_api_key dependency.
Why does the server warn about tokens set in the shell environment?
The warning generated by _warn_if_process_auth_token() in api/app.py appears when the token is sourced from the process environment rather than a .env file. This encourages users to avoid shell history leakage and makes credentials more visible in configuration management, as dotenv values are explicitly declared in files rather than exported in terminal sessions.
How do I add authentication protection to a custom endpoint?
Import require_api_key from api.dependencies and include it in your route's dependency list using Depends(require_api_key). If the token is configured, the dependency validates incoming requests; if not configured, the endpoint remains openly accessible.
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 →