init des architektur beschreibenden MD...

noch kein code, nur REadme, ai.agent md s
This commit is contained in:
br committed 2026-09-29 22:45:38 +02:00
1 parent 7f59a5d9b7
commit 9861c25949
3 files changed
+488 -3

No files matched your search

+45
View File
@@ -0,0 +1,45 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Instruktionen
Lies die `.ai/*.md` Files. Diese liefern den Context für die App, die hier entstehen soll.
Maßgeblich ist aktuell [.ai/sultan-system-architecture.md](.ai/sultan-system-architecture.md) (Netzwerk-, Sicherheits-, Daten- und Anwendungsmodell inkl. SQL-Schema, Event-Format und Referenz-Compose-Files). Bei Widersprüchen zwischen diesem File und der Spec gilt die Spec.
## Projektstatus
Greenfield: Es existiert noch kein Go-Code, kein `go.mod`, keine Build-/Test-Toolchain. Build-, Lint- und Test-Befehle hier ergänzen, sobald sie existieren.
## Big Picture
Sultan ersetzt manuell gepflegtes Ingress-Routing (z. B. Nginx Proxy Manager): Backends deklarieren ihr Routing selbst (Traefik-Labels an Docker-Containern oder Drop-ins in `/etc/sultan.d/*.conf` für Bare-Metal/LAMP), ein Agent meldet das an einen zentralen Server, und Traefik auf dem Ingress-Knoten pollt daraus seine Konfiguration.
**Single Binary in Go** mit drei Subcommands:
- `sultan server` – Registry, Stream-Hub (hält Agent-Verbindungen im RAM, Dead-Node-Timeout 90s), Policy-Engine, Traefik-HTTP-Provider
- `sultan agent` – Watcher (Docker Events API auf `traefik.*`-Labels bzw. inotify auf `/etc/sultan.d`), State-Serializer (injiziert LAN- oder NetBird-IP `100.64.x.y` als Backend-Ziel), Transport mit Reconnect + exponentiellem Backoff
- `sultan token` – CLI für Schlüssel, Enrollment-Tokens, Lizenzausstellung
**Ports / Endpunkte des Servers:**
- `:8443` (TLS) – Control Plane, ausschließlich *ausgehend* vom Agent (NAT/CGNAT/DS-Lite-tauglich). Persistenter Stream (HTTP/2 oder SSE), 45s-Keepalive, Events werden sofort gepusht. Enrollment: `POST /api/v1/enroll`.
- `127.0.0.1:8080` – `GET /v1/traefik-config` (Traefik pollt alle 2–5s; flache Labels aller aktiven Nodes → verschachteltes Traefik-JSON) und `GET /metrics/checkmk` (Checkmk Local-Check-Format).
**Sicherheitsmodell (Kerninvarianten):**
- Server-TLS-Zertifikat self-signed (ECDSA P-256), Agent pinnt den SHA256-Fingerprint per TOFU in `known_servers`.
- Agent-Keys (Ed25519) werden nur lokal erzeugt und verlassen den Host nie; Enrollment tauscht Public Key + einmaligen Token gegen Mandanten-Zuordnung und signierten Capability-Lease. Danach ist jeder Heartbeat mit `node.key` signiert.
- Jeder Agent-Payload wird serverseitig gegen die Mandanten-Policy geprüft: Hosts in `Host(...)`-Regeln müssen in `allowed_domains` stehen (sonst ablehnen + Audit-Log), Routen über `max_routes` werden verworfen.
- Lizenzen (`license.json`) sind mit dem Ed25519-Server-Master-Key signiert.
**Stream-Events** (JSON: `event_id`, `timestamp`, `type`, `node_id`, `payload`): `service_state` (Agent→Server, vollständiger Label-Snapshot, nicht Delta), `node_command` (`re_enroll`/`drain`/`maintenance`), `lease_renew`, `error`.
**Persistenz:** SQLite unter `<data-dir>/sultan.db` (Default `/var/lib/sultan`), Tabellen `tenants`, `nodes`, `enrollment_tokens` (Tokens nur als Hash gespeichert).
**Policy/Lizenzablauf:** Mandanten-Status steuert das generierte Routing – Zahlungsverzug → Router auf Bezahlseite (402), Backend down/`service_down` → Statusseite 503 mit `Retry-After: 60`. Checkmk-Schwellen: WARN bei 30, CRIT bei 14 Tagen Restlaufzeit, bei Ablauf Umleitung auf Landingpage.
## Bekannte Unstimmigkeiten in der Spec
Vor der Implementierung mit dem User klären statt raten:
- Token-Präfix: `sltn_token_...` (Abschnitt 3.2) vs. `sltn_enroll_...` (Compose-Beispiel 7.2).
- Tenant-Status: Schema kennt `active`/`suspended_payment`/`quarantined`, Abschnitt 6.2 setzt `expired`.
- Stream-Transport ist offen: HTTP/2 *oder* SSE (SSE wäre nur Server→Agent; bidirektionale Events brauchen dann einen Rückkanal).
- Einige URLs in JSON/YAML-Blöcken der Spec sind durch Copy-Paste als Markdown-Links verstümmelt (`"[http://...](http://...)"`) – die nackte URL ist gemeint.