Fuenf von sechs Befunden einer externen Integration. Der sechste - unsignierte
Lizenzurteile - ist bestaetigt, aber bewusst nicht Teil dieses Commits.
1. Lizenzschluessel stand in der Kommandozeile
Der Agent nahm --license-key nur als Argument und las keine
Umgebungsvariablen. "ps" zeigt argv jedem Benutzer der Maschine - exakt die
Begruendung, mit der UPGRADE.md §5 den Crontab-Weg verwirft. Damit nahm das
SDK einen bereits geloesten Sicherheitsbefund zurueck.
Der Agent liest jetzt DC_LICENSE_KEY, DC_DOWNLOAD_USER und
DC_DOWNLOAD_PASSWORD, Umgebung vor Argument. LaunchUpdateAgent uebergibt
den Schluessel nicht mehr als Argument, sondern setzt die Variable auf dem
eigenen Prozess: das Kind erbt den Umgebungsblock, danach wird sie wieder
entfernt. Das funktioniert auch mit UseShellExecute=true, wo sich
ProcessStartInfo.Environment nicht setzen laesst.
2. --wait-timeout war nicht durchgereicht
Der Agent kannte den Parameter, LaunchUpdateAgent hatte keinen dafuer - es
galten fest 60 Sekunden. Eine Anwendung, die allein fuer host.StopAsync 30
Sekunden braucht, kommt damit gefaehrlich nah an die Grenze. Neu:
waitTimeoutSeconds. Ausserdem ist im Quelltext und in der Doku jetzt
festgehalten, dass exitCurrentApp:true ueber Environment.Exit(0) laeuft und
damit finally-Bloecke und IHostApplicationLifetime uebergeht - bei offenem
Zustand die falsche Wahl.
3. ILicensePrompt war tot
Der Konstruktor nahm es entgegen, legte es in _prompt ab und benutzte es
nirgends. Wer darauf eine headless-Story aufbaute, baute auf Sand. Neu:
EnsureLicensedAsync() - zwischengespeicherten Schluessel nehmen, sonst
fragen, pruefen, bei Ablehnung erneut fragen. allowPrompt:false lehnt ohne
Cache ab, statt auf eine Eingabe zu warten, die im Dienst nie kommt. Ein
voruebergehender Netzfehler fuehrt nicht zur erneuten Abfrage - der
Schluessel ist ja nicht falsch.
4. Der Packager warnte nur
Er bricht jetzt ab. Anlass war ein echter API-Schluessel in einem
oeffentlich abrufbaren Paket - und die Warnung war damals ausgerechnet
unterdrueckt, weil die Datei auf der preserve-Liste stand.
Zwei Stufen: Dateiname (appsettings.Local.json, master.key, *.pfx, *.db,
server_settings.xml) und Inhalt (gefuelltes Password=, sk-, ghp_,
dc_master_, AKIA, private Schluessel). Die Inhaltspruefung findet auch
Dateien mit unverdaechtigem Namen.
Platzhalter loesen bewusst nicht aus: "sk-DEIN-SCHLUESSEL-HIER" haette
sonst jede ausgelieferte Vorlage blockiert, und --allow-secrets waere nach
einer Woche Gewohnheit. Beim Erproben zuerst genau in diese Falle gelaufen.
5. BuildInfo.targets war nur per Pfad-Import zu haben
Die Anleitung empfahl einen <Import> ins Nachbar-Repository - das setzt
voraus, dass beide Arbeitskopien nebeneinander liegen und in derselben
Fassung stehen. Das Client-Projekt ist jetzt packbar und legt das Target
unter build/ ins Paket, wo NuGet es selbst importiert.
Ausserdem: Unauthorized wurde nur im statischen Zweig erkannt, im API-Zweig
kam ein 401 als gewoehnlicher HTTP-Fehler an.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>