Claude API Authentication with Environment Variables
Claude API authentication with environment variables means storing your API key as a system-level variable instead of hardcoding it into your source files. You set it once per environment (ANTHROPIC_API_KEY or a custom name like SUBTOAPI_KEY), and your code reads it at runtime with something like process.env.ANTHROPIC_API_KEY or os.environ.get("ANTHROPIC_API_KEY"). This keeps secrets out of version control and lets you swap keys between development, staging, and production without touching code.
The rest of this guide covers how to set environment variables correctly across different setups — local development, CI/CD, Docker, and serverless — plus the mistakes that most commonly leak API keys into logs or git history.
Why Environment Variables and Not Hardcoded Keys
Hardcoding an API key directly into a script is the fastest way to leak it. Keys committed to git end up in GitHub history forever, even after you delete them in a later commit. Environment variables solve this by keeping the secret outside the codebase entirely:
- The key lives in the shell, a
.envfile (gitignored), or your hosting provider's secrets manager. - Code references a variable name, never the literal value.
- Different environments can use different keys without branching logic.
- Rotating a compromised key means updating one value, not redeploying code.
This pattern applies whether you're calling Anthropic's Claude API directly or using a proxy like SubToAPI that issues its own sub_live_... keys for your app.
Setting Up Environment Variables Locally
macOS / Linux (shell)
Export the variable in your current shell session:
export ANTHROPIC_API_KEY="sk-ant-xxxxxxxxxxxx"
To persist it across sessions, add that line to ~/.bashrc, ~/.zshrc, or equivalent. For project-specific keys, a .env file is more practical:
# .env
ANTHROPIC_API_KEY=sk-ant-xxxxxxxxxxxx
Add .env to .gitignore immediately — before you commit anything, not after.
Loading .env in Node.js
require("dotenv").config();
const apiKey = process.env.ANTHROPIC_API_KEY;
if (!apiKey) {
throw new Error("Missing ANTHROPIC_API_KEY in environment");
}
Loading .env in Python
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.environ.get("ANTHROPIC_API_KEY")
if not api_key:
raise RuntimeError("Missing ANTHROPIC_API_KEY in environment")
Always fail fast if the key is missing. A silent None value that gets passed to an HTTP header turns into a confusing 401 error three steps later.
Using the Variable in a Request
Once the variable is loaded, pass it as a bearer token or custom header depending on which API you're calling. For SubToAPI, which wraps Claude access behind a standard HTTPS API, the pattern looks like this:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this changelog."}]
}'
In JavaScript:
const response = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet",
max_tokens: 1024,
messages: [{ role: "user", content: "Summarize this changelog." }]
})
});
The key never appears in the code itself — only the variable name does. That's the entire point. Full request and response shapes are in the docs and the quickstart.
Environment Variables in CI/CD
Most CI providers (GitHub Actions, GitLab CI, CircleCI) have a secrets store separate from your repository. Reference it the same way in your pipeline config:
# GitHub Actions example
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
Never echo the variable in a build step for debugging — logs are often stored longer than you expect, and some CI providers don't redact secrets perfectly in multi-line output.
Environment Variables in Docker
Pass the variable at runtime instead of baking it into the image:
docker run -e ANTHROPIC_API_KEY=$ANTHROPIC_API_KEY my-app
Or reference an env file:
docker run --env-file .env my-app
Avoid ARG and ENV instructions in a Dockerfile for secrets — anything set that way gets baked into image layers and is recoverable by anyone with access to the image.
Environment Variables in Serverless (Vercel, Netlify, AWS Lambda)
Each platform has a dashboard or CLI for setting environment variables per deployment stage:
- Vercel: Project Settings → Environment Variables, scoped to Production/Preview/Development.
- Netlify: Site Settings → Environment Variables.
- AWS Lambda: Configuration → Environment Variables, or via
serverless.yml/ Terraform referencing a secrets manager.
The same rule applies everywhere: separate keys per environment, and never log the full value even for debugging.
Common Mistakes to Avoid
- Committing
.envfiles. Add.envto.gitignorebefore the first commit, not after the key is already in history. - Printing the key in error messages. A stack trace that includes the full request headers can leak the key into log aggregators.
- Using the same key across dev and prod. If a key leaks in a staging environment, you don't want production traffic affected too. Teams using SubToAPI can issue separate
sub_live_...keys per environment and per team member from one dashboard. - Forgetting to rotate after a leak. If a key ever appears in a public repo, rotate it immediately — don't wait to see if anyone noticed.
Wrapping Up
Environment variables are the baseline for handling any API key, Claude included. The setup is nearly identical across local development, CI, Docker, and serverless — load the variable, fail fast if it's missing, and never let the literal value touch source code or logs. If you want key management, usage tracking, and team seats without building that infrastructure yourself, sign up for a free trial and generate your first key in minutes.
questions
Do I need a different environment variable for each environment? Yes. Using separate keys for development, staging, and production limits the damage if one leaks and makes usage tracking per environment much clearer.
What's the difference between .env files and system environment variables? .env files are loaded by a library (like dotenv) into the process environment at runtime; system environment variables are set directly in the shell or OS. Both end up accessible via the same process.env or os.environ interface — .env is just more convenient for local projects.
Is it safe to use environment variables in client-side JavaScript? No. Environment variables set in a browser-facing build get bundled into the shipped JavaScript and are visible to anyone who opens dev tools. API keys should only be used server-side, in a backend that proxies requests to Claude or a service like SubToAPI.