Key Configuration
This document explains how to create and configure RSA keys for the auth service’s token exchange feature.
Overview
Section titled “Overview”The auth service uses RSA keys to sign enriched JWT tokens during token exchange. These tokens contain governance organization/project context, roles, DID key claims, and IDP metadata that may not be present in the original IDP token.
Key Configuration Methods
Section titled “Key Configuration Methods”The service supports three methods for configuring RSA keys, in order of precedence:
1. Environment Variable (Recommended for Production)
Section titled “1. Environment Variable (Recommended for Production)”Provide the private key directly via the AUTH_SERVICE_PRIVATE_KEY environment variable.
# Generate a 2048-bit RSA private keyopenssl genrsa -out auth-service-key.pem 2048
# Set the environment variable with the key contentexport AUTH_SERVICE_PRIVATE_KEY="$(cat auth-service-key.pem)"
# Optionally set a custom key ID (otherwise auto-generated)export AUTH_SERVICE_KEY_ID="auth-service-prod-001"Advantages:
- No file system access required
- Easy integration with secrets management systems
- Suitable for containerized deployments
2. File-Based Configuration
Section titled “2. File-Based Configuration”The service can read keys from a file path on the filesystem.
# Generate the keyopenssl genrsa -out /secure/path/auth-service-key.pem 2048
# Set the path via environment variableexport AUTH_SERVICE_KEY_PATH="/secure/path/auth-service-key.pem"
# The service will automatically create a .kid file for the key IDDefault path: /tmp/auth-service-key.pem (if AUTH_SERVICE_KEY_PATH not set)
Advantages:
- Keys persist across restarts
- Can use existing key management workflows
- Suitable for VM-based deployments
3. Auto-Generation (Development Only)
Section titled “3. Auto-Generation (Development Only)”If no key is provided, the service automatically:
- Generates a 2048-bit RSA key pair
- Saves it to the configured or default path
- Creates a unique key ID
Advantages:
- Zero configuration for development
- Quick setup for testing
Warning: Auto-generated keys may be lost on container restart if not using persistent storage.
Key Specifications
Section titled “Key Specifications”- Type: RSA private key
- Size: 2048 bits (hardcoded in the service)
- Format: PEM-encoded
- Supported Encodings: PKCS1 or PKCS8
- Signing Algorithm: RS256 (RSA with SHA-256)
- Key ID Format:
auth-service-{8-hex-chars}(auto-generated from the first UUID segment) or custom
Deployment Examples
Section titled “Deployment Examples”Kubernetes
Section titled “Kubernetes”The Auth Service Helm chart injects AUTH_SERVICE_PRIVATE_KEY and AUTH_SERVICE_KEY_ID from a templated Kubernetes Secret. Provision the key material through your secret manager of choice (AWS Secrets Manager, Azure Key Vault, GCP Secret Manager) and wire it into the release-specific Helm values rather than creating secrets out-of-band.
Docker Compose
Section titled “Docker Compose”services: auth-service: image: auth-service:latest environment: AUTH_SERVICE_PRIVATE_KEY: | -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEA... -----END RSA PRIVATE KEY----- AUTH_SERVICE_KEY_ID: auth-service-dev-001Generating Keys
Section titled “Generating Keys”Basic Key Generation
Section titled “Basic Key Generation”# Generate private keyopenssl genrsa -out auth-service-private.pem 2048
# Extract public key (for documentation/verification)openssl rsa -in auth-service-private.pem -pubout -out auth-service-public.pem
# View key detailsopenssl rsa -in auth-service-private.pem -text -nooutGenerate with Password Protection (convert before use)
Section titled “Generate with Password Protection (convert before use)”# Generate encrypted keyopenssl genrsa -aes256 -out auth-service-private-encrypted.pem 2048
# Remove password for service useopenssl rsa -in auth-service-private-encrypted.pem -out auth-service-private.pemConvert Between Formats
Section titled “Convert Between Formats”# PKCS1 to PKCS8openssl pkcs8 -topk8 -inform PEM -outform PEM -nocrypt \ -in auth-service-private.pem -out auth-service-private-pkcs8.pem
# PKCS8 to PKCS1openssl rsa -in auth-service-private-pkcs8.pem -out auth-service-private-pkcs1.pemPublic Key Access
Section titled “Public Key Access”The public key is automatically exposed via the JWKS endpoint:
# Get the JWKS (JSON Web Key Set)curl http://localhost:8080/api/v1/auth/.well-known/jwks.json
# Response format{ "keys": [ { "kty": "RSA", "use": "sig", "kid": "auth-service-prod-001", "alg": "RS256", "n": "...", // Modulus (base64url) "e": "AQAB" // Exponent (base64url) } ]}External services use this endpoint to validate tokens issued by the auth service.
Key Rotation
Section titled “Key Rotation”Planned Rotation Process
Section titled “Planned Rotation Process”-
Generate new key pair
Terminal window openssl genrsa -out auth-service-key-new.pem 2048 -
Update configuration
Terminal window export AUTH_SERVICE_PRIVATE_KEY="$(cat auth-service-key-new.pem)"export AUTH_SERVICE_KEY_ID="auth-service-prod-002" # New ID -
Deploy carefully
- Rolling update in Kubernetes
- Blue-green deployment
- Gradual instance replacement
-
Monitor
- Old tokens remain valid until expiration
- New tokens use the new key
- The current JWKS endpoint exposes the active signing key only, so rotate during a window where old access tokens can expire naturally or downstream validators can tolerate the key change
Emergency Rotation
Section titled “Emergency Rotation”If a key is compromised:
- Generate and deploy new key immediately
- Reduce token expiration time temporarily
- Force re-authentication where possible
- Monitor for unauthorized token usage
Security Best Practices
Section titled “Security Best Practices”Key Storage
Section titled “Key Storage”- Never commit private keys to version control
- Use secrets management systems in production:
- Kubernetes Secrets
- AWS Secrets Manager
- HashiCorp Vault
- Azure Key Vault
- Restrict file permissions to 0600 for key files
- Encrypt keys at rest in production environments
Key Lifecycle
Section titled “Key Lifecycle”-
Rotate keys periodically
- Production: Every 90 days
- Staging: Every 180 days
- Development: As needed
-
Monitor key usage through logs:
grep "Issued enriched token" auth-service.log -
Audit key access in production environments
Operational Security
Section titled “Operational Security”- Separate keys per environment (dev, staging, prod)
- Use different key IDs to track key usage
- Implement key escrow for disaster recovery
- Document key rotation procedures
Troubleshooting
Section titled “Troubleshooting”Common Issues
Section titled “Common Issues”Service fails to start with key error:
Error: failed to load or generate key: failed to parse private key- Check key format (must be PEM)
- Verify no extra whitespace in environment variable
- Ensure proper line endings (LF, not CRLF)
Token validation fails:
Error: token signature is invalid- Verify correct public key in JWKS
- Check key ID matches between token and JWKS
- Ensure token hasn’t been modified
Auto-generated key lost:
- Check default path:
/tmp/auth-service-key.pem - Look for backup in service logs
- Generate new key and restart
Debugging Commands
Section titled “Debugging Commands”# Verify key formatopenssl rsa -in auth-service-key.pem -check
# Test key with sample JWTecho '{"test": "data"}' | jwt encode -k auth-service-key.pem -a RS256
# Decode and verify tokenjwt decode -k auth-service-public.pem YOUR_TOKEN
# Check JWKS endpointcurl -s http://localhost:8080/api/v1/auth/.well-known/jwks.json | jqMigration Considerations
Section titled “Migration Considerations”When migrating from other token signing methods:
- Dual validation period: Support both old and new tokens
- Gradual rollout: Update services incrementally
- Monitor error rates: Track validation failures
- Communicate changes: Notify API consumers
Related Documentation
Section titled “Related Documentation”- Token Exchange - Overview of token exchange feature
- Refresh Tokens - Refresh-token behavior for exchanged tokens
- Auth Service API reference - generated from the service OpenAPI specification and available in the published docsite; Swagger UI is served at
/swagger/when enabled