Secrets-Management

OpenClaw unterstützt additive SecretRefs, damit unterstützte Credentials nicht als Klartext in der Konfiguration gespeichert werden müssen.

Klartext funktioniert weiterhin. SecretRefs sind pro Credential optional.

Ziele und Runtime-Modell

Secrets werden in einen In-Memory-Runtime-Snapshot aufgelöst.

  • Die Auflösung erfolgt eager während der Aktivierung, nicht lazy auf Request-Pfaden.
  • Der Start schlägt sofort fehl, wenn ein effektiv aktiver SecretRef nicht aufgelöst werden kann.
  • Reload verwendet atomaren Swap: vollständiger Erfolg, oder den letzten funktionierenden Snapshot beibehalten.
  • Runtime-Requests lesen nur vom aktiven In-Memory-Snapshot.
  • Ausgehende Zustellungspfade lesen ebenfalls vom aktiven Snapshot (z. B. Discord-Reply-/Thread-Zustellung und Telegram-Action-Sends); sie lösen SecretRefs nicht bei jedem Senden erneut auf.

Das hält Secret-Provider-Ausfälle von Hot-Request-Pfaden fern.

Active-Surface-Filterung

SecretRefs werden nur auf effektiv aktiven Oberflächen validiert.

  • Aktive Oberflächen: Nicht aufgelöste Refs blockieren Start/Reload.
  • Inaktive Oberflächen: Nicht aufgelöste Refs blockieren Start/Reload nicht.
  • Inaktive Refs erzeugen nicht-fatale Diagnosen mit Code SECRETS_REF_IGNORED_INACTIVE_SURFACE.

Beispiele für inaktive Oberflächen:

  • Deaktivierte Channel-/Account-Einträge.
  • Top-Level-Channel-Credentials, die kein aktivierter Account erbt.
  • Deaktivierte Tool-/Feature-Oberflächen.
  • Web-Search-Provider-spezifische Keys, die nicht durch tools.web.search.provider ausgewählt sind. Im Auto-Modus (Provider nicht gesetzt) werden Keys nach Priorität für die Provider-Auto-Erkennung konsultiert, bis einer auflöst. Nach der Auswahl werden nicht ausgewählte Provider-Keys als inaktiv behandelt, bis sie ausgewählt werden.
  • gateway.remote.token / gateway.remote.password SecretRefs sind aktiv, wenn eine der folgenden Bedingungen zutrifft:
    • gateway.mode=remote
    • gateway.remote.url ist konfiguriert
    • gateway.tailscale.mode ist serve oder funnel
    • Im Local-Modus ohne diese Remote-Oberflächen:
      • gateway.remote.token ist aktiv, wenn Token-Auth gewinnen kann und kein Env-/Auth-Token konfiguriert ist.
      • gateway.remote.password ist nur aktiv, wenn Passwort-Auth gewinnen kann und kein Env-/Auth-Passwort konfiguriert ist.
  • Der gateway.auth.token-SecretRef ist für die Startup-Auth-Auflösung inaktiv, wenn OPENCLAW_GATEWAY_TOKEN (oder CLAWDBOT_GATEWAY_TOKEN) gesetzt ist, da der Env-Token-Input für diese Runtime gewinnt.

Gateway-Auth-Surface-Diagnosen

Wenn ein SecretRef auf gateway.auth.token, gateway.auth.password, gateway.remote.token oder gateway.remote.password konfiguriert ist, protokolliert der Gateway-Start/Reload den Surface-Status explizit:

  • active: Der SecretRef ist Teil der effektiven Auth-Surface und muss aufgelöst werden.
  • inactive: Der SecretRef wird für diese Runtime ignoriert, weil eine andere Auth-Surface gewinnt oder weil Remote-Auth deaktiviert/nicht aktiv ist.

Diese Einträge werden mit SECRETS_GATEWAY_AUTH_SURFACE protokolliert und enthalten den Grund der Active-Surface-Policy, sodass du sehen kannst, warum ein Credential als aktiv oder inaktiv behandelt wurde.

Onboarding-Referenz-Preflight

Wenn das Onboarding im interaktiven Modus läuft und du SecretRef-Speicherung wählst, führt OpenClaw eine Preflight-Validierung vor dem Speichern durch:

  • Env-Refs: Validiert den Env-Variablen-Namen und bestätigt, dass ein nicht-leerer Wert während des Onboardings sichtbar ist.
  • Provider-Refs (file oder exec): Validiert die Provider-Auswahl, löst id auf und prüft den aufgelösten Werttyp.
  • Quickstart-Wiederverwendungspfad: Wenn gateway.auth.token bereits ein SecretRef ist, löst das Onboarding ihn vor dem Probe-/Dashboard-Bootstrap auf (für env-, file- und exec-Refs) unter Verwendung derselben Fail-Fast-Sperre.

Bei fehlgeschlagener Validierung zeigt das Onboarding den Fehler an und lässt dich es erneut versuchen.

SecretRef-Vertrag

Verwende überall diese eine Objektform:

{ source: "env" | "file" | "exec", provider: "default", id: "..." }

source: "env"

{ source: "env", provider: "default", id: "OPENAI_API_KEY" }

Validierung:

  • provider muss ^[a-z][a-z0-9_-]{0,63}$ entsprechen
  • id muss ^[A-Z][A-Z0-9_]{0,127}$ entsprechen

source: "file"

{ source: "file", provider: "filemain", id: "/providers/openai/apiKey" }

Validierung:

  • provider muss ^[a-z][a-z0-9_-]{0,63}$ entsprechen
  • id muss ein absoluter JSON-Pointer sein (/...)
  • RFC6901-Escaping in Segmenten: ~ => ~0, / => ~1

source: "exec"

{ source: "exec", provider: "vault", id: "providers/openai/apiKey" }

Validierung:

  • provider muss ^[a-z][a-z0-9_-]{0,63}$ entsprechen
  • id muss ^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$ entsprechen
  • id darf . oder .. nicht als Slash-getrennte Pfadsegmente enthalten (z. B. a/../b wird abgelehnt)

Provider-Konfiguration

Definiere Provider unter secrets.providers:

{
  secrets: {
    providers: {
      default: { source: "env" },
      filemain: {
        source: "file",
        path: "~/.openclaw/secrets.json",
        mode: "json", // oder "singleValue"
      },
      vault: {
        source: "exec",
        command: "/usr/local/bin/openclaw-vault-resolver",
        args: ["--profile", "prod"],
        passEnv: ["PATH", "VAULT_ADDR"],
        jsonOnly: true,
      },
    },
    defaults: {
      env: "default",
      file: "filemain",
      exec: "vault",
    },
    resolution: {
      maxProviderConcurrency: 4,
      maxRefsPerProvider: 512,
      maxBatchBytes: 262144,
    },
  },
}

Env-Provider

  • Optionale Allowlist via allowlist.
  • Fehlende/leere Env-Werte lassen die Auflösung fehlschlagen.

File-Provider

  • Liest lokale Datei aus path.
  • mode: "json" erwartet ein JSON-Objekt als Payload und löst id als Pointer auf.
  • mode: "singleValue" erwartet Ref-ID "value" und gibt den Dateiinhalt zurück.
  • Der Pfad muss Besitz-/Berechtigungsprüfungen bestehen.
  • Windows-Fail-Closed-Hinweis: Wenn die ACL-Verifizierung für einen Pfad nicht verfügbar ist, schlägt die Auflösung fehl. Für vertrauenswürdige Pfade setze allowInsecurePath: true auf diesem Provider, um Pfad-Sicherheitsprüfungen zu umgehen.

Exec-Provider

  • Führt den konfigurierten absoluten Binärpfad aus, keine Shell.
  • Standardmäßig muss command auf eine reguläre Datei zeigen (keinen Symlink).
  • Setze allowSymlinkCommand: true, um Symlink-Command-Pfade zuzulassen (z. B. Homebrew-Shims). OpenClaw validiert den aufgelösten Zielpfad.
  • Kombiniere allowSymlinkCommand mit trustedDirs für Paketmanager-Pfade (z. B. ["/opt/homebrew"]).
  • Unterstützt Timeout, No-Output-Timeout, Output-Byte-Limits, Env-Allowlist und vertrauenswürdige Verzeichnisse.
  • Windows-Fail-Closed-Hinweis: Wenn die ACL-Verifizierung für den Command-Pfad nicht verfügbar ist, schlägt die Auflösung fehl. Für vertrauenswürdige Pfade setze allowInsecurePath: true auf diesem Provider, um Pfad-Sicherheitsprüfungen zu umgehen.

Request-Payload (stdin):

{ "protocolVersion": 1, "provider": "vault", "ids": ["providers/openai/apiKey"] }

Response-Payload (stdout):

{ "protocolVersion": 1, "values": { "providers/openai/apiKey": "<openai-api-key>" } } // pragma: allowlist secret

Optionale Per-ID-Fehler:

{
  "protocolVersion": 1,
  "values": {},
  "errors": { "providers/openai/apiKey": { "message": "not found" } }
}

Exec-Integrationsbeispiele

1Password CLI

{
  secrets: {
    providers: {
      onepassword_openai: {
        source: "exec",
        command: "/opt/homebrew/bin/op",
        allowSymlinkCommand: true, // erforderlich für Homebrew-Symlink-Binaries
        trustedDirs: ["/opt/homebrew"],
        args: ["read", "op://Personal/OpenClaw QA API Key/password"],
        passEnv: ["HOME"],
        jsonOnly: false,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: { source: "exec", provider: "onepassword_openai", id: "value" },
      },
    },
  },
}

HashiCorp Vault CLI

{
  secrets: {
    providers: {
      vault_openai: {
        source: "exec",
        command: "/opt/homebrew/bin/vault",
        allowSymlinkCommand: true, // erforderlich für Homebrew-Symlink-Binaries
        trustedDirs: ["/opt/homebrew"],
        args: ["kv", "get", "-field=OPENAI_API_KEY", "secret/openclaw"],
        passEnv: ["VAULT_ADDR", "VAULT_TOKEN"],
        jsonOnly: false,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: { source: "exec", provider: "vault_openai", id: "value" },
      },
    },
  },
}

sops

{
  secrets: {
    providers: {
      sops_openai: {
        source: "exec",
        command: "/opt/homebrew/bin/sops",
        allowSymlinkCommand: true, // erforderlich für Homebrew-Symlink-Binaries
        trustedDirs: ["/opt/homebrew"],
        args: ["-d", "--extract", '["providers"]["openai"]["apiKey"]', "/path/to/secrets.enc.json"],
        passEnv: ["SOPS_AGE_KEY_FILE"],
        jsonOnly: false,
      },
    },
  },
  models: {
    providers: {
      openai: {
        baseUrl: "https://api.openai.com/v1",
        models: [{ id: "gpt-5", name: "gpt-5" }],
        apiKey: { source: "exec", provider: "sops_openai", id: "value" },
      },
    },
  },
}

Unterstützte Credential-Oberfläche

Die kanonischen unterstützten und nicht unterstützten Credentials sind aufgelistet in:

Runtime-generierte oder rotierende Credentials und OAuth-Refresh-Material sind bewusst von der Read-Only-SecretRef-Auflösung ausgeschlossen.

Erforderliches Verhalten und Vorrang

  • Feld ohne Ref: unverändert.
  • Feld mit Ref: auf aktiven Oberflächen während der Aktivierung erforderlich.
  • Wenn sowohl Klartext als auch Ref vorhanden sind, hat der Ref auf unterstützten Vorrangpfaden Vorrang.

Warn- und Audit-Signale:

  • SECRETS_REF_OVERRIDES_PLAINTEXT (Runtime-Warnung)
  • REF_SHADOWED (Audit-Befund, wenn auth-profiles.json-Credentials Vorrang vor openclaw.json-Refs haben)

Google-Chat-Kompatibilitätsverhalten:

  • serviceAccountRef hat Vorrang vor Klartext-serviceAccount.
  • Klartext-Werte werden ignoriert, wenn ein Sibling-Ref gesetzt ist.

Aktivierungsauslöser

Die Secret-Aktivierung läuft bei:

  • Start (Preflight plus finale Aktivierung)
  • Config-Reload Hot-Apply-Pfad
  • Config-Reload Restart-Check-Pfad
  • Manueller Reload via secrets.reload

Aktivierungsvertrag:

  • Erfolg tauscht den Snapshot atomar aus.
  • Startfehler bricht den Gateway-Start ab.
  • Runtime-Reload-Fehler behält den letzten funktionierenden Snapshot.
  • Die Angabe eines expliziten Per-Call-Channel-Tokens bei einem ausgehenden Helper-/Tool-Call löst keine SecretRef-Aktivierung aus; Aktivierungspunkte bleiben Start, Reload und explizites secrets.reload.

Degraded- und Recovered-Signale

Wenn eine Reload-Time-Aktivierung nach einem gesunden Zustand fehlschlägt, wechselt OpenClaw in den degradierten Secrets-Zustand.

Einmalige Systemereignis- und Log-Codes:

  • SECRETS_RELOADER_DEGRADED
  • SECRETS_RELOADER_RECOVERED

Verhalten:

  • Degraded: Runtime behält den letzten funktionierenden Snapshot.
  • Recovered: Wird einmal nach der nächsten erfolgreichen Aktivierung ausgegeben.
  • Wiederholte Fehlschläge im bereits degradierten Zustand loggen Warnungen, erzeugen aber keine Spam-Events.
  • Start-Fail-Fast erzeugt keine Degraded-Events, da die Runtime nie aktiv wurde.

Command-Pfad-Auflösung

Command-Pfade können sich über Gateway-Snapshot-RPC für die unterstützte SecretRef-Auflösung entscheiden.

Es gibt zwei grundlegende Verhaltensweisen:

  • Strikte Command-Pfade (z. B. openclaw memory-Remote-Memory-Pfade und openclaw qr --remote) lesen vom aktiven Snapshot und schlagen sofort fehl, wenn ein erforderlicher SecretRef nicht verfügbar ist.
  • Read-Only-Command-Pfade (z. B. openclaw status, openclaw status --all, openclaw channels status, openclaw channels resolve und Read-Only-Doctor-/Config-Repair-Flows) bevorzugen ebenfalls den aktiven Snapshot, degradieren aber statt abzubrechen, wenn ein gezielter SecretRef in diesem Command-Pfad nicht verfügbar ist.

Read-Only-Verhalten:

  • Wenn das Gateway läuft, lesen diese Befehle zuerst vom aktiven Snapshot.
  • Wenn die Gateway-Auflösung unvollständig ist oder das Gateway nicht verfügbar, versuchen sie einen gezielten lokalen Fallback für die spezifische Command-Oberfläche.
  • Wenn ein gezielter SecretRef immer noch nicht verfügbar ist, fährt der Befehl mit degradierter Read-Only-Ausgabe und expliziten Diagnosen fort, z. B. “configured but unavailable in this command path”.
  • Dieses degradierte Verhalten ist nur command-lokal. Es schwächt weder Runtime-Start, Reload noch Send-/Auth-Pfade.

Weitere Hinweise:

  • Snapshot-Refresh nach Backend-Secret-Rotation wird durch openclaw secrets reload gehandhabt.
  • Von diesen Command-Pfaden verwendete Gateway-RPC-Methode: secrets.resolve.

Audit- und Configure-Workflow

Standard-Operator-Flow:

openclaw secrets audit --check
openclaw secrets configure
openclaw secrets audit --check

secrets audit

Befunde umfassen:

  • Klartext-Werte im Ruhezustand (openclaw.json, auth-profiles.json, .env und generierte agents/*/agent/models.json)
  • Klartext-Sensitive-Provider-Header-Rückstände in generierten models.json-Einträgen
  • Nicht aufgelöste Refs
  • Vorrang-Shadowing (auth-profiles.json hat Vorrang vor openclaw.json-Refs)
  • Legacy-Rückstände (auth.json, OAuth-Erinnerungen)

Header-Rückstands-Hinweis:

  • Die Erkennung sensitiver Provider-Header basiert auf Namens-Heuristiken (gängige Auth-/Credential-Header-Namen und Fragmente wie authorization, x-api-key, token, secret, password und credential).

secrets configure

Interaktiver Helfer, der:

  • zuerst secrets.providers konfiguriert (env/file/exec, hinzufügen/bearbeiten/entfernen)
  • dich unterstützte Secret-tragende Felder in openclaw.json plus auth-profiles.json für einen Agent-Scope auswählen lässt
  • ein neues auth-profiles.json-Mapping direkt im Target-Picker erstellen kann
  • SecretRef-Details erfasst (source, provider, id)
  • Preflight-Auflösung durchführt
  • sofort anwenden kann

Hilfreiche Modi:

  • openclaw secrets configure --providers-only
  • openclaw secrets configure --skip-provider-setup
  • openclaw secrets configure --agent <id>

configure-Apply-Standardwerte:

  • Scrubbing passender statischer Credentials aus auth-profiles.json für Ziel-Provider
  • Scrubbing veralteter statischer api_key-Einträge aus auth.json
  • Scrubbing passender bekannter Secret-Zeilen aus <config-dir>/.env

secrets apply

Einen gespeicherten Plan anwenden:

openclaw secrets apply --from /tmp/openclaw-secrets-plan.json
openclaw secrets apply --from /tmp/openclaw-secrets-plan.json --dry-run

Für strikte Ziel-/Pfad-Vertragsdetails und exakte Ablehnungsregeln siehe:

Einweg-Sicherheitsrichtlinie

OpenClaw schreibt absichtlich keine Rollback-Backups mit historischen Klartext-Secret-Werten.

Sicherheitsmodell:

  • Preflight muss vor dem Schreibmodus erfolgreich sein
  • Runtime-Aktivierung wird vor dem Commit validiert
  • Apply aktualisiert Dateien mittels atomarem Dateiaustausch und Best-Effort-Wiederherstellung bei Fehler

Legacy-Auth-Kompatibilitätshinweise

Für statische Credentials hängt die Runtime nicht mehr von Klartext-Legacy-Auth-Speicherung ab.

  • Runtime-Credential-Quelle ist der aufgelöste In-Memory-Snapshot.
  • Legacy-statische api_key-Einträge werden beim Auffinden gescrubbt.
  • OAuth-bezogenes Kompatibilitätsverhalten bleibt separat.

Web-UI-Hinweis

Einige SecretInput-Unions lassen sich im Raw-Editor-Modus einfacher konfigurieren als im Formular-Modus.

Verwandte Dokumentation