# Secret Management Guide

This document describes how to securely generate and manage secrets for Akosha deployments.

## Overview

Akosha requires several secrets for secure operation:

- **JWT_SECRET**: Used for signing JWT authentication tokens (required in production)
- **ENCRYPTION_KEY**: Used for data-at-rest encryption (optional)
- **External Service Credentials**: Redis, S3/R2, OpenTelemetry (optional)

## Security Principles

1. **Never commit secrets to version control**: Production secrets are gitignored
1. **Use cryptographically secure generation**: All secrets generated with `secrets` module
1. **Enforce minimum length**: JWT secrets must be ≥32 characters for HS256 algorithm
1. **Reject placeholders in production**: Startup validation prevents placeholder secrets
1. **Environment-specific controls**: Development is more permissive, production is strict

## Quick Start

### Development Setup

For local development, you can use test secrets:

```bash
export JWT_SECRET="development-test-secret-key-for-local-testing-min-32-chars"
export AUTH_ENABLED="true"
```

### Production Deployment

**Step 1: Generate production secrets**

```bash
python -m akosha.scripts.generate_secrets
```

This creates `k8s/secret.production.yaml` with cryptographically secure secrets.

**Step 2: Review the generated secrets**

```bash
cat k8s/secret.production.yaml
```

**Step 3: Apply to Kubernetes cluster**

```bash
kubectl apply -f k8s/secret.production.yaml
```

**Step 4: Verify secrets are applied**

```bash
kubectl get secrets -n akosha
kubectl describe secret akosha-secrets -n akosha
```

## Secret Generation Script

The `akosha/scripts/generate_secrets.py` script provides secure secret generation:

### Features

- **Cryptographically secure**: Uses `secrets.token_urlsafe(32)` for 256-bit entropy
- **Template-based**: Supports custom templates via `--template` flag
- **Flexible output**: Specify output path with `--output` flag
- **Validation**: Ensures generated secrets meet minimum length requirements

### Usage

```bash
# Default usage (generates k8s/secret.production.yaml)
python -m akosha.scripts.generate_secrets

# Custom output path
python -m akosha.scripts.generate_secrets --output /tmp/my-secrets.yaml

# Custom template
python -m akosha.scripts.generate_secrets \
  --template k8s/secret.custom.yaml.template \
  --output k8s/secret.custom.yaml
```

### Generated Secrets

| Secret | Length | Algorithm | Purpose |
|--------|--------|-----------|---------|
| JWT_SECRET | 43 chars | URL-safe base64 (32 bytes) | JWT token signing (HS256) |
| ENCRYPTION_KEY | 43 chars | URL-safe base64 (32 bytes) | AES-256 encryption |

## Environment-Specific Behavior

### Development (ENVIRONMENT=development)

- ✅ Allows test secrets
- ✅ No placeholder validation
- ⚠️ Still enforces minimum length (32 chars)
- ⚠️ Logs warning if auth disabled

### Production (ENVIRONMENT=production)

- ✅ Requires valid JWT_SECRET (if AUTH_ENABLED=true)
- ✅ Rejects placeholder secrets
- ✅ Enforces minimum length (32 chars)
- ❌ Startup fails if secrets are invalid

## Placeholder Rejection

In production, the following placeholder values are **rejected**:

- `change-this-in-production`
- `change-me`
- `placeholder`
- `""` (empty)
- `none`
- `null`
- `example`
- `test-secret`
- `jwt-secret-placeholder`

**Example error:**

```
RuntimeError: Authentication configuration failed: JWT_SECRET is using a placeholder value. Generate secure secrets with: python -m akosha.scripts.generate_secrets
```

## Kubernetes Secrets

### Development Secret (`k8s/secret.yaml`)

Contains **no actual secrets** - only comments and documentation. Safe to commit to git.

### Production Secret (`k8s/secret.production.yaml`)

Generated by the script, contains real secrets. **Gitignored** for security.

### Production Template (`k8s/secret.production.yaml.template`)

Template file that can be customized for your deployment. Safe to commit to git.

## Validation

### Startup Validation

Akosha validates secrets on startup:

```python
# From akosha/mcp/auth.py
def validate_auth_config() -> bool:
    # 1. Check if auth is enabled
    # 2. Ensure JWT_SECRET is set
    # 3. Reject placeholders in production
    # 4. Enforce minimum length (32 chars)
```

**Startup failures:**

```
# Missing secret
RuntimeError: Authentication configuration failed: AUTH_ENABLED=true but JWT_SECRET is not set

# Too short
RuntimeError: Authentication configuration failed: JWT_SECRET too short (25 chars). Must be at least 32 characters for HS256 algorithm

# Placeholder in production
RuntimeError: Authentication configuration failed: JWT_SECRET is using a placeholder value
```

### Manual Validation

Test your secrets before deployment:

```bash
# Test JWT generation
python -c "
import os
os.environ['JWT_SECRET'] = 'your-secret-here-min-32-chars'
from akosha.security import generate_jwt_token
token = generate_jwt_token('test-user')
print(f'Token: {token[:50]}...')
"

# Test validation
python -c "
import os
os.environ['JWT_SECRET'] = 'your-secret-here-min-32-chars'
os.environ['ENVIRONMENT'] = 'production'
os.environ['AUTH_ENABLED'] = 'true'
from akosha.mcp.auth import validate_auth_config
validate_auth_config()
print('✅ Secrets validated')
"
```

## Rotation

### JWT Secret Rotation

**Recommended**: Rotate JWT secrets quarterly (every 3 months).

**Process**:

1. Generate new secret:

   ```bash
   python -m akosha.scripts.generate_secrets --output k8s/secret.new.yaml
   ```

1. Apply new secret:

   ```bash
   kubectl apply -f k8s/secret.new.yaml
   ```

1. Rolling restart pods:

   ```bash
   kubectl rollout restart deployment akosha-mcp -n akosha
   ```

1. Verify new tokens work:

   ```bash
   # Test authentication with new secret
   ```

1. **Important**: Old tokens will become invalid immediately. Plan rotation during low-traffic periods.

### Encryption Key Rotation

For data-at-rest encryption, key rotation is more complex:

1. **Stop ingestion**: Pause data ingestion to avoid mixed encryption
1. **Re-encrypt data**: Decrypt with old key, encrypt with new key
1. **Update secret**: Apply new secret to Kubernetes
1. **Restart services**: Rolling restart all pods
1. **Verify**: Check data accessibility and encryption

**Recommendation**: Consult security team before rotating encryption keys.

## Security Best Practices

### ✅ DO

- Generate secrets with `python -m akosha.scripts.generate_secrets`
- Store secrets in Kubernetes Secrets (not ConfigMaps)
- Use environment-specific secrets (dev/staging/prod)
- Rotate secrets regularly (quarterly for JWT, annually for encryption)
- Limit secret access to least-privilege service accounts
- Enable audit logging for secret access
- Use RBAC to control who can view/create secrets

### ❌ DON'T

- Commit secrets to git (use `.gitignore`)
- Share secrets via email/chat (use secret managers)
- Reuse secrets across environments
- Use weak/predictable secrets
- Store secrets in ConfigMaps or environment variables in manifests
- Log secrets or include them in error messages

## Troubleshooting

### "JWT_SECRET is not set"

**Cause**: Missing environment variable or Kubernetes secret.

**Fix**:

```bash
# Check if secret exists
kubectl get secrets -n akosha

# Check if secret has JWT_SECRET
kubectl get secret akosha-secrets -n akosha -o jsonpath='{.data.JWT_SECRET}' | base64 -d

# Generate and apply secret
python -m akosha.scripts.generate_secrets
kubectl apply -f k8s/secret.production.yaml
```

### "JWT_SECRET too short"

**Cause**: Secret is less than 32 characters (minimum for HS256).

**Fix**: Regenerate secret with proper length:

```bash
python -m akosha.scripts.generate_secrets
```

### "JWT_SECRET is using a placeholder value"

**Cause**: Production deployment is using placeholder secret.

**Fix**:

```bash
# Generate real secrets
python -m akosha.scripts.generate_secrets

# Apply to cluster
kubectl apply -f k8s/secret.production.yaml

# Restart pods
kubectl rollout restart deployment akosha-mcp -n akosha
```

### Authentication works in dev but not production

**Cause**: Different environment variable (`ENVIRONMENT=production`).

**Fix**: Ensure you're using production secrets:

```bash
# Check environment
kubectl get deployment akosha-mcp -n akosha -o yaml | grep ENVIRONMENT

# Set production environment
kubectl set env deployment/akosha-mcp ENVIRONMENT=production -n akosha
```

## References

- **OWASP Secret Management**: https://cheatsheetseries.owasp.org/cheatsheets/Secret_Management_Cheat_Sheet.html
- **Kubernetes Secrets Best Practices**: https://kubernetes.io/docs/concepts/configuration/secret/
- **JWT Best Practices**: https://tools.ietf.org/html/rfc8725

## Appendix: Manual Secret Generation

If you need to generate secrets manually (not recommended):

```bash
# JWT Secret (32 bytes, URL-safe base64 = ~43 chars)
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='

# Encryption Key (32 bytes, URL-safe base64 = ~43 chars)
openssl rand -base64 32 | tr '+/' '-_' | tr -d '='
```

**Note**: Use the provided script instead of manual generation for consistency.
