diff --git a/client-dotnet/Deploymentcenter.Client/Deploymentcenter.Client.csproj b/client-dotnet/Deploymentcenter.Client/Deploymentcenter.Client.csproj
index acb653f..8f01d5d 100644
--- a/client-dotnet/Deploymentcenter.Client/Deploymentcenter.Client.csproj
+++ b/client-dotnet/Deploymentcenter.Client/Deploymentcenter.Client.csproj
@@ -23,7 +23,7 @@
-->
true
Deploymentcenter.Client
- 2.5.1
+ 2.5.2
Deploymentcenter
Client-SDK für Lizenzprüfung, Update-Verteilung und Erstinstallation über das Deploymentcenter.
deploymentcenter;update;lizenz
diff --git a/client-dotnet/Deploymentcenter.Client/UpdateClient.cs b/client-dotnet/Deploymentcenter.Client/UpdateClient.cs
index 0886857..ef814b9 100644
--- a/client-dotnet/Deploymentcenter.Client/UpdateClient.cs
+++ b/client-dotnet/Deploymentcenter.Client/UpdateClient.cs
@@ -338,6 +338,15 @@ namespace Deploymentcenter.Client
/// Anwendung abwartet, bevor er Dateien ersetzt. Ohne diesen Handschlag
/// kopiert er bei langsamem Herunterfahren ueber gesperrte Dateien.
///
+ ///
+ /// Reicht --require-signature an den Agenten durch. Ohne diesen
+ /// Parameter gab es dafuer nur den Kommandozeilenschalter - jede
+ /// Anwendung, die dem Leitfaden folgt und ueber diese Methode
+ /// startet, aktualisierte damit ungeprueft, waehrend derselbe Aufruf
+ /// von Hand auf der Kommandozeile geschuetzt gewesen waere. Den
+ /// oeffentlichen Schluessel muss dafuer niemand selbst verwalten: der
+ /// Agent holt und cached ihn ohnehin von /api/updateservice/v1/pubkey.
+ ///
public static bool LaunchUpdateAgent(
string agentPath,
string projectId,
@@ -351,7 +360,8 @@ namespace Deploymentcenter.Client
string? platform = null,
bool waitForCurrentProcess = true,
string? licenseKey = null,
- int waitTimeoutSeconds = 60)
+ int waitTimeoutSeconds = 60,
+ bool requireSignature = false)
{
if (!File.Exists(agentPath))
{
@@ -418,6 +428,11 @@ namespace Deploymentcenter.Client
AppendArg(args, "--restart", restart!);
}
+ if (requireSignature)
+ {
+ AppendFlag(args, "--require-signature");
+ }
+
var startInfo = new ProcessStartInfo
{
FileName = agentPath,
@@ -468,6 +483,12 @@ namespace Deploymentcenter.Client
builder.Append("\" ");
}
+ private static void AppendFlag(StringBuilder builder, string name)
+ {
+ builder.Append(name);
+ builder.Append(' ');
+ }
+
private static string? GetCurrentExecutablePath()
{
try
diff --git a/docs/UPDATESERVICE_INTEGRATION_GUIDE.md b/docs/UPDATESERVICE_INTEGRATION_GUIDE.md
index b0781a0..88eb0ad 100644
--- a/docs/UPDATESERVICE_INTEGRATION_GUIDE.md
+++ b/docs/UPDATESERVICE_INTEGRATION_GUIDE.md
@@ -26,6 +26,12 @@
> - `LaunchUpdateAgent` übergibt jetzt Neustart, Prozesskennung und Plattform,
> siehe **[§2A](#a-referenz-auf-deploymentcenterclient)**.
+> **⚠️ Geändert in Version 2.5.2**
+> - **`LaunchUpdateAgent` reicht `--require-signature` durch.** Zuvor gab es
+> den Schalter nur auf der Kommandozeile — der empfohlene Weg über das SDK
+> aktualisierte damit ungeprüft, siehe
+> **[§6, "Erzwingen über LaunchUpdateAgent"](#erzwingen-über-launchupdateagent)**.
+
Das **UpdateService-Modul** des Deploymentcenters bietet ein unternehmensweites, leichtgewichtiges Update-, Rollback- und Reparatur-Schema: statisch ausgelieferte Pakete plus eine PHP-API.
@@ -943,6 +949,36 @@ auf. War der Wechsel beabsichtigt, die Datei löschen.
Ohne hinterlegten Schlüssel bleibt also alles funktionsfähig — es fehlt nur die
Vertrauenskette, und darauf wird bei jedem Update hingewiesen.
+### Erzwingen über `LaunchUpdateAgent`
+
+**Seit 2.5.2.** `--require-signature` war vorher nur über die Kommandozeile
+erreichbar — `LaunchUpdateAgent`, der empfohlene Weg aus
+**[§2A](#a-referenz-auf-deploymentcenterclient)**, hatte dafür keinen
+Parameter. Eine Anwendung, die dem Leitfaden folgte, aktualisierte damit
+ungeprüft, während derselbe Vorgang von Hand auf der Kommandozeile geschützt
+gewesen wäre — ausgerechnet bei dem Feature, das genau diesen Pfad absichern
+soll.
+
+```csharp
+UpdateClient.LaunchUpdateAgent(
+ agentPath: agentPath,
+ projectId: "myapp",
+ licenseKey: meineLizenz,
+ requireSignature: true);
+```
+
+Um den öffentlichen Schlüssel muss sich niemand zusätzlich kümmern: der Agent
+holt und cached ihn ohnehin selbst von `/api/updateservice/v1/pubkey` (siehe
+oben, "Prüfen"). `--pubkey` bleibt nötig, wenn ein Schlüssel ohne
+Netzwerkzugriff hinterlegt werden soll.
+
+**Erst scharfschalten, wenn wirklich alles signiert ist.** Ist
+`security.release_private_key` gesetzt, signiert der Server nur *neue*
+Veröffentlichungen — bereits abgelegte Releases bleiben unsigniert, bis sie
+erneut veröffentlicht werden. Mit `requireSignature: true` bricht der Agent
+bei jedem noch unsignierten Release ab, auch bei einem sonst harmlosen
+Downgrade-Schutz oder einer Reparatur auf eine ältere Version.
+
---
## 7. Release-Verwaltung (Bearbeiten & Löschen)
diff --git a/public/docs/changelog.json b/public/docs/changelog.json
index d6d07b8..54117e2 100644
--- a/public/docs/changelog.json
+++ b/public/docs/changelog.json
@@ -2,9 +2,24 @@
"_comment": "Einzige Quelle der Wahrheit fuer den Changelog. Wird von /docs/changelog.php gerendert und von GET /api/updateservice/v1/changelog?since=X ausgeliefert. Neue Eintraege oben einfuegen.",
"schema": 1,
- "current": "2.5.1",
+ "current": "2.5.2",
"versions": [
+ {
+ "version": "2.5.2",
+ "date": "2026-08-15",
+ "summary": "LaunchUpdateAgent reicht --require-signature durch.",
+ "actionRequired": true,
+ "changes": [
+ {
+ "area": "sdk",
+ "breaking": false,
+ "title": "requireSignature-Parameter auf LaunchUpdateAgent",
+ "text": "--require-signature gab es bisher nur als Kommandozeilenschalter. Jede Anwendung, die dem Leitfaden folgt und ueber LaunchUpdateAgent startet - der empfohlene Weg - aktualisierte damit ungeprueft, waehrend derselbe Vorgang von Hand auf der Kommandozeile geschuetzt gewesen waere. Der oeffentliche Schluessel muss dafuer nicht separat verwaltet werden, der Agent holt und cached ihn ohnehin selbst.",
+ "action": "LaunchUpdateAgent(..., requireSignature: true) setzen, sobald server.security.release_private_key hinterlegt ist und alle ausgelieferten Releases signiert wurden."
+ }
+ ]
+ },
{
"version": "2.5.1",
"date": "2026-08-14",