Runtime model
- Secrets resolve into an in-memory runtime snapshot, eagerly during activation, not lazily on request paths.
- Cold Gateway startup isolates a retryable SecretRef failure to a known non-Gateway owner when that owner supports isolation. Mapped owner classes include model providers and skills, media/TTS/cron providers, eligible auth profiles, per-agent memory, sandbox SSH, channel accounts, and manifest-declared plugin routes. The Gateway starts, records the owner as configured-unavailable, and emits a redacted degradation warning. Gateway ingress auth, structurally invalid refs or resolved values, fail-closed owners, and refs whose runtime owner is not mapped still fail startup.
- Reload validates each mapped owner independently, then publishes one atomic snapshot. Healthy owners refresh. An eligible failed owner keeps its last-known-good value and becomes stale only when its ref identities, provider definitions, and complete non-secret owner contract are unchanged; a changed or new failed owner becomes cold. A strict failure rejects the reload and preserves the active snapshot.
- Config reload also reconciles channel connections when a secret-provider edit changes resolved credentials. Plugins that support account-scoped reload restart only the affected named accounts; shared, default, removed, or unresolved account changes use the plugin’s whole-channel restart policy. Cold accounts stop, eligible stale accounts keep using their last-known-good credentials, and recovery preserves manual stops.
- Policy violations (for example an OAuth-mode auth profile combined with SecretRef input) fail activation before the runtime swap.
- Runtime requests read only the active in-memory snapshot. Model-provider SecretRef credentials pass through auth storage and stream options as process-local sentinels until egress. Outbound delivery paths (Discord reply/thread delivery, Telegram action sends) also read that snapshot and do not re-resolve refs per send.
- Read-only channel capability discovery evaluates accounts independently. A configured-but-unavailable account does not hide healthy sibling accounts’ message actions, while direct sends through the unavailable account still fail closed.
Egress-time injection (sentinels)
For model-provider credentials backed by SecretRefs, OpenClaw mints an opaque, process-local sentinel during model-auth resolution. Auth storage, stream options, SDK configuration, logs, error objects, and most runtime introspection therefore see a value such asoc-sent-v2.<authenticated-ciphertext>.end, not the provider credential. The guarded model fetch and managed local-provider health probes replace known sentinels in URL and header values immediately before each request leaves the process.
Unknown sentinel-shaped values fail closed before network activity. OpenClaw refuses to send the request rather than forwarding an unresolved sentinel to a provider. Resolved secret values are also registered for exact-value log redaction as a defense in depth measure.
Provider adapters use the latest injection point their SDK supports:
- SDKs with a custom fetch option receive OpenClaw’s guarded fetch, so the SDK retains the sentinel.
- SDKs without a custom fetch option unwrap the sentinel immediately before client construction. Plugin-owned provider streams and agent harnesses unwrap at the final core-owned handoff because those transports do not share OpenClaw’s guarded fetch.
OPENCLAW_SECRET_SENTINELS=off (also accepts 0 or false, case-insensitive) to disable model-provider sentinel minting during incident response or compatibility troubleshooting. This switch disables neither exact-value redaction registration nor protected-store sealing for Gateway-hosted subprocesses.
Agent-access boundary
SecretRefs stop credentials from being persisted in config and generated model files, but they are not a process-isolation boundary. A plaintext credential left on disk in a path the agent can read is still readable via file or shell tools, bypassing API-level redaction. For production deployments where agent-accessible files are in scope, treat migration as complete only when all of these hold:- Supported credentials use SecretRefs instead of plaintext values.
- Legacy plaintext residue is scrubbed from
openclaw.json, the SQLite auth-profile store,.env, and generatedmodels.jsonfiles. Retired auth JSON is doctor-owned migration input and is never rewritten bysecrets apply. openclaw secrets audit --checkis clean after migration.- Any remaining unsupported or rotating credentials are protected by OS isolation, container isolation, or an external credential proxy.
Active-surface filtering
SecretRefs are validated only on effectively active surfaces:- Enabled surfaces: retryable failures for mapped, isolatable owners enter cold or stale degradation. Strict, fail-closed, Gateway-required, or unmapped failures block startup/reload.
- Inactive surfaces: unresolved refs do not block startup/reload; they emit a non-fatal
SECRETS_REF_IGNORED_INACTIVE_SURFACEdiagnostic.
Examples of inactive surfaces
Examples of inactive surfaces
- Disabled channel/account entries.
- Top-level channel credentials that no enabled account inherits.
- Disabled tool/feature surfaces.
- Web search provider-specific keys not selected by
tools.web.search.provider. In auto mode (provider unset), keys are consulted by precedence for auto-detection until one resolves; after selection, non-selected provider keys are inactive. - Sandbox SSH auth material (
agents.defaults.sandbox.ssh.identityData,certificateData,knownHostsData, plus per-agent overrides) is active only when the effective sandbox backend issshand sandbox mode is notoff, for the default agent or an enabled agent. gateway.remote.token/gateway.remote.passwordSecretRefs are active if any of these hold:gateway.mode=remotegateway.remote.urlis configuredgateway.tailscale.modeisserveorfunnel- In local mode without those remote surfaces:
gateway.remote.tokenis active when token auth can win and no env/auth token is configured;gateway.remote.passwordis active only when password auth can win and no env/auth password is configured.
- Active
gateway.auth.token/gateway.auth.passwordSecretRefs stay authoritative overOPENCLAW_GATEWAY_TOKEN/OPENCLAW_GATEWAY_PASSWORD; environment credentials are fallbacks when the corresponding local config input is absent.
Gateway auth surface diagnostics
When a SecretRef is set ongateway.auth.token, gateway.auth.password, gateway.remote.token, or gateway.remote.password, gateway startup/reload logs the surface state under code SECRETS_GATEWAY_AUTH_SURFACE:
active: the SecretRef is part of the effective auth surface and must resolve.inactive: another auth surface wins, or remote auth is disabled/not active.
Onboarding reference preflight
In interactive onboarding, choosing SecretRef storage runs preflight validation before saving:- Env refs: validates the env var name and confirms a non-empty value is visible during setup.
- Provider refs (
file,exec, orstore): validates provider selection, resolvesid, and checks the resolved value type. - Quickstart flow: when
gateway.auth.tokenis already a SecretRef, onboarding resolves it before probe/dashboard bootstrap (forenv,file,exec, andstorerefs) using the same fail-fast gate. - Generated gateway token: setup mints
gateway.auth.tokenitself, so reference mode has nothing to prompt for. WithOPENCLAW_GATEWAY_TOKENexported it writes anenvref to that variable, keeping a later rotation authoritative; otherwise it writes the token to the secret store underOPENCLAW_GATEWAY_TOKENand stores astoreref. An existing store entry is reused rather than rotated, so re-running setup never invalidates already-paired clients.