Homelab MCP – Netzwerk-Authentifizierung¶
Stand 08.09.2026: OAuth-Resource-Server, Trusted-Proxy-Modell und MCP-Tool-Audit des neuen homelab-mcp sind implementiert, automatisiert getestet und im aktuellen GitHub-Stand enthalten. CT 109 nutzt bereits den Audit-Pfad live, bleibt aber weiterhin ausschließlich über Loopback erreichbar, bis ein realer Authorization Server und der endgültige Ingress festgelegt sind.
Ziel¶
Der neue MCP-Endpunkt soll später nicht nur durch einen vorgeschalteten Tunnel geschützt werden, sondern selbst als standardkonformer OAuth-Resource-Server arbeiten. Zusätzlich darf er Forwarding-Header nur von explizit bekannten Reverse Proxys übernehmen. Jeder ausgeführte MCP-Tool-Aufruf muss anschließend über den privileggetrennten Audit-Writer nachvollziehbar sein.
Der Zugriffspfad ist technisch umgesetzt als:
flowchart LR
CLIENT["MCP-Client"] --> PROXY["vertrauenswürdiger Reverse Proxy"]
PROXY --> FORWARD["Proxy-IP · HTTPS · öffentlicher Host"]
FORWARD --> TOKEN["Bearer Access Token"]
TOKEN --> VERIFY["JWT/JWKS-Prüfung"]
VERIFY --> META["Issuer · Audience · Ablauf · Scope"]
META --> AUTH["ctx.http.authInfo"]
AUTH --> POLICY["MCP Default-Deny-Policy"]
POLICY --> AUDIT["Tool-Audit<br/>attempt"]
AUDIT --> TOOL["freigegebenes Plugin-Tool"]
TOOL --> RESULT["Audit<br/>success / error"]
Ein gültiges OAuth-Token ersetzt damit nicht die Proxy-Prüfung, die Tool-Policy oder das persistente Audit. Alle Schichten müssen erfolgreich durchlaufen werden.
OAuth-Resource-Server¶
Der neue Server orientiert sich am aktuellen MCP-v2-Authorization-Modell:
- MCP-Server = OAuth-2.1-Resource-Server;
- Access Token ausschließlich über
Authorization: Bearer ...; - Protected Resource Metadata nach RFC 9728;
WWW-Authenticatebei 401/403;- Resource-/Audience-Bindung nach RFC 8707;
- Token-Passthrough zu nachgelagerten Diensten ist verboten.
Für einen späteren externen Endpunkt wie beispielsweise:
wird die Resource-Metadaten-URL bereitgestellt unter:
Zusätzlich wird der Root-Fallback unterstützt:
JWT/JWKS-Verifier¶
Die Implementierung validiert JWT-Access-Tokens gegen einen entfernten JWKS-Endpunkt.
Geprüft werden:
- kryptografische Signatur;
- erlaubter Signaturalgorithmus;
- exakter Issuer;
- exakte Audience beziehungsweise MCP-Resource;
- Ablaufzeitpunkt
exp; - maximale Tokengröße;
- verwendbare Client-Identität;
- OAuth-Scopes.
Erlaubte Signaturalgorithmen:
Die Client-Identität wird in dieser Reihenfolge übernommen:
Scopes werden aus scope sowie gängigen scp-Darstellungen gelesen.
MCP-AuthInfo¶
Nach erfolgreicher Prüfung wird die Identität an den offiziellen MCP-Node-Adapter übergeben und steht im Tool-Handler unter:
Dort stehen unter anderem zur Verfügung:
clientId;scopes;expiresAt;resource;- minimale Issuer-/Subject-Metadaten;
- geprüfte Proxy- und Client-IP-Metadaten.
Der rohe Access Token darf nicht in Logs oder Audit-Ereignisse übernommen werden.
Protected Resource Metadata¶
Beispiel:
{
"resource": "https://mcp.example.com/mcp",
"authorization_servers": [
"https://auth.example.com"
],
"bearer_methods_supported": [
"header"
],
"scopes_supported": [
"mcp"
]
}
Fehlt ein Token oder ist es ungültig, antwortet der Server mit 401 und einer Bearer-Challenge einschließlich resource_metadata. Fehlt ein benötigter Scope, folgt 403 mit insufficient_scope.
OAuth-Konfiguration¶
OAuth bleibt vollständig deaktiviert, solange keine OAuth-Umgebungsvariablen gesetzt sind. Sobald eine Pflichtvariable gesetzt ist, müssen alle Pflichtvariablen vorhanden sein; eine Teilkonfiguration führt beim Start zu einem Fehler.
Pflichtvariablen:
Optional:
Standard-Scope:
Generisches Beispiel:
Environment="HOMELAB_MCP_OAUTH_RESOURCE_URL=https://mcp.example.com/mcp"
Environment="HOMELAB_MCP_OAUTH_ISSUER=https://auth.example.com"
Environment="HOMELAB_MCP_OAUTH_JWKS_URI=https://auth.example.com/.well-known/jwks.json"
Environment="HOMELAB_MCP_OAUTH_REQUIRED_SCOPES=mcp"
Diese Werte sind keine Secrets. Client-Secrets oder private Schlüssel gehören weiterhin ausschließlich in den Secret Store beziehungsweise in die sichere lokale Ablage.
Trusted-Proxy-Modell¶
Nichtlokaler Betrieb darf nur über explizit freigegebene Reverse Proxys erfolgen.
Die direkten Proxy-IP-Adressen werden konfiguriert über:
Generisches Beispiel:
Die Anwendung prüft zuerst die tatsächliche TCP-Gegenstelle. Forwarding-Header werden erst ausgewertet, wenn diese direkte Gegenstelle in der Proxy-Allowlist steht. Ein normaler Client kann sich deshalb nicht durch selbst gesetzte X-Forwarded-*-Header als Proxy ausgeben.
HTTPS und öffentlicher Host¶
Der Proxy muss melden:
X-Forwarded-Host muss exakt zum Host von HOMELAB_MCP_OAUTH_RESOURCE_URL passen. Fehlt der Header, muss der normale Host-Header exakt passen. Mehrdeutige, kommagetrennte Forwarding-Werte werden abgewiesen.
Client-IP¶
Eine Client-IP wird nur übernommen, wenn dafür ausdrücklich ein einzelner Header konfiguriert ist:
Für einen Cloudflare-Ingress wäre beispielsweise möglich:
Auch dieser Header wird ausschließlich nach erfolgreicher Proxy-IP-Prüfung ausgewertet und muss eine einzelne gültige IPv4- oder IPv6-Adresse enthalten. X-Forwarded-For wird absichtlich nicht pauschal vertraut.
Netzwerkdaten im Auth-Kontext¶
Nach erfolgreicher Proxy- und OAuth-Prüfung stehen zusätzlich zur Verfügung:
Plugins müssen damit keine ungeprüften HTTP-Header selbst auswerten.
MCP-Tool-Audit¶
Das Tool-Audit ist inzwischen live auf CT 109 aktiv. Jeder MCP-Tool-Aufruf läuft nach dem Muster:
Der Audit-Actor wird aus der bereits validierten Identität aufgebaut:
Tool-Argumente und Tool-Antworten werden nicht in das äußere Audit kopiert.
Ist bereits der attempt-Eintrag nicht schreibbar, wird das Tool nicht ausgeführt. Schlägt nur der abschließende Audit-Eintrag fehl, nachdem die Aktion bereits lief, liefert MCP ausdrücklich den Hinweis, den Aufruf nicht automatisch zu wiederholen.
Der persistente Audit-Pfad auf CT 109:
homelab-mcp
-> /run/homelab-mcp-audit/audit.sock
-> homelab-mcp-audit-writer.service
-> /var/log/homelab-mcp/YYYY-MM-DD.jsonl
Geprüfte Rechte:
/run/homelab-mcp-audit/audit.sock root:homelab-mcp 0660
/var/log/homelab-mcp/ root:homelab-mcp 0750
/var/log/homelab-mcp/*.jsonl root:homelab-mcp 0640
Der Laufzeitbenutzer kann den Socket nutzen, die Audit-Dateien aber nicht direkt verändern oder löschen.
Bind-Policy¶
Loopback ist weiterhin ohne Remote-Authentifizierung zulässig:
Eine Bindung außerhalb von Loopback wird nur zugelassen, wenn alle drei Voraussetzungen erfüllt sind:
- vollständige OAuth-Resource-Server-Konfiguration;
- vollständige Trusted-Proxy-Konfiguration;
- persistentes Socket-Audit.
Fehlt eine dieser Schichten, verweigert der Dienst den Start.
Unsicherer HTTP-Testmodus¶
Für automatisierte lokale OAuth-Tests existiert:
Dieser Modus ist ausschließlich für Loopback erlaubt und darf nicht produktiv verwendet werden.
Mehrstufige Berechtigung¶
Der endgültige Zugriffspfad lautet:
vertrauenswürdiger Proxy
-> HTTPS / öffentlicher Host
-> OAuth Token
-> Signatur / Issuer / Audience / Ablauf
-> erforderlicher OAuth-Scope
-> authentifizierter Client
-> Plugin aktiviert?
-> interne Capability verfügbar?
-> Toolklasse freigegeben?
-> expliziter Tool-Override?
-> Audit-Intent erfolgreich?
-> Ausführung
-> Audit-Ergebnis
Damit kann ein Client ein technisch gültiges Token mit Scope mcp besitzen und trotzdem keinerlei Proxmox-Schreibrechte haben.
Automatisierte Tests¶
Der Auth-, Proxy- und Audit-Block ist mit echten, zur Laufzeit erzeugten RSA-Schlüsseln, temporärem JWKS-Server und dem offiziellen MCP-v2-Client getestet.
Abgedeckt sind unter anderem:
- gültiges JWT;
- falscher Issuer;
- falsche Audience;
- abgelaufenes Token;
- Scope-Auswertung;
- fehlender Bearer-Header → 401;
- unzureichender Scope → 403;
- RFC-9728-Metadaten;
- offizieller MCP-v2-Client mit Bearer-JWT;
- explizite Proxy-IP-Allowlist;
- Prüfung von HTTPS und öffentlichem Host;
- optionale vertrauenswürdige Client-IP;
- vollständiger End-to-End-Pfad Trusted Proxy → OAuth → MCP;
- Direktzugriff mit gültigem Token ohne korrekte Proxy-Metadaten wird abgewiesen;
- Tool-Audit ohne Argumente/Antworten;
- Tool wird bei fehlendem Audit-Intent nicht ausgeführt;
- Live-Audit auf CT 109 mit
attemptundsuccessfürsystem_status.
Stand auf CT 109¶
Der aktuelle GitHub-Stand mit OAuth, Trusted Proxy und Tool-Audit ist auf CT 109 installiert.
Live aktiv sind:
homelab-mcp.service;homelab-mcp-audit-writer.service;- Socket-Audit;
- ausschließlich das read-only Tool
system_status.
Noch nicht produktiv konfiguriert sind OAuth und Trusted Proxy. Deshalb bleibt der MCP-Endpunkt:
Warum noch keine LAN-/Cloudflare-Freigabe?¶
Die generischen Schutzschichten sind fertig. Offen ist die konkrete produktive Einbindung:
- tatsächlichen OAuth-/OIDC-Authorization-Server auswählen und konfigurieren;
- endgültigen Cloudflare-/Reverse-Proxy-Ingress zu CT 109 festlegen;
- konkrete Proxy-IP-Allowlist für die DieBrocks-Installation setzen;
- endgültigen öffentlichen Resource-Host setzen;
- Host-Firewall auf CT 109 so begrenzen, dass ein nichtlokaler MCP-Port nur vom vorgesehenen Proxy erreichbar wäre;
- Admin-HTTP-Zugang separat absichern, bevor er remote freigegeben wird.
Nächster Entwicklungsschritt¶
Als Nächstes wird die interne SSH-Capability umgesetzt und daran das zunächst rein lesende Proxmox-Plugin angebunden. SSH bleibt dabei eine interne Transportfähigkeit und wird nicht als allgemeines MCP-Tool exponiert.