Skip to content

Secret Management

Nick edited this page Nov 26, 2025 · 1 revision

Secret Management Guide

This guide covers best practices for managing secrets in PATAS deployments.

Overview

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)

Environment Variables

All secrets should be provided via environment variables, NOT in code or config files.

Required Secrets

# 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

Optional Secrets

# Redis (for distributed rate limiting/caching)
REDIS_URL="redis://user:password@host:6379/0"

# TAS Integration
TAS_API_KEY="your-tas-api-key"

Secret Storage Options

1. Environment Files (.env)

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-key

2. Docker Secrets

For 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: true

3. Kubernetes Secrets

For 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-secrets

4. HashiCorp Vault

For 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"

5. AWS Secrets Manager

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']

6. Google Cloud Secret Manager

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')

Secret Rotation

API Keys

  1. Generate new API key
  2. Add to API_KEYS (comma-separated)
  3. Update clients to use new key
  4. 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"

Database Credentials

  1. Create new database user with same permissions
  2. Update DATABASE_URL with new credentials
  3. Restart services
  4. Remove old database user

LLM API Keys

  1. Generate new key in provider console
  2. Update LLM_API_KEY environment variable
  3. Restart services
  4. Revoke old key in provider console

Security Best Practices

DO

  • ✅ 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

DON'T

  • ❌ 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

Validation

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 provider

Monitoring

Monitor 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"

Emergency Response

If a secret is compromised:

  1. Immediately rotate the compromised secret
  2. Audit access logs for unauthorized activity
  3. Notify affected parties
  4. Review and strengthen access controls
  5. Document the incident

References

Clone this wiki locally