# Nexus – Security Spot Check > **Historische Evidenz:** Diese Datei hält den Stand vom 2026-07-26 fest. Der > v0.2.60-Stabilitätsslice entfernte die ungenutzte CSRF-Tokenroute, ergänzte > Browser-Origin-Prüfungen für Refresh/Logout und ersetzte den einfachen CI-Grep > durch checksum-gepinntes Full-History-Gitleaks. Aktuelle Abnahmegrenzen stehen > in `docs/audits/2026-07-31/stability-v0.2.60/IMPLEMENTATION_AND_ACCEPTANCE.md`. **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.