Schlüssel-Proxy, Server-Anforderungen und gitleaks-Regel für API-Werk

- tools/ki-proxy: setzt API-Schlüssel aus der Windows-Anmeldeinformationsverwaltung ein,
  nur im Speicher, ohne Header-Protokoll; Tests gegen Platzhalter-Server
- docs/server-anforderungen.md für den ITM-Entwickler
- .gitleaks.toml erkennt zki_/zodl_/zocr_-Schlüssel
- CLAUDE.md, Plan, Tech-Stack: Schlüssel nie in .env, in der App verschlüsselt in der DB

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Christoph
2026-10-05 08:25:30 +02:00
co-authored by Claude Opus 5.5
parent 6d6f8f8f27
commit ca09d23a78
9 changed files with 716 additions and 4 deletions
+132
View File
@@ -0,0 +1,132 @@
# KI-BauIN – Server-Anforderungen (Staging und Produktion)
Stand: 5. Oktober 2026. Für den ITM-Entwickler, der die Server aufbaut. Hintergründe stehen in
`docs/tech-stack.md`, Termine in `docs/projektplan.md`.
## Überblick
- **Zwei Umgebungen, gleich aufgebaut:** Staging (Pilot mit BauIn, ab KW 44) und Produktion
(ab KW 51). Getrennte Server, getrennte Datenbanken, getrennte API-Schlüssel.
- **Ein Server je Umgebung reicht:** Anwendung, MySQL, Meilisearch und Worker laufen auf derselben VM.
- **Betrieb nativ**, ohne Docker: Nginx, PHP-FPM, Worker unter systemd, Cron für den Scheduler.
- **Die Versionen entsprechen der Entwicklung.** Abweichungen bitte vorher abstimmen.
## Ausstattung je Server (Vorschlag)
| | Vorschlag | Anmerkung |
|---|---|---|
| Betriebssystem | Ubuntu Server 24.04 LTS | Debian 12/13 geht auch |
| CPU | 4 vCPU | |
| RAM | 16 GB | Meilisearch hält Vektoren mit 4.096 Dimensionen; endgültig nach dem Meilisearch-Test (KW 41) |
| Platte | 150 GB SSD, erweiterbar | Daten (MySQL, Uploads, Meilisearch) am besten auf eigenem Volume |
| Verschlüsselung | Festplattenverschlüsselung gewünscht | Entscheidung mit BauIn offen |
| Zeitzone | Europe/Berlin, NTP aktiv | |
## Software
| Paket | Version | Hinweise |
|---|---|---|
| PHP (FPM und CLI) | 8.5 | Erweiterungen: bcmath, ctype, curl, dom, fileinfo, gd, iconv, intl, mbstring, opcache, openssl, pcntl, pdo_mysql, simplexml, sodium, tokenizer, xml, xmlreader, xmlwriter, zip, zlib |
| Composer | 2.x | |
| Node.js mit npm | 22 LTS | nur zum Bauen der Oberfläche beim Deployment |
| MySQL | 8.4 LTS | utf8mb4 / utf8mb4_unicode_ci, nur auf 127.0.0.1, `max_allowed_packet` mindestens 64M |
| Meilisearch | v1.54.2 (fest) | eigener systemd-Dienst, nur auf 127.0.0.1:7700, Master-Key gesetzt, `--no-analytics` |
| Nginx | aktuelle Version der Distribution | `client_max_body_size 200M` (ZIP mit LVs), HTTP → HTTPS |
| poppler-utils, qpdf | Distribution | Text und Seitenzahlen aus PDFs lesen, große PDFs teilen (Grenze der KI-API: 50 MB) |
| git, unzip | Distribution | Deployment aus Gitea |
## Dienste
- `php8.5-fpm`: Pool läuft unter einem eigenen Benutzer (Vorschlag `kibauin`).
- `nginx`
- `mysql`
- `meilisearch`: eigener Benutzer, Daten auf dem Datenvolume.
- **Worker:** zwei Instanzen `php artisan queue:work database --sleep=3 --tries=3 --max-time=3600`
unter systemd, Benutzer `kibauin`, mit automatischem Neustart.
- **Scheduler:** Cron-Zeile `* * * * * cd /srv/ki-bauin/current && php artisan schedule:run`.
Die Vorlagen für den Nginx-Server-Block, die systemd-Units, die Cron-Zeile, das Deploy-Skript und
das Backup-Skript liefern wir bis KW 44 im Repository (`deploy/`).
## Netzwerk
- **Eingehend:** nur 443 sowie 80 für die Weiterleitung und die Zertifikatsausstellung.
SSH nur mit Schlüssel und möglichst nur über VPN oder freigegebene IP-Adressen.
- **Zugriff für BauIn:** offen, ob aus dem Internet mit Login und 2FA oder nur über VPN
bzw. freigegebene IP-Adressen (Fragenkatalog B2).
- **Ausgehend:**
- `https://api-werk.de` (KI-API)
- der Gitea von ITM (Deployment)
- SMTP für Benachrichtigungen
- Paketquellen für Updates
Die Anwendung selbst lädt nichts von fremden Servern.
- **MySQL und Meilisearch** sind nur lokal erreichbar.
## Verzeichnisse
```
/srv/ki-bauin/
├── releases/<zeitstempel>/ je Deployment ein Verzeichnis
├── current -> releases/… aktive Version (Symlink)
└── shared/
├── .env Rechte 0600, Besitzer kibauin
└── storage/ u. a. storage/app/private = Uploads (nie über Nginx ausliefern)
```
## Konfiguration und Geheimnisse
- **In `shared/.env`** stehen `APP_KEY`, das Datenbank-Passwort, der Meilisearch-Master-Key und
die Mail-Zugangsdaten.
- **Die Schlüssel der KI-API stehen nicht in der `.env`.** Sie werden in der Anwendung unter
Verwaltung → Einstellungen eingetragen und verschlüsselt in der Datenbank gespeichert. Danach
sind sie nur noch beschreibbar, nicht mehr lesbar.
- **Der `APP_KEY` muss zusätzlich sicher außerhalb des Servers aufbewahrt werden**, z. B. im
Passwortmanager. Ohne ihn lassen sich verschlüsselte Felder aus einem Backup nicht wiederherstellen.
## Backups (Vorschlag, Entscheidung mit BauIn offen)
- **Was:** täglich `mysqldump --single-transaction`, dazu `shared/storage/app/private` und
`shared/.env`.
- **Wie:** vor dem Verlassen des Servers verschlüsseln (z. B. restic), Ziel außerhalb des Servers.
- **Aufbewahrung:** z. B. 7 tägliche, 4 wöchentliche, 6 monatliche Stände.
- **Meilisearch** wird nicht gesichert, der Index wird aus MySQL neu aufgebaut.
- **Restore-Test:** einmal vollständig vor dem Produktivstart (KW 3/2027).
## Überwachung
- **Lebenszeichen:** `https://<domain>/up` antwortet mit HTTP 200.
- **Worker und Scheduler** melden Lebenszeichen, fehlgeschlagene Jobs werden gezählt. Die
Artisan-Befehle dafür liefern wir.
- **Alarm per Mail**, wenn die Anwendung, ein Worker oder der Scheduler ausfällt, wenn die Platte
zu über 80 % voll ist oder wenn die KI-API nicht erreichbar ist.
## Deployment
Ablauf, als Skript geliefert:
1. Code aus dem Gitea holen.
2. `composer install --no-dev --optimize-autoloader`
3. `npm ci && npm run build`
4. `php artisan migrate --force`
5. Konfiguration, Routen und Views cachen.
6. `php artisan queue:restart`
7. PHP-FPM neu laden.
Wer im Betrieb deployt und Updates einspielt, ist noch offen (Fragenkatalog C12).
## Termine
| Bis | Was |
|---|---|
| KW 43 | Staging-Server mit SSH-Zugang und Grundinstallation |
| KW 44 | Staging fertig: Domain, Zertifikat, Dienste, erstes Deployment |
| KW 51 | Produktionsserver fertig |
| KW 3/2027 | Backups und Alarmierung in Produktion, Restore-Test |
## Offen
- Standort und Rechenzentrum der Server, Festplattenverschlüsselung
- Domain(s) und Zertifikat (Let's Encrypt oder eigenes)
- Ziel und Zuständigkeit der Backups
- Zugriff für BauIn: Internet oder VPN
- SMTP-Server und Absenderadresse