initial commit
This commit is contained in:
53
docs/IMPLEMENTATION_STATUS.md
Normal file
53
docs/IMPLEMENTATION_STATUS.md
Normal file
@@ -0,0 +1,53 @@
|
||||
# HexaHost GameCloud — Implementation Status
|
||||
|
||||
Last updated: 2026-06-26
|
||||
|
||||
## Current phase: Phase 0 — Repository and foundations
|
||||
|
||||
### Completed
|
||||
|
||||
| Area | Status | Notes |
|
||||
|------|--------|-------|
|
||||
| Monorepo layout | Done | pnpm workspace, Turborepo |
|
||||
| Go node-agent | Done | Config, protocol types, health, agent loop stub |
|
||||
| Go edge-gateway | Stub | Disabled by default; Phase 8 |
|
||||
| Docker Compose dev stack | Done | PostgreSQL, Redis, MinIO, Mailpit, API, Worker, Web |
|
||||
| Environment template | Done | `.env.example` |
|
||||
| CI pipeline | Done | Lint, typecheck, tests, Go tests, build |
|
||||
| Documentation skeleton | Done | ADR, architecture, threat model, installation |
|
||||
| WHMCS integration layout | Placeholder | Directory structure and README |
|
||||
| Deploy placeholders | Done | Traefik, Ansible, systemd, Prometheus |
|
||||
|
||||
### In progress / next (Phase 1)
|
||||
|
||||
- User registration, login, sessions
|
||||
- Email verification and password reset
|
||||
- TOTP 2FA
|
||||
- Admin bootstrap CLI
|
||||
- Prisma schema and migrations
|
||||
|
||||
### Abnahmekriterium Phase 0
|
||||
|
||||
- [x] Repository structure and configuration baseline
|
||||
- [x] Local infrastructure compose file
|
||||
- [x] Node agent builds and tests pass
|
||||
- [x] CI workflow defined
|
||||
- [ ] All services start locally end-to-end (requires `docker compose up` validation)
|
||||
- [ ] Full API/Web/Worker feature implementation (Phase 1+)
|
||||
|
||||
### Known limitations
|
||||
|
||||
- Edge gateway is intentionally not implemented (Join-to-Start is Phase 8).
|
||||
- API, Worker, and Web are minimal health-check stubs in Phase 0.
|
||||
- Traefik, Ansible, and production compose are documented but not fully implemented.
|
||||
- Node agent does not yet connect to the control plane WebSocket.
|
||||
|
||||
### Test commands
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
pnpm lint
|
||||
pnpm typecheck
|
||||
pnpm test
|
||||
cd apps/node-agent && make test
|
||||
```
|
||||
70
docs/adr/0001-monorepo-architecture.md
Normal file
70
docs/adr/0001-monorepo-architecture.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# ADR 0001: Monorepo architecture
|
||||
|
||||
- **Status:** Accepted
|
||||
- **Date:** 2026-06-26
|
||||
- **Deciders:** HexaHost GameCloud core team
|
||||
|
||||
## Context
|
||||
|
||||
HexaHost GameCloud is a multi-component platform: web UI, REST API, background workers, per-node Go agents, and a future edge gateway. Teams need shared contracts, consistent tooling, and atomic changes across services.
|
||||
|
||||
## Decision
|
||||
|
||||
Adopt a **pnpm + Turborepo monorepo** with the following application split:
|
||||
|
||||
| Component | Technology | Responsibility |
|
||||
|-----------|------------|----------------|
|
||||
| `apps/web` | Next.js (App Router) | User and admin UI |
|
||||
| `apps/api` | NestJS + Fastify | REST API, auth, orchestration |
|
||||
| `apps/worker` | NestJS / Node | BullMQ jobs, scheduler |
|
||||
| `apps/node-agent` | Go | Game node daemon, container lifecycle |
|
||||
| `apps/edge-gateway` | Go | TCP/UDP Join-to-Start (Phase 8) |
|
||||
| `packages/*` | TypeScript | Shared database, contracts, UI, config |
|
||||
|
||||
Supporting infrastructure:
|
||||
|
||||
- **PostgreSQL** — primary data store (Prisma ORM)
|
||||
- **Redis** — cache, locks, BullMQ queues
|
||||
- **S3-compatible storage** — backups and large artifacts
|
||||
- **Docker Compose** — local and control-plane production deployment
|
||||
- **systemd** — node agent on game nodes
|
||||
- **Traefik** — TLS termination and routing (external)
|
||||
|
||||
## Rationale
|
||||
|
||||
1. **pnpm workspaces** provide fast, disk-efficient dependency sharing across TypeScript packages.
|
||||
2. **Turborepo** caches build and test tasks with explicit dependency graphs.
|
||||
3. **NestJS + Fastify** offers structured modules, validation, and OpenAPI for the API layer.
|
||||
4. **Next.js** supports SSR/RSC, i18n, and a modern React UX without a proprietary UI kit.
|
||||
5. **Go** for node-agent and edge-gateway: small static binaries, strong concurrency, suitable for systemd daemons on game nodes.
|
||||
6. **Prisma** gives type-safe schema evolution and migration tooling shared by API and worker.
|
||||
|
||||
## Consequences
|
||||
|
||||
### Positive
|
||||
|
||||
- Single repository for cross-cutting changes (API contract + UI + worker).
|
||||
- Shared TypeScript types via `packages/contracts`.
|
||||
- Unified CI for all languages.
|
||||
- Clear deployment boundaries: Compose for control plane, systemd for agents.
|
||||
|
||||
### Negative
|
||||
|
||||
- Larger clone size and CI surface area.
|
||||
- Go modules live outside the Node dependency graph; versioning is manual.
|
||||
- Developers need Node 22, pnpm, Go 1.23, and Docker.
|
||||
|
||||
## Alternatives considered
|
||||
|
||||
| Alternative | Rejected because |
|
||||
|-------------|------------------|
|
||||
| Polyrepo | Harder to keep contracts and releases in sync |
|
||||
| Kubernetes | Explicitly out of MVP scope; Compose + VMs first |
|
||||
| Single language (all TypeScript) | Go better fits low-level node agent requirements |
|
||||
| tRPC only (no REST) | REST + OpenAPI required for WHMCS integration and public API docs |
|
||||
|
||||
## Related documents
|
||||
|
||||
- `docs/architecture/overview.md`
|
||||
- `docs/operations/installation.md`
|
||||
- `docs/security/threat-model.md`
|
||||
100
docs/architecture/overview.md
Normal file
100
docs/architecture/overview.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Architecture overview
|
||||
|
||||
HexaHost GameCloud is a self-hosted, multi-tenant platform for on-demand Minecraft servers.
|
||||
|
||||
## High-level diagram
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
subgraph users [Users]
|
||||
Browser[Web Browser]
|
||||
MC[Minecraft Client]
|
||||
end
|
||||
|
||||
subgraph control [Control Plane]
|
||||
Web[Next.js Web]
|
||||
API[NestJS API]
|
||||
Worker[BullMQ Worker]
|
||||
PG[(PostgreSQL)]
|
||||
Redis[(Redis)]
|
||||
S3[(S3 / MinIO)]
|
||||
end
|
||||
|
||||
subgraph nodes [Game Nodes]
|
||||
Agent[Go Node Agent]
|
||||
Docker[Docker Engine]
|
||||
Server[Minecraft Containers]
|
||||
end
|
||||
|
||||
subgraph future [Phase 8+]
|
||||
Edge[Edge Gateway]
|
||||
end
|
||||
|
||||
Browser --> Web
|
||||
Web --> API
|
||||
API --> PG
|
||||
API --> Redis
|
||||
Worker --> Redis
|
||||
Worker --> PG
|
||||
Worker --> S3
|
||||
API <-->|mTLS WebSocket| Agent
|
||||
Agent --> Docker
|
||||
Docker --> Server
|
||||
MC --> Server
|
||||
MC -.-> Edge
|
||||
Edge -.-> API
|
||||
```
|
||||
|
||||
## Component responsibilities
|
||||
|
||||
### Control plane
|
||||
|
||||
Runs on one or more VMs (Ubuntu 24.04 / Debian 13). Handles authentication, server metadata, scheduling decisions, billing projection, and job orchestration. **Never** mounts the Docker socket.
|
||||
|
||||
### Game nodes
|
||||
|
||||
Dedicated Linux VMs with Docker Engine (cgroup v2). Each node runs the **node-agent** as a systemd service. The agent connects **outbound** to the API via mTLS WebSocket and executes signed lifecycle commands locally.
|
||||
|
||||
### Data flow
|
||||
|
||||
1. User creates a server via the web UI.
|
||||
2. API persists state in PostgreSQL and enqueues provisioning jobs.
|
||||
3. Worker selects a node, reserves resources, and sends `server.provision` to the agent.
|
||||
4. Agent creates an isolated container and reports `server.state` transitions.
|
||||
5. Backups stream to S3; metadata stays in PostgreSQL.
|
||||
|
||||
### Security boundaries
|
||||
|
||||
| Boundary | Mechanism |
|
||||
|----------|-----------|
|
||||
| User → API | HTTPS, session cookies, CSRF, rate limits |
|
||||
| API → Agent | mTLS, node token, signed JSON messages |
|
||||
| Agent → Docker | Local Unix socket only, no remote exposure |
|
||||
| Game container → Internet | Egress rules, no internal network access by default |
|
||||
|
||||
## Repository layout
|
||||
|
||||
See [ADR 0001](../adr/0001-monorepo-architecture.md) for the full monorepo structure.
|
||||
|
||||
## Protocol
|
||||
|
||||
Agent communication uses versioned JSON envelopes over WebSocket. Message types include `agent.hello`, `agent.heartbeat`, `server.start`, and `server.state`. See `apps/node-agent/internal/protocol/messages.go`.
|
||||
|
||||
## Deployment models
|
||||
|
||||
| Environment | Mechanism |
|
||||
|-------------|-----------|
|
||||
| Local development | `deploy/compose/compose.dev.yml` |
|
||||
| Production control plane | Docker Compose + Traefik |
|
||||
| Game nodes | Ansible + systemd node-agent |
|
||||
|
||||
## Phase roadmap
|
||||
|
||||
| Phase | Focus |
|
||||
|-------|-------|
|
||||
| 0 | Repository, infra, CI, docs |
|
||||
| 1 | Authentication |
|
||||
| 2 | Single-node vertical slice |
|
||||
| 3–7 | Panel features, multi-node, idle shutdown |
|
||||
| 8 | DNS, edge gateway, join-to-start |
|
||||
| 9 | Billing, production hardening |
|
||||
112
docs/operations/installation.md
Normal file
112
docs/operations/installation.md
Normal file
@@ -0,0 +1,112 @@
|
||||
# Local development installation
|
||||
|
||||
This guide covers setting up HexaHost GameCloud on a single machine for development.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Tool | Version |
|
||||
|------|---------|
|
||||
| Node.js | 22.x |
|
||||
| pnpm | 9.x |
|
||||
| Go | 1.23+ |
|
||||
| Docker Engine | 24+ |
|
||||
| Docker Compose | v2 |
|
||||
|
||||
Optional:
|
||||
|
||||
- `make` (for node-agent)
|
||||
- Traefik with external network `traefik-network`
|
||||
|
||||
## 1. Clone and configure
|
||||
|
||||
```bash
|
||||
git clone <repository-url> hexahost-gamecloud
|
||||
cd hexahost-gamecloud
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
Edit `.env` and set at minimum:
|
||||
|
||||
- `SESSION_SECRET` and `ENCRYPTION_KEY` — generate with `openssl rand -base64 32`
|
||||
- `DATABASE_URL`, `REDIS_URL` — defaults work with compose
|
||||
- `NODE_ID` — any unique string for local agent testing
|
||||
|
||||
## 2. Install dependencies
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
## 3. Start infrastructure
|
||||
|
||||
```bash
|
||||
# Optional: create Traefik network if using external routing
|
||||
docker network create traefik-network 2>/dev/null || true
|
||||
|
||||
# Start PostgreSQL, Redis, MinIO, Mailpit, API, Worker, Web
|
||||
docker compose -f deploy/compose/compose.dev.yml --env-file .env up -d
|
||||
```
|
||||
|
||||
Verify health:
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:3001/healthz
|
||||
curl -s http://localhost:3000/api/health
|
||||
```
|
||||
|
||||
Mailpit UI: http://localhost:8025
|
||||
MinIO console: http://localhost:9001 (default `minioadmin` / `minioadmin`)
|
||||
|
||||
## 4. Run applications locally (without Docker)
|
||||
|
||||
Alternatively, run only infrastructure in Docker and apps on the host:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose/compose.dev.yml --env-file .env up -d postgres redis minio mailpit
|
||||
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
## 5. Node agent (optional)
|
||||
|
||||
```bash
|
||||
cd apps/node-agent
|
||||
export NODE_ID=local-dev-node
|
||||
export NODE_AGENT_PUBLIC_URL=ws://localhost:3001/api/v1/nodes/ws
|
||||
make build
|
||||
make run
|
||||
```
|
||||
|
||||
Health: http://localhost:9100/healthz
|
||||
|
||||
## 6. Quality checks
|
||||
|
||||
```bash
|
||||
pnpm lint
|
||||
pnpm typecheck
|
||||
pnpm test
|
||||
cd apps/node-agent && make test
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### `traefik-network` not found
|
||||
|
||||
Either create the network (`docker network create traefik-network`) or remove the external network from compose for pure local dev.
|
||||
|
||||
### Port conflicts
|
||||
|
||||
Adjust `API_PORT`, `WEB_PORT`, `POSTGRES_PORT`, `REDIS_PORT` in `.env`.
|
||||
|
||||
### MinIO bucket missing
|
||||
|
||||
The `minio-init` service creates the bucket on first start. Restart compose if it failed:
|
||||
|
||||
```bash
|
||||
docker compose -f deploy/compose/compose.dev.yml up minio-init
|
||||
```
|
||||
|
||||
## Next steps
|
||||
|
||||
- Phase 1: database migrations and authentication — see `docs/IMPLEMENTATION_STATUS.md`
|
||||
- Production deployment: `deploy/traefik/`, `deploy/ansible/` (Phase 9)
|
||||
59
docs/security/threat-model.md
Normal file
59
docs/security/threat-model.md
Normal file
@@ -0,0 +1,59 @@
|
||||
# Threat model (initial)
|
||||
|
||||
**Status:** Draft — Phase 0
|
||||
**Last updated:** 2026-06-26
|
||||
**Scope:** HexaHost GameCloud control plane, workers, node agents, and game containers.
|
||||
|
||||
## Assets
|
||||
|
||||
- User credentials and sessions
|
||||
- Node enrollment tokens and mTLS certificates
|
||||
- Game server world data and backups
|
||||
- Billing and audit records
|
||||
- Internal service credentials (database, Redis, S3)
|
||||
|
||||
## Trust boundaries
|
||||
|
||||
1. Public internet → Web/API (untrusted)
|
||||
2. API ↔ Node Agent (mutually authenticated)
|
||||
3. Node Agent → Docker (trusted local host)
|
||||
4. Game container → network (untrusted, tenant-controlled code)
|
||||
|
||||
## Threat catalog
|
||||
|
||||
| ID | Threat | Description | Mitigation (planned / partial) | Residual risk |
|
||||
|----|--------|-------------|-------------------------------|---------------|
|
||||
| T01 | Malicious registered user | Abuse file upload, API, or quotas | AuthZ on every endpoint, path validation, rate limits, quotas | Medium — requires ongoing abuse monitoring |
|
||||
| T02 | Compromised mod/plugin file | Malicious JAR in server directory | Server-side install only, checksum validation, optional ClamAV | Medium |
|
||||
| T03 | Compromised user account | Attacker uses stolen session | 2FA, session revocation, login rate limits, audit log | Low–Medium |
|
||||
| T04 | Compromised node agent | Attacker controls agent process | mTLS, signed commands, no inbound agent port, cert rotation | Medium |
|
||||
| T05 | Compromised game container | Escape or lateral movement | Non-privileged containers, dropped caps, seccomp, network isolation | Medium |
|
||||
| T06 | Stolen agent token | Replay enrollment or impersonate node | One-time enrollment, token rotation, mTLS binding | Low |
|
||||
| T07 | Replay of lifecycle message | Duplicate start/stop commands | Idempotency keys, generation counters, message IDs | Low |
|
||||
| T08 | Path traversal | Access files outside server directory | Server-side path normalization, deny `..` and symlinks | Low |
|
||||
| T09 | ZIP bomb | Decompression DoS via upload | Size, file count, compression ratio limits | Low |
|
||||
| T10 | Symlink attack | Escape via symlink in archive | Reject symlinks on extract by default | Low |
|
||||
| T11 | SSRF via resource pack URL | Server fetches internal URLs | URL allowlist, block RFC1918, validate schemes | Medium |
|
||||
| T12 | Internal port scan from game server | Scan control plane from container | Egress firewall, no host network mode | Low–Medium |
|
||||
| T13 | Secret exfiltration via logs | Tokens in console or API logs | Structured logging with redaction, no secrets in env dumps | Low |
|
||||
| T14 | Queue flooding | Enqueue excessive jobs | Per-user rate limits, queue depth alerts | Medium |
|
||||
| T15 | Start spam | Repeated start requests (join-to-start) | Rate limits, idempotent starts, captcha at edge (Phase 8) | Medium (Phase 8) |
|
||||
| T16 | Backup manipulation | Tamper with or replace backups | SHA-256 checksums, server-side encryption, immutable S3 policies | Low |
|
||||
| T17 | Supply-chain attack | Compromised npm/go dependency | Lockfiles, CI audit, SBOM, image scanning | Medium |
|
||||
| T18 | Manipulated runtime image | Unauthorized Docker image | Digest-pinned images, admin-managed catalog only | Low |
|
||||
| T19 | DNS takeover | Hijack game subdomain | DNS provider auth, monitoring, short TTL only where needed | Low |
|
||||
| T20 | WebSocket hijacking | Steal or inject agent channel | mTLS, origin checks, correlation IDs | Low |
|
||||
| T21 | Tenant isolation failure | User A accesses User B server | Server-side authZ, row-level checks, audit | Critical — must test continuously |
|
||||
|
||||
## Out of scope (documented dependencies)
|
||||
|
||||
- DDoS mitigation at network edge (external infrastructure)
|
||||
- Physical host compromise
|
||||
- Mojang/Microsoft account security
|
||||
|
||||
## Next steps
|
||||
|
||||
- [ ] STRIDE review per component (Phase 1)
|
||||
- [ ] Container seccomp/AppArmor profiles (Phase 2)
|
||||
- [ ] Penetration test before production (Phase 9)
|
||||
- [ ] `docs/security/container-isolation.md`, `secrets.md`, `data-retention.md`
|
||||
Reference in New Issue
Block a user