-
-
Notifications
You must be signed in to change notification settings - Fork 69.6k
Bug: custom provider SecretRef marker leaks into Authorization header as Bearer secretref-managed #39823
Description
Summary
Agent-generated report, filed by an OpenClaw agent on behalf of the user after local debugging and user-assisted packet capture.
After upgrading to OpenClaw 2026.3.7, a custom OpenAI-compatible provider configured with an exec SecretRef for models.providers.*.apiKey can send the literal placeholder marker as the upstream bearer token instead of the resolved secret.
Observed request header sent upstream:
Authorization: Bearer secretref-managed
This causes upstream 401 responses such as invalid API key errors, even though:
- the SecretRef resolves successfully,
- the actual secret works with direct manual requests,
- and the provider/model configuration itself is otherwise valid.
Privacy / secret handling note
This report intentionally excludes:
- the real API key,
- the full SecretRef payload,
- raw credential material,
- and any user-specific secret values.
Only the non-secret placeholder marker (secretref-managed) is described here.
Environment
- OpenClaw: 2026.3.7
- Platform: macOS
- Provider type: custom OpenAI-compatible provider via
models.providers - Credential source:
apiKeyconfigured as SecretRef withsource: "exec" - Secret provider: user-defined exec SecretRef provider (1Password-backed resolver in this case, but the bug appears to be in OpenClaw marker/runtime handling rather than the external resolver itself)
Expected behavior
For SecretRef-managed custom providers:
- generated
agents/*/agent/models.jsonmay persist a non-secret marker such assecretref-managed, but - runtime request/auth code must resolve the actual secret before building upstream HTTP auth headers,
- and must never send the placeholder marker as the provider API key.
Actual behavior
OpenClaw emits upstream requests with:
Authorization: Bearer secretref-managed
The upstream provider correctly rejects this with 401.
What was verified
1) SecretRef resolution works
The configured exec SecretRef provider successfully resolves the real provider API key at runtime.
2) Direct upstream requests work
Using the resolved real API key directly against the same upstream base URL succeeds:
GET /modelssucceeds- minimal
POST /chat/completionssucceeds - tested with the same provider base URL and the same model ids used by OpenClaw
3) Generated models.json uses the marker
The affected generated agent models.json contains:
"apiKey": "secretref-managed"for the affected provider.
4) Actual upstream request capture confirms marker leakage
A captured upstream request from OpenClaw showed:
Authorization: Bearer secretref-managed
So this is not just a speculative explanation; the marker is actually leaking into the outgoing auth header.
Suspected regression source
Most likely related to the 2026.3.7 SecretRef/models.json persistence hardening work, especially:
- Secrets: harden SecretRef-safe models.json persistence #38955
Secrets: harden SecretRef-safe models.json persistence - possibly also fix: prevent API key plaintext leak into models.json state file #38889
prevent API key plaintext leak into models.json state file
The new persistence behavior appears correct in principle (do not persist plaintext secrets), but a runtime auth path still seems to treat the marker as a usable API key for custom providers.
Why this appears to be an OpenClaw bug, not a user config issue
The current documented behavior says SecretRef-managed provider API keys should refresh from source markers rather than persist resolved secrets into models.json.
That implies this configuration remains supported.
The failure is that the marker is being used as a literal credential at request time instead of being resolved back to the real secret.
Potential root cause area
The likely failure mode is:
- SecretRef-managed provider
apiKeyis persisted into generatedmodels.jsonassecretref-managed - a runtime provider auth path reads
models.json/ merged provider config - the marker is treated as a normal string API key
- runtime request construction emits
Authorization: Bearer secretref-managed
Request
Please investigate the runtime/provider auth path for custom OpenAI-compatible providers using SecretRef-managed models.providers.*.apiKey, and ensure marker values such as secretref-managed are never emitted as actual upstream credentials.
It would also help to add a regression test that verifies:
- SecretRef-managed custom providers can persist markers in generated
models.json - but runtime requests always use the resolved secret, never the marker