openclaw - 💡(How to fix) Fix browser.profiles.*.cdpUrl does not support SecretRef interpolation [1 comments, 2 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#78337Fetched 2026-05-07 03:38:05
View on GitHub
Comments
1
Participants
2
Timeline
7
Reactions
2
Author
Timeline (top)
subscribed ×4commented ×1cross-referenced ×1mentioned ×1

browser.profiles.*.cdpUrl is the documented way to attach to a remote CDP service like Browserbase or Browserless, and the docs explicitly say "treat remote CDP URLs/tokens as secrets" (docs/tools/browser.md §Security). However, this field is not on the supported SecretRef surface, and the runtime reads the URL raw with no interpolation pass. The consequence is that the API key must live in cleartext inside openclaw.json.

This is a quiet trap: the field accepts arbitrary strings, the SecretRef resolver can be configured correctly, the WebSocket library would accept the URL — but the gateway routes the literal placeholder string to the remote service, which then fails with an opaque "not reachable" error.

Error Message

This is a quiet trap: the field accepts arbitrary strings, the SecretRef resolver can be configured correctly, the WebSocket library would accept the URL — but the gateway routes the literal placeholder string to the remote service, which then fails with an opaque "not reachable" error.

Root Cause

Today's debugging took ~30 minutes before reading the dist source revealed resolveProfile reads the URL raw. The user had to fall back to inlining the resolved API key into openclaw.json, which the docs themselves discourage ("avoid embedding long-lived tokens directly in config files" — docs/tools/browser.md §Security).

Existing related issues:

  • #67656 (closed) — config-response redaction now covers cdpUrl, so config.get doesn't leak the key. Good. But the file at rest still does.
  • #55365 (open) — embedded credentials in browser tool URLs. Different concern (the tool input side, not the config side).
  • #43455 (open) — Browserbase static URL no longer works (note: it does work as of 2026.5.4 if you use the documented format exactly; tested today).

Code Example

"secrets": {
     "providers": {
       "onepassword_browserbase": {
         "source": "exec",
         "command": "/usr/bin/op",
         "args": ["read", "op://OpenClaw/Browserbase/credential"]
       }
     }
   }

---

function resolveProfile(resolved, profileName) {
    const profile = resolved.profiles[profileName];
    if (!profile) return null;
    const rawProfileUrl = profile.cdpUrl?.trim() ?? "";
    // ... no resolveSecretString / interpolateSecrets call before use
}
RAW_BUFFERClick to expand / collapse

Summary

browser.profiles.*.cdpUrl is the documented way to attach to a remote CDP service like Browserbase or Browserless, and the docs explicitly say "treat remote CDP URLs/tokens as secrets" (docs/tools/browser.md §Security). However, this field is not on the supported SecretRef surface, and the runtime reads the URL raw with no interpolation pass. The consequence is that the API key must live in cleartext inside openclaw.json.

This is a quiet trap: the field accepts arbitrary strings, the SecretRef resolver can be configured correctly, the WebSocket library would accept the URL — but the gateway routes the literal placeholder string to the remote service, which then fails with an opaque "not reachable" error.

Repro

  1. Configure a SecretRef provider for the API key:
    "secrets": {
      "providers": {
        "onepassword_browserbase": {
          "source": "exec",
          "command": "/usr/bin/op",
          "args": ["read", "op://OpenClaw/Browserbase/credential"]
        }
      }
    }
  2. Try any of these in browser.profiles.browserbase.cdpUrl:
    • wss://connect.browserbase.com?apiKey={{SECRET:onepassword_browserbase}}
    • wss://connect.browserbase.com?apiKey=${secret:onepassword_browserbase}
    • A raw SecretRef object — rejected by schema, the field is string.
  3. Run any browser tool with profile=browserbase. Connection fails because the literal interpolation token is sent as the API key.
  4. Inlining the resolved secret directly into cdpUrl works (and is the only path that does).

Source evidence

dist/config-qEt9W89m.js:

function resolveProfile(resolved, profileName) {
    const profile = resolved.profiles[profileName];
    if (!profile) return null;
    const rawProfileUrl = profile.cdpUrl?.trim() ?? "";
    // ... no resolveSecretString / interpolateSecrets call before use
}

docs/reference/secretref-credential-surface.md "Supported credentials" section does not list browser.profiles.*.cdpUrl. Critically, the omission is silent — there is no entry under "Unsupported credentials" either.

Why this matters

Today's debugging took ~30 minutes before reading the dist source revealed resolveProfile reads the URL raw. The user had to fall back to inlining the resolved API key into openclaw.json, which the docs themselves discourage ("avoid embedding long-lived tokens directly in config files" — docs/tools/browser.md §Security).

Existing related issues:

  • #67656 (closed) — config-response redaction now covers cdpUrl, so config.get doesn't leak the key. Good. But the file at rest still does.
  • #55365 (open) — embedded credentials in browser tool URLs. Different concern (the tool input side, not the config side).
  • #43455 (open) — Browserbase static URL no longer works (note: it does work as of 2026.5.4 if you use the documented format exactly; tested today).

Suggested fix

Two options, in order of preference:

Option 1 (preferred): Add SecretRef interpolation to cdpUrl

Add a token-replacement pass at profile resolve time, expanding ${secret:<provider>} placeholders against the resolved secrets map. This matches user expectation, the docs' security guidance, and how other credential-bearing fields already work.

Option 2 (doc-only fallback): Document the exclusion explicitly

Add browser.profiles.*.cdpUrl to the "Unsupported credentials" list in docs/reference/secretref-credential-surface.md, and add a short note in docs/tools/browser.md §Browserbase saying SecretRef interpolation is not supported and the resolved key must be inlined.

Option 2 is a doc-only fix and unblocks users immediately; Option 1 is the correct long-term answer.

Environment

  • OpenClaw 2026.5.4 (commit 325df3e)
  • Linux x64, Node v22.22.2
  • Browserbase free tier

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

openclaw - 💡(How to fix) Fix browser.profiles.*.cdpUrl does not support SecretRef interpolation [1 comments, 2 participants]