-
Notifications
You must be signed in to change notification settings - Fork 0
Secret Management
Nick edited this page Nov 26, 2025
·
1 revision
This guide covers best practices for managing secrets in PATAS deployments.
PATAS uses various secrets for:
- API authentication (API keys)
- Database connectivity (credentials)
- LLM provider access (API keys)
- Embedding provider access (API keys)
- Redis connectivity (connection strings)
All secrets should be provided via environment variables, NOT in code or config files.
# API Authentication
API_KEYS="key1:namespace1,key2:namespace2"
# Database (PostgreSQL)
DATABASE_URL="postgresql+asyncpg://user:password@host:5432/patas"
# LLM Provider (if using OpenAI)
LLM_API_KEY="sk-..."
OPENAI_API_KEY="sk-..." # Alternative name
# Embedding Provider (if using OpenAI)
EMBEDDING_API_KEY="sk-..." # Falls back to LLM_API_KEY if not set# Redis (for distributed rate limiting/caching)
REDIS_URL="redis://user:password@host:6379/0"
# TAS Integration
TAS_API_KEY="your-tas-api-key"For development only. Never commit .env files.
# .env (add to .gitignore!)
API_KEYS=dev-key:development
DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5432/patas_dev
LLM_API_KEY=sk-test-keyFor Docker Swarm deployments:
# docker-compose.yml
services:
patas:
image: patas:latest
secrets:
- db_password
- api_keys
- llm_api_key
environment:
DATABASE_URL: postgresql+asyncpg://patas:${DB_PASSWORD}@db:5432/patas
secrets:
db_password:
external: true
api_keys:
external: true
llm_api_key:
external: trueFor Kubernetes deployments:
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: patas-secrets
type: Opaque
stringData:
DATABASE_URL: postgresql+asyncpg://user:password@host:5432/patas
API_KEYS: key1:namespace1,key2:namespace2
LLM_API_KEY: sk-your-api-key
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: patas
spec:
template:
spec:
containers:
- name: patas
envFrom:
- secretRef:
name: patas-secretsFor enterprise deployments:
# Store secrets in Vault
vault kv put secret/patas \
database_url="postgresql+asyncpg://..." \
api_keys="key1:ns1,key2:ns2" \
llm_api_key="sk-..."
# Use Vault Agent Injector in Kubernetes
annotations:
vault.hashicorp.com/agent-inject: "true"
vault.hashicorp.com/agent-inject-secret-config: "secret/patas"
vault.hashicorp.com/role: "patas"For AWS deployments:
# Example: Load secrets from AWS Secrets Manager at startup
import boto3
import json
def load_aws_secrets():
client = boto3.client('secretsmanager')
response = client.get_secret_value(SecretId='patas/production')
secrets = json.loads(response['SecretString'])
os.environ['DATABASE_URL'] = secrets['database_url']
os.environ['API_KEYS'] = secrets['api_keys']
os.environ['LLM_API_KEY'] = secrets['llm_api_key']For GCP deployments:
from google.cloud import secretmanager
def load_gcp_secrets():
client = secretmanager.SecretManagerServiceClient()
def get_secret(name):
response = client.access_secret_version(
request={"name": f"projects/my-project/secrets/{name}/versions/latest"}
)
return response.payload.data.decode("UTF-8")
os.environ['DATABASE_URL'] = get_secret('patas-database-url')
os.environ['API_KEYS'] = get_secret('patas-api-keys')- Generate new API key
- Add to API_KEYS (comma-separated)
- Update clients to use new key
- Remove old key after transition period
# Before rotation
API_KEYS="old-key:namespace"
# During transition (both keys active)
API_KEYS="old-key:namespace,new-key:namespace"
# After rotation
API_KEYS="new-key:namespace"- Create new database user with same permissions
- Update DATABASE_URL with new credentials
- Restart services
- Remove old database user
- Generate new key in provider console
- Update LLM_API_KEY environment variable
- Restart services
- Revoke old key in provider console
- ✅ Use environment variables for all secrets
- ✅ Use a secrets manager in production
- ✅ Rotate secrets regularly (every 90 days)
- ✅ Use different secrets per environment
- ✅ Encrypt secrets at rest and in transit
- ✅ Limit secret access to necessary services only
- ✅ Audit secret access regularly
- ✅ Use strong, randomly generated secrets
- ❌ Commit secrets to version control
- ❌ Log secrets (even accidentally)
- ❌ Share secrets via insecure channels (email, Slack)
- ❌ Use the same secrets in dev and production
- ❌ Hardcode secrets in source code
- ❌ Store secrets in plain text files
- ❌ Use weak or predictable secrets
PATAS validates secret configuration at startup:
# Production mode validates required secrets
ENVIRONMENT=production patas-api
# Errors for missing required secrets:
# Production configuration errors:
# - API_KEYS must be configured in production
# - LLM_API_KEY required when using OpenAI LLM providerMonitor for:
- Failed authentication attempts (potential key exposure)
- API key usage patterns (detect compromised keys)
- Secret access logs (from secrets manager)
# Prometheus alert for failed auth
- alert: HighFailedAuthRate
expr: rate(patas_auth_failures_total[5m]) > 10
annotations:
summary: "High rate of authentication failures"
description: "May indicate attempted unauthorized access or compromised API key"If a secret is compromised:
- Immediately rotate the compromised secret
- Audit access logs for unauthorized activity
- Notify affected parties
- Review and strengthen access controls
- Document the incident