Enhance API with OIDC support, including login and callback endpoints. Update environment variables for OIDC configuration in .env.example. Add new features to the catalog service for listing software families, Minecraft versions, and deployment regions. Implement server management actions such as kill, delete, and update in the servers module. Integrate feature flags for maintenance mode in server operations. Update pnpm-lock.yaml with new dependencies and versions.
Some checks failed
CI / Node — lint, typecheck, test, build (push) Failing after 12s
CI / Go — node-agent tests (push) Failing after 9s
CI / Go — edge-gateway build (push) Successful in 17s

This commit is contained in:
TheOnlyMace
2026-07-05 18:39:53 +02:00
parent bf36cb3159
commit 50cd4b3ffd
225 changed files with 17824 additions and 436 deletions

View File

@@ -0,0 +1,9 @@
# Backup Encryption at Rest
GameCloud backups are stored in S3-compatible object storage. Production deployments should enable:
1. **Bucket SSE** — Server-side encryption (AES-256) on the backup bucket
2. **Application envelope encryption** (roadmap) — Per-backup data keys wrapped with `ENCRYPTION_KEY`
3. **Key rotation** — Documented in `docs/security/secrets.md`
Current MVP stores backups without client-side encryption. Enable bucket policies before production.

View File

@@ -0,0 +1,14 @@
# Container Hardening
The node-agent applies baseline Docker hardening:
- `cap_drop: ALL` with minimal adds
- `security_opt: no-new-privileges`
- PID limits and log rotation
## Roadmap (Post-MVP)
- **Seccomp** — Custom profile per software family under `deploy/seccomp/`
- **AppArmor** — Node-level profiles for game server containers
See `apps/node-agent/internal/docker/client.go` for current defaults.

View File

@@ -0,0 +1,71 @@
# Container isolation
How HexaHost GameCloud isolates Minecraft server workloads on game nodes.
## Model
Each customer server runs as a **non-privileged Docker container** on a dedicated game node. The node-agent creates and manages containers; customers never receive Docker socket access.
```
Control plane (trusted) ──mTLS──► Node agent (trusted) ──► Game container (untrusted)
```
## Container hardening (target profile)
| Control | Setting |
|---------|---------|
| User | Non-root UID inside container |
| Privileges | `--privileged=false` |
| Capabilities | Drop ALL, add only required (none for vanilla Java) |
| seccomp | Docker default or custom profile (Phase 2) |
| AppArmor | Docker default profile |
| Network | Bridge network per server; no `host` network mode |
| Read-only root | Where compatible with selected software family |
| Memory / CPU | cgroup limits from plan slug |
| PIDs limit | Prevents fork bombs |
## Network isolation
- Game containers reach the internet for Minecraft auth and mod downloads only through controlled egress
- No route to control plane PostgreSQL, Redis, or internal APIs
- Node-agent management port (`9100`) bound to localhost or management VLAN only
See threat T05 and T12 in [threat model](threat-model.md).
## Storage isolation
- Per-server data directory on node disk: `/var/lib/hgc-node/servers/{serverId}/`
- Path traversal prevented server-side; symlinks rejected on archive extract
- Backups uploaded to object storage — not readable by other tenants
## Image policy
- Only catalog-approved runtime images (digest-pinned)
- Customers cannot push custom images
- Periodic image vulnerability scan in CI (Phase 9)
## Multi-tenant on one node
The scheduler enforces RAM and server count limits per node. There is no shared filesystem between server containers except the read-only image layers.
## Operator responsibilities
| Task | Frequency |
|------|-----------|
| Docker security updates on nodes | Monthly |
| Review AppArmor/seccomp profiles after Minecraft/Java major bumps | Per release |
| Audit `docker ps` for unexpected privileged containers | Weekly |
Bootstrap hardening via `deploy/ansible/game-node.yml`.
## Verification
- Attempt cross-container network scan from test server (should fail to reach agent port)
- Confirm `docker inspect` shows `Privileged: false`
- Penetration test before production go-live
## Related
- [Threat model](threat-model.md)
- [Game node operations](../operations/game-node.md)
- [Secrets](secrets.md)

View File

@@ -0,0 +1,66 @@
# Data retention
Retention periods and deletion procedures for HexaHost GameCloud customer and operational data.
## Policy summary
| Data type | Retention | Deletion trigger |
|-----------|-----------|------------------|
| Account profile | Life of account + 90 days | Account deletion request |
| Game server world (live) | Life of service | Terminate in WHMCS / admin |
| Automated backups | Per plan (730 days default) | Lifecycle job + S3 expiry |
| Manual backup downloads | Link valid 24 h; object 7 days | Worker cleanup |
| Audit log | 24 months | Scheduled purge job |
| Application logs (Loki) | 30 days (`720h` in loki-config) | Loki compactor |
| Session tokens | 7 days idle / 30 days max | Redis TTL |
| WHMCS sync events | 90 days acknowledged | Addon retention SQL |
| DNS record history | 12 months | DB maintenance |
| Metering / usage samples | 13 months (billing) | Aggregated then purged |
Adjust periods in contracts and WHMCS product terms. Document customer-facing retention in your privacy policy (German: *Datenschutzerklärung*).
## Backup retention
Backup objects live under `s3://{bucket}/backups/{serverId}/`. The worker applies plan-based retention:
- Free/starter plans: 7 daily slots
- Pro plans: 14 daily + 4 weekly
- Enterprise: configurable via admin
Expired backups are deleted from object storage; metadata rows in PostgreSQL are soft-deleted then purged after 7 days.
## Termination flow
When WHMCS calls `TerminateAccount`:
1. Server stopped on node
2. Final backup optional (plan-dependent)
3. World data on node deleted within 24 h
4. S3 prefix `backups/{serverId}/` deleted within 7 days
5. PostgreSQL server row anonymised or hard-deleted per legal requirement
## GDPR / DSGVO considerations
- **Right to erasure:** Export then delete user row; cascade removes owned servers
- **Data portability:** World export ZIP + backup download via panel
- **Processor agreement:** Required between you (controller) and HexaHost GameCloud operator if different entity
Logs may contain IP addresses and user IDs — treat as personal data where applicable.
## Operational data
| Store | Purge method |
|-------|--------------|
| PostgreSQL audit | `DELETE FROM audit_events WHERE created_at < NOW() - INTERVAL '24 months'` (automated job) |
| Redis | TTL-based; no long-term PII |
| MinIO access logs | Provider lifecycle rule |
## Legal hold
Suspend automated deletion for accounts under litigation hold. Flag in admin metadata; worker skips purge for affected `serverId`.
## Related
- [Backup and restore](../operations/backup-restore.md)
- [Object storage](../operations/object-storage.md)
- [Threat model](threat-model.md) — T16 backup integrity

95
docs/security/secrets.md Normal file
View File

@@ -0,0 +1,95 @@
# 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)