Python / FastAPI

Secure Your Anthropic API Key in Python

Python's anthropic SDK reads ANTHROPIC_API_KEY from the environment at import time. A misconfigured Docker COPY or a verbose exception traceback can expose it. KVE tokens are refused when the request's Origin isn't on the token's allowed hosts.

The Problem

This is what most Python codebases look like today. The ANTHROPIC_API_KEY key (sk-ant-...) lives directly in the process environment. If your repo, your CI logs, or your deployment config leaks — so does your key.

Python
# api.py — real Anthropic key in ANTHROPIC_API_KEY
import os
import anthropic

client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

def generate(prompt: str) -> str:
    message = client.messages.create(
        model="claude-opus-4-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": prompt}],
    )
    return message.content[0].text

The Fix

Send the request to the KeyVault Edge proxy at https://proxy.keyvaultedge.com with the provider's usual path, your kvt_ token in X-KV-Token and the provider's base URL in X-KV-Target. The proxy refuses requests whose Origin isn't on the token's allowed hosts, then injects your real ANTHROPIC_API_KEY, so it never sits in your app's environment.

Python
# api.py — KVE_TOKEN is host-bound; ANTHROPIC_API_KEY not needed
import os
import httpx

KVE_TOKEN = os.environ["KVE_TOKEN"]

def generate(prompt: str) -> str:
    response = httpx.post(
        "https://proxy.keyvaultedge.com/v1/messages",
        headers={
            "X-KV-Token": os.environ["KVE_TOKEN"],  # kvt_... token
            "X-KV-Target": "https://api.anthropic.com",
            # Must match one of the token's allowed hosts
            "Origin": os.environ["APP_ORIGIN"],
            "Content-Type": "application/json",
        },
        json={
            "model": "claude-opus-4-5",
            "max_tokens": 1024,
            "messages": [{"role": "user", "content": prompt}],
        },
        timeout=60.0,
    )
    response.raise_for_status()
    return response.json()["content"][0]["text"]

Setup in 4 steps

1

Create a KVE token for Anthropic

Log into keyvaultedge.com, go to Tokens → New Token, paste your sk-ant- key, and add your server's hostname as an allowed host. Save the KVE_TOKEN value.

2

Update your environment configuration

Replace ANTHROPIC_API_KEY with KVE_TOKEN in your .env file, docker-compose environment block, or platform secret store.

Shell
# .env
KVE_TOKEN=kvt_...your_token
APP_ORIGIN=https://yourdomain.com  # one of the token's allowed hosts

pip install httpx  # if not already installed
3

Replace the anthropic SDK call with httpx

Use httpx.post. Point the request at https://proxy.keyvaultedge.com with the provider's usual path (e.g. /v1/messages), send your token in X-KV-Token, the provider's base URL (https://api.anthropic.com) in X-KV-Target, and an Origin header matching one of the token's allowed hosts. The body is the provider's normal request body; the proxy sets the provider's auth header with your real key and forwards it.

4

Configure webhook alerts

In your KeyVault Edge dashboard, add a webhook URL (Slack, PagerDuty, or Discord) under Alerts. You'll get notified immediately if your token is used from a host outside its allowlist.

What this protects, and what it doesn't

  • Your real ANTHROPIC_API_KEY stays at the edge, so it can't leak from your repo, logs, bundle or server environment.
  • The kvt_ token is still a credential. A copied token can be replayed by anyone who can send the right headers, including a fake Origin from a server. The protection is that each token has its own rate limits, monthly cost cap and endpoint scope, and you can revoke it in one click without rotating the provider key.
  • The cost cap is estimated from the usage the provider reports, so a request already in flight can overshoot it slightly.

Plans and limits are on the pricing page.

Start protecting your keys

Your Anthropic key is one leaked .env file away from being exploited. With KeyVault Edge the real key stays at the edge, and the token that replaces it is capped, scoped and revocable in one click.