feat: ship agent-first mission control v0.2.57
CI - Build & Test / Backend (.NET) (push) Successful in 42s
CI - Build & Test / Frontend (Vue/TS) (push) Successful in 2m46s
CI - Build & Test / Security Check (push) Successful in 3s
CI - Build & Test / Deploy Nexus (push) Successful in 56s

This commit is contained in:
AzuTear
2026-07-31 22:39:47 +02:00
parent 3bc7622977
commit f5552218bc
535 changed files with 95242 additions and 8791 deletions
+148
View File
@@ -0,0 +1,148 @@
# Nexus Security Spot Check
**Datum:** 2026-07-26
**Commit:** `3bc7622977f4a6c2f2e98ab4aa856a2e45c3cf49`
**Vertraulichkeit:** Intern
**Scope:** Statische, risikoorientierte Prüfung von Authentifizierung,
Autorisierung, Bridge-Identität, Proxyweiterleitung und Credential-Lifecycle.
> Dies ist kein vollständiger Security Scan und kein Penetrationstest. Die
> Befunde sind codebasiert und müssen nach der Korrektur in einer realistischen
> Proxy-/Containerumgebung negativ getestet werden.
## Executive Summary
Zwei Zugriffskontrollbefunde blockieren eine verantwortbare
Produktionsfreigabe:
- Die API verlangt nicht global Authentifizierung. Mehrere Controller sind
dadurch standardmäßig öffentlich, darunter ein mutierender Agent-Endpunkt.
- Die Agent-Bridge akzeptiert eine bekannte, vom Client gesetzte
`X-Agent-Id` als ausreichenden Identitätsnachweis, während Nginx diesen Header
öffentlich weiterleitet.
Beide Probleme sind strukturell. Einzelne zusätzliche `[Authorize]`-Attribute
reichen nicht als dauerhafte Lösung; die sichere Voreinstellung muss
„authenticated by default“ lauten.
## SEC-001 Fehlende globale Authorization Policy
**Schweregrad:** P0 / kritisch
**Konfidenz:** Hoch
**Betroffene Grenze:** Öffentliches `/api/v1` -> Controller
### Evidenz
- `backend/Extensions/ServiceCollectionExtensions.cs` registriert
`services.AddAuthorization()` ohne Fallback Policy.
- `backend/Program.cs` mappt sämtliche Controller.
- Mehrere Controller besitzen weder ein klassenweites `[Authorize]` noch
vollständige methodenspezifische Attribute.
- `backend/Controllers/AgentsController.cs` stellt
`POST /api/v1/agents/{id}/command` nur unter Rate Limiting bereit; die Methode
ruft den Agent Runtime Chat auf und schreibt einen Activity-Eintrag.
- `frontend/nginx.conf` leitet `/api/` an das Backend weiter.
- `README.md` behauptet gleichzeitig, alle `/api/v1`-Operationsrouten
benötigten ein Access Token. Implementierung und dokumentierter Vertrag
widersprechen sich.
### Auswirkung
Nicht authentifizierte Aufrufer können abhängig vom jeweiligen Controller
Betriebsdaten lesen. Im schwerwiegendsten verifizierten Fall kann ein Aufrufer
einem Agenten einen Command übermitteln und damit Laufzeit- und
Ressourcennutzung auslösen.
### Korrektur
1. Eine globale Fallback Policy einführen, die einen authentifizierten Principal
verlangt.
2. Ausschließlich wirklich öffentliche Endpunkte explizit mit
`[AllowAnonymous]` markieren, zum Beispiel Health und die notwendigen
Login-/Refresh-Routen.
3. Für mutierende oder sensitive Endpunkte zusätzlich Rollen-/Policy-Prüfungen
definieren.
4. Eine Controller-Inventur durchführen und jeden Endpunkt als public, owner,
admin, agent-service oder internal klassifizieren.
5. Negative Integrationstests hinzufügen: ohne Token muss jeder nicht
freigegebene Endpunkt `401` oder `403` liefern.
## SEC-002 Caller-controlled `X-Agent-Id` gilt als Authentifizierung
**Schweregrad:** P0 / kritisch
**Konfidenz:** Hoch
**Betroffene Grenze:** Öffentliches `/api/bridge` -> Agent-Service-Identität
### Evidenz
- `GatewayBridgeController.TryResolveAgentAsync` akzeptiert eine
`X-Agent-Id`, sobald sie in der bekannten Actor-ID-Menge enthalten ist.
- Ein API-Key oder ein kryptografisch authentifizierter Service Principal ist
in diesem Pfad nicht erforderlich.
- `frontend/nginx.conf` übernimmt `X-Agent-Id` direkt aus dem eingehenden
Client-Header und leitet `/api/bridge/` weiter.
- Die Bridge bietet lesende und mutierende Task-/Activity-/Handoff-Commands.
- Bestehende Tests behandeln eine bekannte `X-Agent-Id` bewusst als
erfolgreichen Authentifizierungsfall.
### Auswirkung
Wer eine gültige Agent-ID kennt oder errät, kann sich gegenüber der Bridge als
dieser Agent ausgeben. Das gefährdet Task-Board-Integrität, Delegationen,
Activity-Audit-Trails und die Verlässlichkeit der Agentenidentität.
### Korrektur
1. Einen bekannten Identitätsheader niemals allein als Authentifizierung
akzeptieren.
2. Service-Traffic über mindestens einen starken Nachweis absichern:
rotierbarer Service-Key mit konstanter Zeitprüfung, mTLS, signiertes
Gateway-Token oder eine private Netzwerkgrenze mit authentifizierendem
Proxy.
3. Am äußeren Proxy eingehende `X-Agent-Id` entfernen. Der vertrauenswürdige
Proxy darf sie erst nach erfolgreicher Authentifizierung neu setzen.
4. `X-Agent-Id` nur als Actor-Attribut innerhalb eines bereits
authentifizierten Service-Contexts verwenden.
5. Replay-, falsche-ID-, fehlender-Key- und Proxy-Bypass-Tests ergänzen.
## SEC-003 Temporäres Owner-Passwort im Prozess-Log
**Schweregrad:** P2 / mittel
**Konfidenz:** Hoch
**Betroffene Grenze:** Bootstrap -> Log-Aggregation / Betreiberzugriff
### Evidenz
Beim ersten Seed wird ein generiertes temporäres Owner-Passwort einmalig in
stderr ausgegeben. Obwohl das Passwort nicht in Git gespeichert wird, können
Container-, CI- oder zentrale Logs den Wert länger aufbewahren als vorgesehen.
### Korrektur
- Passwort über einen expliziten One-Time-Secret-Kanal bereitstellen oder einen
zeitlich eng begrenzten Reset-Link verwenden.
- Wenn Logging vorerst bleibt: Zugriff, Aufbewahrung und automatische
Redaction verbindlich konfigurieren.
- Erstanmeldung zum sofortigen Passwortwechsel zwingen und Seed-Nutzung
auditieren.
## Positive Kontrollen
- JWT-Schlüssel müssen mindestens 32 Byte lang sein.
- Issuer, Audience, Signatur und Laufzeit werden geprüft; Clock Skew ist klein.
- Refresh Tokens werden rotiert und gehasht persistiert.
- Sichere Cookie- und CSRF-Bausteine sind vorhanden.
- Auth- und Agent-Routen besitzen Rate-Limiting-Policies.
- Nginx setzt CSP, Frame-, MIME-, Referrer- und Permissions-Header.
- CI enthält eine einfache Suche nach versehentlich eingecheckten Secrets.
## Freigabekriterien
Eine Security-Freigabe ist erst möglich, wenn:
- beide P0-Pfade korrigiert sind,
- eine vollständige Endpoint-Policy-Matrix dokumentiert ist,
- negative Auth- und Bridge-Integrationstests in .NET 10 grün sind,
- der Test über dieselbe Nginx-/Traefik-Grenze wie Produktion erfolgt,
- unbekannte, bekannte-aber-nicht-authentifizierte und manipulierte
Agent-Identitäten zuverlässig abgewiesen werden.