Skip to content

SecretRef credentials travel as plaintext through the model-call chain after resolution #102008

Description

@steipete

Problem

SecretRefs (docs: https://docs.openclaw.ai/gateway/secrets) keep provider credentials out of openclaw.json, but after eager resolution the plaintext value travels through the entire model-call chain:

  • resolveApiKeyForProvider returns the resolved plaintext (src/agents/model-auth.ts)
  • it lands in runtime auth storage (src/agents/embedded-agent-runner/run/auth-controller.ts)
  • flows into stream options (src/agents/embedded-agent-runner/stream-resolution.ts, packages/agent-core/src/agent-loop.ts)
  • and into SDK client construction (packages/ai/src/providers/*)

Any log line, error dump, capture file, or introspection surface along that chain can leak the real credential. Several packages/ai adapters (Anthropic, OpenAI responses) also construct SDK clients without the host guarded fetch, so the SDK builds auth headers from the raw key with no in-repo interception point.

The secrets docs currently punt the remaining risk to "OS isolation, container isolation, or an external credential proxy."

Proposal

Egress-time credential injection inside the runtime:

  1. Mint an opaque per-process sentinel (oc-sent-v1-<hex>) for SecretRef-managed model credentials at auth resolution; everything downstream holds the sentinel.
  2. Swap sentinels for real values in the guarded model fetch (headers + URL), immediately before the SSRF-guarded send; fail closed on unknown sentinel-shaped values.
  3. Converge packages/ai adapters onto the host guarded fetch where the SDK supports custom fetch; unwrap at client construction (host port) where it does not.
  4. Register every resolved secret value (and its percent-encoded form) in an exact-value redaction registry consumed by redactSensitiveText / redactSecrets.

Kill switch: OPENCLAW_SECRET_SENTINELS=off. Plugin SDK auth surface stays plaintext (shipped contract).

Out of scope (follow-ups): channel tokens, MCP env/headers, skills env, sandbox egress proxying for tool traffic.

Metadata

Metadata

Assignees

Labels

P0Emergency: data loss, security bypass, crash loop, or unusable core runtime.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.clawsweeper:needs-maintainer-reviewClawSweeper marked this issue as needing maintainer review before automation.clawsweeper:needs-product-decisionClawSweeper marked this issue as needing a product or behavior decision.clawsweeper:needs-security-reviewClawSweeper marked this issue as needing security-sensitive review.clawsweeper:no-new-fix-prClawSweeper does not recommend queueing a new automated fix PR for this issue.clawsweeper:source-reproClawSweeper found a high-confidence source-level issue reproduction.impact:auth-providerAuth, provider routing, model choice, or SecretRef resolution may break.impact:securitySecurity boundary, credential, authz, sandbox, or sensitive-data risk.issue-rating: 🦞 diamond lobsterVery strong issue quality with high-confidence source-level or clear reproduction.maintainerMaintainer-authored PRmaturity:stableIssue affects a taxonomy feature currently scored M4/M5.

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions