Comprehensive Guide to API Key Management
This document provides detailed best practices for managing API keys and sensitive information in the Physical AI & Humanoid Robotics project and other software applications.
1. Understanding API Keys
API keys are unique identifiers used to authenticate and authorize access to services. They act as passwords that allow your application to communicate with external services like OpenAI, Cohere, Gemini, and databases.
2. Types of API Keys & Tokens
Different Kinds of Keys
- Service Account Keys: Used for authentication with cloud services
- Bearer Tokens: Used for API authentication
- Secret Keys: Used for signing and verifying data
- Database Connection Strings: Contain credentials for database access
Permissions and Scopes
Always use keys with minimal required permissions:
- Limit access to specific resources
- Apply time-based expiration where possible
- Use read-only keys when write access isn't required
3. Secure Storage
❌ Never Store Keys Like This:
# DON'T store keys directly in code
const OPENAI_API_KEY = "sk-actual-key-here"
# DON'T store keys in public repositories
export OPENAI_API_KEY="sk-actual-key-here"
# DON'T hardcode keys in your application
public static final String API_KEY = "sk-actual-key-here";
✅ Instead, Use Environment Variables:
# Python example using python-dotenv
import os
from dotenv import load_dotenv
load_dotenv() # Load environment variables from .env file
# Access the API key
openai_api_key = os.getenv("OPENAI_API_KEY")
// JavaScript/Node.js example
// Access the API key from environment variables
const openaiApiKey = process.env.OPENAI_API_KEY;
// For frontend applications, pass variables through build process
// DO NOT directly access backend API keys from frontend code
# Store in .env file (and add to .gitignore)
OPENAI_API_KEY=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
COHERE_API_KEY=HTFZezITzJtoLBloDX0rP4Eb6NKsrk9BTxNkNW7l
QDRANT_URL=https://c96efe7c-aa83-47e9-a297-2961f5942f0c.us-east4-0.gcp.cloud.qdrant.io
QDRANT_API_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhY2Nlc3MiOiJtIn0.3CuOHUNlKyj01GPjTuQavvfNsYy0n2gjdS3IWfcM7q0
DATABASE_URL=https://ep-wild-bird-adcyfk2v.apirest.c-2.us-east-1.aws.neon.tech/neondb/rest/v1
BETTER_AUTH_SECRET=MTPMFZy6ovucemA62babULjzW07s6DV9
GEMINI_API_KEY=AIzaSyCURhNq2jgupaiJs1yS_oatEMTy9LaJcbY
✅ Proper Storage Methods:
- Use environment variables for runtime configuration
- Store in dedicated secrets management systems (HashiCorp Vault, AWS Secrets Manager, Azure Key Vault)
- Utilize cloud provider's secret management solutions (AWS Systems Manager Parameter Store, Google Cloud Secret Manager)
4. Environment-Specific Keys
Use different API keys for different environments:
- Development: Use dedicated development keys with limited permissions
- Staging: Use staging keys that mirror production as closely as possible
- Production: Use full-privileged production keys
Example configuration structure:
.env.development
.env.staging
.env.production
5. Revocation and Rotation
Regular Rotation Schedule
- Rotate keys every 3-6 months (or according to your security policy)
- Establish automated rotation for some services
- Maintain a rotation calendar
Immediate Action Steps When Keys Are Compromised
- Revoke the exposed key immediately
- Generate a new key with the same permissions
- Deploy the new key to all affected systems
- Monitor for suspicious activity during the transition period
Audit Trail
- Keep records of who had access to keys
- Document when keys were rotated
- Log key usage where possible
6. Application-Level Security
Backend Proxy Pattern
As demonstrated in this project, never expose backend API keys to frontend code: