Skip to content

Secret resolver does not inject file-source secrets into ElevenLabs TTS provider at runtime #89607

Description

@pablonunoutande-source

Summary

When an apiKey in messages.tts.personas.<id>.providers.elevenlabs is configured as a SecretRef pointing to a file-source secret provider, the config validates correctly and openclaw config get returns a redacted ref object, but at runtime the elevenlabs plugin fails with elevenlabs: not configured and openclaw infer tts convert returns TTS conversion failed: elevenlabs: not configured.

Inlining the apiKey as a literal string works fine. So the problem is specifically the SecretRef → runtime injection path for this plugin.

Reproduction

Both of these configurations validate but fail at runtime:

Variant A — mode: "json" with JSON pointer

{
  secrets: {
    providers: {
      "default": {
        source: "file",
        path: "/Users/me/.openclaw/credentials/secrets.json",
        mode: "json"
      }
    }
  },
  messages: {
    tts: {
      personas: {
        "my-persona": {
          providers: {
            elevenlabs: {
              apiKey: {
                source: "file",
                provider: "default",
                id: "/elevenlabs_api_key"
              }
            }
          }
        }
      }
    }
  }
}

Where secrets.json contains {"elevenlabs_api_key": "sk_..."}.

Variant B — mode: "singleValue" with id: "value"

{
  secrets: {
    providers: {
      "my-provider": {
        source: "file",
        path: "/Users/me/.openclaw/credentials/elevenlabs/api-key",
        mode: "singleValue"
      }
    }
  },
  messages: {
    tts: {
      personas: {
        "my-persona": {
          providers: {
            elevenlabs: {
              apiKey: {
                source: "file",
                provider: "my-provider",
                id: "value"
              }
            }
          }
        }
      }
    }
  }
}

Where /Users/me/.openclaw/credentials/elevenlabs/api-key contains a single line with the key (sk_...).

Observed behavior

  • openclaw config validate → passes.
  • openclaw config get messages.tts.personas.my-persona.providers.elevenlabs.apiKey → returns the ref object with all fields __OPENCLAW_REDACTED__.
  • openclaw infer tts providers → shows elevenlabs with available: true, configured: true.
  • openclaw infer tts status → shows elevenlabs with configured: false.
  • openclaw infer tts convert --text "test" --output /tmp/x.mp3Error: TTS conversion failed: elevenlabs: not configured.
  • No errors in ~/.openclaw/logs/gateway.err.log during the failed convert.

Expected behavior

The elevenlabs plugin should receive the resolved secret value at runtime and proceed with TTS synthesis identically to when the apiKey is inlined.

Workaround

Inline the apiKey as a literal string in openclaw.json. Works, but defeats the purpose of the SecretRef surface for security.

Environment

  • OpenClaw 2026.5.7 (eeef486)
  • macOS Tahoe (arm64)
  • elevenlabs plugin (bundled)

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Normal backlog priority with limited blast radius.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.

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions