Zum Inhalt springen
Farbschema wählenSprache wählen

Sicherheitsmodell der Runner-Flotte

Ein Runner führt echte Agent-Arbeit mit echten Credentials aus, daher ist sein Sicherheitsmodell bewusst gewählt. Diese Seite erklärt die Garantien hinter Einen Runner sicher einrichten, damit du nachvollziehen kannst, was ein Runner erreichen kann und was nicht.

Ein Runner verbindet sich nur hinaus zum Hub über HTTPS; der Hub verbindet sich nie hinein. Es gibt keinen einzuhängenden eingehenden Port, keinen Broker zu betreiben, und die Vertrauensgrenze verläuft in eine Richtung. Ein Runner fragt nur dann nach Arbeit, wenn er freie Kapazität hat — zugleich ein natürlicher Backpressure-Mechanismus.

Jeder Runner authentifiziert sich mit seinem eigenen Bearer-Token (scrn_…): 256 Bit CSPRNG-Entropie, serverseitig nur als SHA-256-Hash gespeichert. Die Rotation (POST /api/runners/{id}/rotate-token) erzeugt ein frisches Token und macht das alte sofort ungültig — Rotation ist Widerruf. Tokens werden genau einmal zurückgegeben, bei Registrierung oder Rotation, und sind nie wieder abrufbar.

Der Runner verweigert beim Start eine Klartext-http://-Hub-URL. Ein Token und das laufspezifische Secret-Bündel dürfen nie eine Klartextverbindung queren. Der einzige Weg, http:// zu erlauben, ist das explizite Setzen von SUPACLOUD_RUNNER_ALLOW_INSECURE_TRANSPORT=true — nur in einem vollständig von dir kontrollierten, vertrauenswürdigen privaten Netz akzeptabel.

Der Runner hält keine Kopie der Hub-Datenbank und kein langlebiges Plattform-Secret. Holt er eine Aufgabe ab, trägt die Start-Payload genau die Secrets, die diese eine Aufgabe braucht (Provider-Keys, Git-Keys, das scope-gebundene Task-Session-Token) und nichts sonst:

  • Die Payload ist auf der Zuweisung at rest verschlüsselt mit einer scope-gebundenen AAD; nur eine redigierte Vorschau wird im Klartext gespeichert, der Chiffretext wird beim Abholen offengelegt und beim Erreichen eines Endzustands verworfen.
  • Eine Denylist entfernt jedes Hub-Master-Secret (den Credential-Verschlüsselungs-Key, Vault-Credentials, die JWT-/OIDC-/MCP-Confirmation-Secrets, die Datenbank-URL, Chat-Bot- und Billing-Tokens) aus der Dispatch-Payload — Defense-in-Depth, sodass ein solches Secret nie versehentlich einen (womöglich fremden) Runner erreicht.

Ein Remote-Lauf streamt seine Ereignisse zurück zum Hub, der sie in dieselbe Ereignis-Pipeline wie ein lokaler Lauf einspeist. Jedes weitergeleitete Ereignis durchläuft einen Redactor, der aus den aufgelösten Secrets dieser Zuweisung gespeist wird, bevor es persistiert oder emittiert wird — sodass ein in ein Ereignis hineingeschriebenes Secret bei einem Remote-Lauf genauso bereinigt wird wie bei einem lokalen.

Entscheidend: dass ein Runner keine Datenbank hat, schwächt die Autorisierung nicht. Die MCP-Tool-Oberfläche des Agenten und die Blast-Radius-Grenzen werden serverseitig gegen das Session-Token der Aufgabe bei jedem Aufruf durchgesetzt — identisch für einen Remote-Runner-Agenten und einen lokalen. Der Runner kann seinem Agenten nicht mehr gewähren, als der Hub erlaubt.

Der Hub markiert einen Runner als offline, wenn sein Heartbeat über ein begrenztes Fenster hinaus veraltet (Standard 90 s, Untergrenze 45 s, SUPACLOUD_RUNNER_STALE_SECS), wählt ihn nicht mehr aus und stellt seine ausstehende Arbeit — sowohl nie abgeholte als auch laufende (claimed/running) — erneut bereit: sie wird fehlgeschlagen, ihr at-rest-Secret verworfen und die Aufgabe zum erneuten Dispatch freigegeben. Das Abholen selbst ist race-frei (FOR UPDATE SKIP LOCKED), und der verspätete Endbericht eines veralteten Runners wird abgelehnt, statt neu verteilte Arbeit zu überschreiben.

Onboarding Dritter: Enrollment & das scope-begrenzte Runner-JWT

Abschnitt betitelt „Onboarding Dritter: Enrollment & das scope-begrenzte Runner-JWT“

Das scrn_…-Bearer oben ist das richtige Credential für einen Runner, den du betreibst. Um einen Runner auf einem Host zu onboarden, dem du weniger vertraust, ergänzt eine zweite Credential-Klasse Defense-in-Depth: der Betreiber hält nie ein langlebiges Hub-Credential, und der Runner kann ausschließlich die Workspaces bedienen, auf die du ihn scopt hast. Die betreiberseitigen Schritte stehen in Einen Runner sicher einrichten; das Trust-Modell ist:

  • Einmaliges, einmalig zurückgegebenes Enrollment-Token. Ein Admin erzeugt ein Enrollment-Token mit kurzer TTL, das einen Scope trägt (Trust-Klasse, Tier, Isolation, erlaubte Workspaces + Labels). Der Klartext wird genau einmal zurückgegeben und nur als Hash gespeichert. Der Runner tauscht es beim Boot ein, und dieser Eintausch verbrennt das Token atomar — es ist nicht wiederverwendbar, und ein ungültiges oder abgelaufenes Token hinterlässt nie einen verwaisten Runner.
  • Scope-begrenztes Runner-JWT — niemals eine Session. Der Eintausch liefert ein kurzlebiges (≤ 1 Stunde) scrnj_…-JWT, dessen Claims den Grant des Runners spiegeln. Es ist mit einem domänenseparierten, aus dem Session-Secret abgeleiteten Schlüssel signiert, sodass ein Runner-JWT nie als Benutzer-Session verifiziert und eine Session nie als Runner-JWT — Cross-Acceptance scheitert an der Signaturprüfung. Ein erforderlicher typ = runner-Claim ist ein zweiter Diskriminator (Gürtel zur Hosenträger-Sicherung). Der Runner erneuert das JWT, bevor es abläuft, und jede Erneuerung prüft den Grant erneut in der Datenbank — der Entzug eines Workspaces wirkt also innerhalb einer Token-Lebensdauer statt erst bei einem Redeploy.
  • Zwei Trust-Klassen. Ein trusted-Runner, der ohne explizite Workspaces erzeugt wurde, hält den Wildcard (jeder Workspace) — reserviere ihn für Hosts, die du vollständig kontrollierst. Ein edge-Runner ist standardmäßig untrusted und fail-closed: er enrollt mit leerer Workspace-Menge und bekommt nichts zugewiesen, bis ein Owner ihm explizit einen Workspace gewährt — selbst wenn er online und untätig ist.
  • Grant beim Dispatch durchgesetzt. Der Grant des Runners ist eine runner_grants-Zeile — der autoritative, DB-veränderbare Scope, nie etwas, das der Runner behauptet. Er wirkt als Kandidaten-Filter vor dem Ranking: einem Runner kann nie Arbeit außerhalb seines Grants zugewiesen werden, und er kann seinen eigenen Scope nie weiten. Eine nicht-leere Label-Menge im Grant verlangt zudem, dass jedes Task-Label gewährt ist (required ⊆ allowed). Die Flotte vor dem Enrollment bleibt unberührt — ein scrn_…-Runner ohne Grant-Zeile behält den impliziten trusted-Wildcard, sodass der Dispatch byteidentisch bleibt.

Standardmäßig darf nur ein System-Admin Enrollment-Tokens erzeugen; der Instanz-Schalter runner_onboarding_by_owner erlaubt zusätzlich Organisations-/Workspace-Ownern, edge-Runner zu onboarden, die auf Workspaces in ihrem Besitz begrenzt sind — nie über ihren eigenen Scope hinaus.