Authentication¶
The SecretZero API uses API key authentication to secure access to your secrets and operations. This guide covers authentication setup, security best practices, and production deployment considerations.
Authentication Overview¶
API Key Authentication¶
SecretZero uses a simple but secure API key authentication mechanism:
- Header-based: API keys are passed via the
X-API-KeyHTTP header - Timing-attack resistant: Uses constant-time comparison to prevent timing attacks
- Optional: Can run in insecure mode for local development (not recommended)
- Flexible: Easy to rotate and manage
Security Features¶
- SHA-256 hashing: API keys are hashed before comparison
- Constant-time comparison: Prevents timing-based attacks using
secrets.compare_digest() - No API key storage: Keys are only stored in environment variables
- Audit logging: All authentication attempts are logged
Generating API Keys¶
Using Python¶
The most secure method:
This generates a 32-byte (256-bit) cryptographically secure random token encoded in URL-safe base64.
Using OpenSSL¶
Alternative method using OpenSSL:
Using the SecretZero CLI¶
Example Output¶
⚠️ Important: Save this key securely! You'll need it for all API requests.
Configuring Authentication¶
Setting the API Key¶
Environment Variable (Recommended)¶
.env File (Local Development)¶
Create a .env file:
Load it before starting:
Systemd Service (Production)¶
[Service]
Environment="SECRETZERO_API_KEY=your-secure-api-key-here"
ExecStart=/usr/local/bin/secretzero-api
Docker (Production)¶
Kubernetes Secret (Production)¶
apiVersion: v1
kind: Secret
metadata:
name: secretzero-api-key
type: Opaque
stringData:
api-key: your-secure-api-key-here
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: secretzero-api
spec:
template:
spec:
containers:
- name: api
env:
- name: SECRETZERO_API_KEY
valueFrom:
secretKeyRef:
name: secretzero-api-key
key: api-key
Running Without Authentication (Insecure)¶
⚠️ Warning: Only for local development!
Simply don't set the SECRETZERO_API_KEY environment variable:
The API will run in insecure mode and accept all requests without authentication.
Making Authenticated Requests¶
Using cURL¶
# Set your API key
export API_KEY="your-api-key-here"
# Make authenticated request
curl -H "X-API-Key: $API_KEY" http://localhost:8000/secrets
Using Python requests¶
import requests
API_KEY = "your-api-key-here"
BASE_URL = "http://localhost:8000"
headers = {"X-API-Key": API_KEY}
response = requests.get(f"{BASE_URL}/secrets", headers=headers)
print(response.json())
Using JavaScript/fetch¶
const API_KEY = "your-api-key-here";
const BASE_URL = "http://localhost:8000";
fetch(`${BASE_URL}/secrets`, {
headers: {
"X-API-Key": API_KEY
}
})
.then(response => response.json())
.then(data => console.log(data));
Using HTTPie¶
Using Postman¶
- Open Postman
- Create a new request
- Go to the "Headers" tab
- Add a header:
- Key:
X-API-Key - Value:
your-api-key-here - Send the request
Authentication Endpoints¶
Unauthenticated Endpoints¶
These endpoints don't require authentication:
| Endpoint | Method | Description |
|---|---|---|
/ |
GET | API root information |
/health |
GET | Health check |
/docs |
GET | Swagger UI documentation |
/redoc |
GET | ReDoc documentation |
/openapi.json |
GET | OpenAPI specification |
Authenticated Endpoints¶
All other endpoints require a valid API key:
| Endpoint | Method | Description |
|---|---|---|
/secrets |
GET | List secrets |
/secrets/{name}/status |
GET | Get secret status |
/sync |
POST | Sync secrets |
/rotation/check |
POST | Check rotation |
/rotation/execute |
POST | Execute rotation |
/policy/check |
POST | Check policies |
/drift/check |
POST | Check drift |
/config/validate |
POST | Validate config |
/audit/logs |
GET | Get audit logs |
Error Responses¶
Missing API Key¶
Request:
Response: 401 Unauthorized
Invalid API Key¶
Request:
Response: 401 Unauthorized
Headers Include WWW-Authenticate¶
Security Best Practices¶
1. Always Use HTTPS in Production¶
Never send API keys over unencrypted HTTP in production:
# Nginx configuration
server {
listen 443 ssl http2;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
# Modern SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
proxy_pass http://localhost:8000;
}
}
2. Rotate API Keys Regularly¶
Establish a rotation schedule:
# Generate new key
NEW_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
# Update environment
export SECRETZERO_API_KEY=$NEW_KEY
# Restart service
systemctl restart secretzero-api
# Update clients with new key
# Wait for confirmation
# Revoke old key
3. Use Environment Variables¶
Never hardcode API keys in source code:
❌ Bad:
✅ Good:
4. Limit API Key Exposure¶
- Don't commit API keys to version control
- Don't log API keys
- Don't include API keys in URLs or query parameters
- Use secret management systems (Vault, AWS Secrets Manager)
5. Implement Network Restrictions¶
Restrict API access at the network level:
Firewall Rules:
# Only allow specific IPs
iptables -A INPUT -p tcp --dport 8000 -s 10.0.0.0/8 -j ACCEPT
iptables -A INPUT -p tcp --dport 8000 -j DROP
Kubernetes NetworkPolicy:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: secretzero-api-access
spec:
podSelector:
matchLabels:
app: secretzero-api
ingress:
- from:
- podSelector:
matchLabels:
access: secretzero-api
6. Monitor and Audit¶
Enable comprehensive audit logging:
# Check audit logs regularly
curl -H "X-API-Key: $API_KEY" \
"http://localhost:8000/audit/logs?limit=100" | jq '.'
Set up alerts for: - Failed authentication attempts - Unusual access patterns - High-frequency requests - Access from unexpected sources
7. Use Separate Keys for Different Environments¶
# Development
export SECRETZERO_API_KEY=$DEV_API_KEY
# Staging
export SECRETZERO_API_KEY=$STAGING_API_KEY
# Production
export SECRETZERO_API_KEY=$PROD_API_KEY
8. Implement Rate Limiting¶
Use a reverse proxy for rate limiting:
Nginx Example:
http {
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location / {
limit_req zone=api burst=20;
proxy_pass http://localhost:8000;
}
}
}
Traefik Example:
9. Principle of Least Privilege¶
If implementing multiple API keys (future feature):
- Use separate keys for different applications
- Grant minimal necessary permissions
- Revoke keys when no longer needed
10. Secure Key Storage¶
For Services: - AWS Secrets Manager - Azure Key Vault - HashiCorp Vault - Kubernetes Secrets
For Developers: - Password managers (1Password, LastPass) - Encrypted files - Environment variable managers (direnv)
Advanced Authentication Patterns¶
API Key Rotation Script¶
#!/bin/bash
# rotate-api-key.sh
# Generate new key
NEW_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
echo "New API key: $NEW_KEY"
# Update Kubernetes secret
kubectl create secret generic secretzero-api-key \
--from-literal=api-key=$NEW_KEY \
--dry-run=client -o yaml | kubectl apply -f -
# Rolling restart
kubectl rollout restart deployment/secretzero-api
# Wait for rollout
kubectl rollout status deployment/secretzero-api
echo "API key rotated successfully"
Multi-Key Support (Future)¶
Currently, SecretZero supports a single API key. For multi-key support:
# Example implementation (not currently supported)
API_KEYS = {
"ci-cd-key": {"name": "CI/CD", "permissions": ["read", "sync"]},
"admin-key": {"name": "Admin", "permissions": ["*"]},
"monitoring-key": {"name": "Monitoring", "permissions": ["read"]},
}
OAuth2/OIDC Integration (Future)¶
For enterprise deployments, consider OAuth2/OIDC:
# Future configuration example
auth:
type: oauth2
issuer: https://auth.example.com
audience: secretzero-api
scopes:
- secretzero:read
- secretzero:write
Troubleshooting Authentication¶
Check API Key is Set¶
# Verify environment variable
echo $SECRETZERO_API_KEY
# Check if server is using it
curl http://localhost:8000/secrets
# Should return 401 if key is set
Test Authentication¶
# Should fail (401)
curl -i http://localhost:8000/secrets
# Should succeed (200)
curl -i -H "X-API-Key: $SECRETZERO_API_KEY" \
http://localhost:8000/secrets
Debug Authentication Issues¶
Check server logs:
# If running with systemd
journalctl -u secretzero-api -f
# If running in Docker
docker logs secretzero-api -f
# If running directly
secretzero-api --log-level debug
Common issues:
-
Extra whitespace in API key
-
Wrong header name
-
Must be
X-API-Key(case-sensitive) -
API key not set on server
-
Check server environment variables
-
API key set but still accepts unauthenticated requests
- Restart the server after setting the environment variable
Next Steps¶
- Learn about all available endpoints
- Use the Python client for easier authentication handling
- Set up production deployment with proper security
- Review audit logs to monitor access
Security Disclosure¶
If you discover a security vulnerability in SecretZero's authentication system, please report it to the maintainers privately through GitHub's security advisory system.