Skip to content

[Bug]: iOS Talk treats SecretRef-backed ElevenLabs API keys as missing #98209

Description

@ooiuuii

Summary

iOS Talk can report Voice API key missing even when the Gateway has a resolved ElevenLabs Talk API key, if the configured Talk provider key is stored as a SecretRef.

Real environment observed

  • OpenClaw Windows/Gateway: 2026.6.11-beta.2
  • iOS OpenClaw client connected through the native pairing flow with operator.talk.secrets
  • Talk provider: ElevenLabs native Talk (eleven_v3)
  • Credential storage: talk.providers.elevenlabs.apiKey configured through SecretRef rather than plaintext

The same account/key became usable when the key was temporarily stored as plaintext in the local OpenClaw config, and the iOS Talk screen moved from Voice API key missing to Permission Ready. That makes this a SecretRef/readback contract issue rather than an ElevenLabs plan or key-permission issue.

User-visible symptom

After pairing the phone and opening Talk, iOS shows Voice API key missing / API key for Native - eleven_v3 even though the Gateway runtime has already resolved the provider key. Users can mistake this for a bad ElevenLabs subscription or a missing key and may work around it by storing provider secrets as plaintext.

Source-level repro on current main

Current main (6cb82eaab865) gates talk.config({ includeSecrets: true }) on operator.talk.secrets, but resolveTalkResponseFromConfig returns the source-shaped payload before the runtime-resolved config path runs. If talk.providers.<id>.apiKey is a SecretRef, the authorized response can therefore put the SecretRef object in talk.resolved.config.apiKey.

That is not usable for iOS native Talk: TalkModeGatewayConfigParser reads activeConfig["apiKey"]?.stringValue, so a SecretRef object is parsed as missing.

Related prior attempt: #91020 identified the same early-return seam and was closed by its author over the credential-boundary question. The current docs still describe operator.talk.secrets as the scope for native Talk configuration reads, so this report tracks the remaining user-visible regression separately and calls out the trust-boundary decision explicitly.

Expected behavior

For a caller authorized with operator.talk.secrets, talk.config({ includeSecrets: true }) should make the effective resolved provider credential available in talk.resolved.config.apiKey so native Talk can use the configured provider.

For callers without Talk secret scope, the runtime key must not be exposed; the existing redacted/source-shaped response should remain redacted.

Actual behavior

Authorized native clients can receive the source SecretRef object instead of a resolved API key string. iOS then treats the key as missing and blocks native ElevenLabs Talk until the user stores the key as plaintext or enters a separate local mobile key.

Scope / non-goals

  • This is not a request to expose Talk provider keys to ordinary operator.read clients.
  • This does not change the redacted response for non-secret reads.
  • This does not change provider execution, ElevenLabs billing, or live synthesis behavior.
  • This intentionally leaves the broader product/security decision around native secret reads visible for maintainer review.

Proposed fix

Keep the source-shaped provider map intact, but do not return early for includeSecrets. Let the existing runtime-resolved config path run, and only use resolvedConfig for talk.resolved.config when the caller already has Talk secret scope.

Regression coverage should prove both sides:

  • includeSecrets: true with operator.talk.secrets returns a string in talk.resolved.config.apiKey when the source key is a SecretRef and runtime config has the resolved key.
  • ordinary talk.config read scope still redacts the runtime key and does not leak the resolved value or SecretRef id.

Metadata

Metadata

Assignees

Labels

P1High-priority user-facing bug, regression, or broken workflow.clawsweeper:linked-pr-openClawSweeper found an open linked pull request for this issue.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.maturity: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