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 .env file 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:

  1. x-api-key header – Direct API key transmission
  2. Authorization: Bearer <token> – Standard OAuth-style bearer token
  3. anthropic-auth-token header` – 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_TOKEN is read via Pydantic settings in config/settings.py, with .env files taking precedence over shell environment variables.
  • Header Flexibility: The system accepts authentication via x-api-key, Authorization: Bearer, or anthropic-auth-token headers.
  • Optional Security: When ANTHROPIC_AUTH_TOKEN is unset, the require_api_key dependency permits unauthenticated requests, enabling zero-config local development.
  • Configuration Warnings: Runtime checks in api/app.py warn against relying on shell-exported tokens, promoting .env file usage.
  • Route Protection: FastAPI dependencies enforce authentication selectively, returning 401 Unauthorized for 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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →