96 lines
3.2 KiB
Markdown
96 lines
3.2 KiB
Markdown
# Secrets management
|
|
|
|
Guidelines for generating, storing, and rotating secrets in HexaHost GameCloud deployments.
|
|
|
|
## Classification
|
|
|
|
| Secret | Location | Rotation |
|
|
|--------|----------|----------|
|
|
| `SESSION_SECRET` | `.env.prod` on control plane | Quarterly; invalidates sessions |
|
|
| `ENCRYPTION_KEY` | `.env.prod` | Annually; requires re-encryption plan |
|
|
| `POSTGRES_PASSWORD` | `.env.prod`, compose | Annually |
|
|
| `S3_ACCESS_KEY` / `S3_SECRET_KEY` | `.env.prod`, MinIO IAM | Quarterly |
|
|
| `WHMCS_API_SECRET` | GameCloud `.env.prod` + WHMCS addon | On compromise; per installation |
|
|
| `WHMCS_WEBHOOK_SECRET` | Both sides | On compromise |
|
|
| `NODE_TOKEN` | Per-node enrollment | One-time at enroll; rotate on rebuild |
|
|
| Node mTLS keys | `/etc/hgc-node/` on game nodes | Before cert expiry |
|
|
| `EDGE_INTERNAL_API_KEY` | Edge gateway + API | Quarterly |
|
|
| `RFC2136_KEY_SECRET` | API/worker env | Annually |
|
|
| `STRIPE_*` | API env (if used) | Per Stripe dashboard policy |
|
|
| Traefik `acme.json` | `/letsencrypt/` | Auto-renewed; backup only |
|
|
|
|
## Generation
|
|
|
|
```bash
|
|
# 32-byte secrets (SESSION_SECRET, ENCRYPTION_KEY, API secrets)
|
|
openssl rand -base64 32
|
|
|
|
# WHMCS integration — minimum 32 characters
|
|
openssl rand -hex 24
|
|
```
|
|
|
|
Never use development defaults from `.env.example` in production.
|
|
|
|
## Storage rules
|
|
|
|
1. **Never commit** `.env`, `.env.prod`, or key material to git
|
|
2. Restrict file permissions: `chmod 600 .env.prod`, owner `gamecloud`
|
|
3. Prefer secret manager (HashiCorp Vault, SOPS, cloud provider SM) over plain files for multi-host
|
|
4. Ansible: use `ansible-vault` for inventory secrets referenced in `deploy/ansible/`
|
|
|
|
## Distribution
|
|
|
|
| From | To | Channel |
|
|
|------|-----|---------|
|
|
| Operator | Control plane | SSH + encrypted archive |
|
|
| Control plane | WHMCS admin | Out-of-band (password manager share) |
|
|
| Control plane | Game node | Enrollment token via secure ticket |
|
|
|
|
WHMCS **Integration ID** is not secret but must match exactly on both sides.
|
|
|
|
## Rotation procedures
|
|
|
|
### SESSION_SECRET
|
|
|
|
1. Generate new value
|
|
2. Update `.env.prod`, restart `api` and `web`
|
|
3. All users must log in again
|
|
|
|
### WHMCS_API_SECRET
|
|
|
|
1. Update GameCloud `.env.prod` and restart API
|
|
2. Update WHMCS addon **API Secret** immediately after — expect brief auth failures
|
|
3. No WHMCS module reinstall required
|
|
|
|
### Database password
|
|
|
|
1. `ALTER USER gamecloud PASSWORD '...'` in PostgreSQL
|
|
2. Update `DATABASE_URL` / `POSTGRES_PASSWORD` in `.env.prod`
|
|
3. Restart `api`, `worker`
|
|
|
|
### Node token compromise
|
|
|
|
1. Revoke token in admin API for affected `NODE_ID`
|
|
2. Issue new enrollment token
|
|
3. Reinstall node-agent with new token and fresh mTLS cert
|
|
|
|
## Logging and redaction
|
|
|
|
- Structured logs must not print env dumps or Authorization headers
|
|
- WHMCS module calls redact `password`, `secret`, `apiSecret` in module logs
|
|
- OpenTelemetry spans must not include query strings with tokens
|
|
|
|
## Development vs production
|
|
|
|
| Variable | Development | Production |
|
|
|----------|-------------|------------|
|
|
| `INTEGRATION_MTLS_ENABLED` | `false` | `true` (recommended) |
|
|
| `NODE_TLS_SKIP_VERIFY` | `true` | `false` |
|
|
| Default MinIO credentials | Allowed | **Forbidden** |
|
|
|
|
## Related
|
|
|
|
- [Threat model](threat-model.md)
|
|
- [WHMCS security](../integrations/whmcs/security.md)
|
|
- [Data retention](data-retention.md)
|