Back to skill

Security audit

Discord Voice

Security checks for vulnerabilities and agentic risk

Overview

The skill largely does what it claims, but by default anyone in a joined Discord voice channel can drive a full OpenClaw agent and share persisted context, so it needs review before use.

Install only in trusted Discord servers or channels, configure allowedUsers explicitly, and run voice-originated requests with a restricted agent/tool profile. Tell participants that speech may be recorded, logged, transcribed, sent to providers, and used as agent input. Prefer local or TLS-protected STT/TTS paths, avoid remote Wyoming TCP unless secured by a trusted tunnel, and audit/update the npm lockfile before production use.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
Findings (5)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.ts:162
Finding

Unrestricted Discord Voice Users Can Invoke a Tool-Enabled Agent

Content
View full analysis
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
index.ts:232
Finding

Guild-Wide Agent Sessions Allow Cross-User Context Leakage and Instruction Persistence

Content
View full analysis
`. 3. The session state is retained in the shared session store. 4. A different user in the same guild later speaks to the bot. 5. The second user’s prompt is routed into the same agent session. 6. The second user asks about prior context, requests a summary, or supplies instructions that exploit the existing state. 7. The agent may reveal prior information or perform an action based on another user’s context. ### Impact Assessment Users within the same guild can influence each other’s agent context without an explicit shared-session decision. Potential impact includes: - Disclosure of prior users’ conversation content. - Confused-deputy operations performed using context established by another user. - Persistence of attacker instructions across later voice interactions. - Incor ...[truncated 219 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/voice-connection.ts:834
Finding

Voice Transcripts and Agent Responses Are Written to Plaintext Logs

Content
View full analysis
50 ? "..." : ""}" (TTS: ${ttsInfo.provider} / ${ttsInfo.model})`, ); ``` ### Technical Analysis The plugin records the complete transcription of user speech at info level. It also records the first 50 characters of every spoken agent response. Voice conversations can contain credentials, personal information, confidential business material, health information, or instructions involving sensitive resources. Info-level logs are commonly persisted, centralized, backed up, included in diagnostic archives, or exposed to operational personnel. Truncating the response log to 50 characters does not reliably protect sensitive content, and the user transcript is not truncated or redacted at all. ### Attack Path 1. A user speaks a password, token, personal detail, confidential instruction, or other sensitive content. 2. The selected STT provider returns the corresponding plaintext. 3. The plugin interpolates the full transcript into an info-level log message. 4. The host logging system persists or forwards the message. 5. A user with access to local logs, centralized logging, backups, telemetry, or support bundles retrieves the conversation. 6. Agent response excerpts may disclose additional sensitive output through the second log statement. ### Impact Assessment The issue exposes conversational content to every principal that can access application logs. Depending on deployment, this may include host admin ...[truncated 345 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
src/stt.ts:370
Finding

Wyoming STT Sends Raw Voice Audio over Unauthenticated Plaintext TCP

Content
View full analysis
{ ``` ```ts // Wyoming STT flow: transcribe -> audio-start -> audio-chunk -> audio-stop sendMessage("transcribe", this.language ? { language: this.language } : {}); sendMessage("audio-start", { rate, width, channels }); sendMessage("audio-chunk", { rate, width, channels }, audioBuffer); sendMessage("audio-stop", {}); ``` The configured destination may be a non-loopback host: ```ts const host = typeof ww["host"] === "string" && (ww["host"] as string).trim() ? (ww["host"] as string).trim() : "127.0.0.1"; ``` ### Technical Analysis The Wyoming provider sends raw PCM voice data through `node:net`, which provides unencrypted TCP only. The connection does not authenticate the server, encrypt the audio, or verify the integrity of transcript responses. Although loopback is the default, configuration accepts arbitrary hostnames or IP addresses. When an administrator points the plugin at a LAN or remote Wyoming server, voice content traverses the network in plaintext. A network-positioned attacker can passively capture speech or actively impersonate the transcription service. Because returned transcript events are trusted and forwarded to the agent, response tampering can also become a prompt-injection path. ### Attack Path #### Passive interception 1. The operator configures `wyomingWhisper.host` with a LAN or remote server. 2. A Discord participant speaks in the joined voice channel. 3. The plugin decodes the audio to PCM. 4. `sendMessage("audio-chunk", ..., audioBuffer)` transmits the raw audio over TCP. 5. An attacker with access to the network path captures and reconstructs the speech. #### Active transc ...[truncated 768 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
package-lock.json:5380
Finding

Dependency Graph Contains a Git-over-SSH Package and Install-Script Components

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (94)

Known Vulnerable Dependency: protobufjs==7.5.4 — 12 advisory(ies): CVE-2026-44294 (protobuf.js: Denial of service from crafted field names in generated code); CVE-2026-44293 (protobuf.js: Code injection through bytes field defaults in generated toObject c); CVE-2026-44289 (protobuf.js: Denial of service through unbounded protobuf recursion) +9 more

Critical
Category
Supply Chain
Confidence
96% confidence
Finding

The lockfile includes protobufjs 7.5.4, which the scanner reports as having multiple critical advisories including denial of service and code-injection issues in generated/protobuf handling paths. Even though this is only a lockfile and exploitability depends on runtime code paths, bundling a version with many known advisories is a real supply-chain risk, especially in an agent skill that may process untrusted network data and model-related payloads.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @hono/node-server==1.19.9 — 3 advisory(ies): CVE-2026-39406 (@hono/node-server: Middleware bypass via repeated slashes in serveStatic); GHSA-frvp-7c67-39w9 (Node.js Adapter for Hono: Path traversal in `serve-static` on Windows via encode); CVE-2026-29087 (@hono/node-server has authorization bypass for protected static paths via encode)

High
Category
Supply Chain
Confidence
83% confidence
Finding

@hono/node-server 1.19.9 is reported with path traversal and middleware bypass issues in static file serving. In this specific skill context it appears as an optional/peer dependency pulled via another package rather than a direct runtime dependency of the Discord voice skill, so exposure is less certain, but the vulnerable package is still present in the dependency graph.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: sharp==0.34.5 — 2 advisory(ies): GHSA-f88m-g3jw-g9cj (sharp inherited vulnerabilities in libvips: CVE-2026-33327, CVE-2026-33328, CVE-); GHSA-rgj7-g3m4-5g8c (sharp: Vulnerabilities in libheif: GHSA-g89c-p67h-r497 and GHSA-2jg2-4ch7-h545)

High
Category
Supply Chain
Confidence
88% confidence
Finding

sharp 0.34.5 is flagged for inherited image-processing vulnerabilities in bundled libraries such as libvips/libheif. This matters because the broader dependency tree includes multiple media-processing components, and malformed media inputs can be attacker-controlled in chat or voice ecosystems, potentially leading to crashes or worse depending on the underlying native issue.

Content

No source excerpt is available for this finding.

Known Vulnerable Dependency: @mariozechner/pi-coding-agent==0.52.12 — 3 advisory(ies): CVE-2026-54326 (Pi Agent: Potential XSS in HTML session exports via Markdown URL sanitization by); CVE-2026-54328 (Pi Agent: Predictable temporary extension install paths allow local privilege es); CVE-2026-54327 (Pi Agent: Race condition in Pi auth.json writes could expose stored credentials)

High
Category
Supply Chain
Confidence
80% confidence
Finding

@mariozechner/pi-coding-agent 0.52.12 is listed with several advisories, but in this package-lock it is introduced through the peer dependency chain of openclaw rather than being a direct feature of the Discord voice skill. That makes the finding real at the dependency level, though likely low impact to this skill unless those agent-export, temp-extension, or auth file paths are actually exercised in the deployment environment.

Content

No source excerpt is available for this finding.

Possible Typosquatting: 'oxlint' resembles popular package 'eslint'

High
Category
Supply Chain
Confidence
70% confidence
Finding

Package name closely resembles a popular package, suggesting possible typosquatting. Attackers publish malicious packages with similar names to trick developers into installing them.

Content

No source excerpt is available for this finding.

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/streaming-stt.ts (reported line 87)May include surrounding context.

ts
},
  ) {
    super();
    this.apiKey = config.deepgram?.apiKey || process.env["DEEPGRAM_API_KEY"] || "";
    this.model = validateDeepgramModel(config.deepgram?.model || "nova-2");
    this.sampleRate = options?.sampleRate ?? 48000;
    this.interimResults = options?.interimResults ?? true;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/stt.ts (reported line 179)May include surrounding context.

ts
},
  ) {
    super();
    this.apiKey = config.deepgram?.apiKey || process.env["DEEPGRAM_API_KEY"] || "";
    this.model = validateDeepgramModel(config.deepgram?.model || "nova-2");
    this.sampleRate = options?.sampleRate ?? 48000;
    this.interimResults = options?.interimResults ?? true;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/tts.ts (reported line 223)May include surrounding context.

ts
},
  ) {
    super();
    this.apiKey = config.deepgram?.apiKey || process.env["DEEPGRAM_API_KEY"] || "";
    this.model = validateDeepgramModel(config.deepgram?.model || "nova-2");
    this.sampleRate = options?.sampleRate ?? 48000;
    this.interimResults = options?.interimResults ?? true;

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/streaming-tts.ts (reported line 56)May include surrounding context.

ts
private model: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.openai?.apiKey || process.env["OPENAI_API_KEY"] || "";
    this.model = config.openai?.whisperModel || "whisper-1";

    if (!this.apiKey) {

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/stt.ts (reported line 38)May include surrounding context.

ts
private model: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.openai?.apiKey || process.env["OPENAI_API_KEY"] || "";
    this.model = config.openai?.whisperModel || "whisper-1";

    if (!this.apiKey) {

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/stt.ts (reported line 127)May include surrounding context.

ts
private model: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.openai?.apiKey || process.env["OPENAI_API_KEY"] || "";
    this.model = config.openai?.whisperModel || "whisper-1";

    if (!this.apiKey) {

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/tts.ts (reported line 49)May include surrounding context.

ts
private model: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.openai?.apiKey || process.env["OPENAI_API_KEY"] || "";
    this.model = config.openai?.whisperModel || "whisper-1";

    if (!this.apiKey) {

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/streaming-tts.ts (reported line 116)May include surrounding context.

ts
private modelId: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.elevenlabs?.apiKey || process.env["ELEVENLABS_API_KEY"] || "";
    this.voiceId = validateElevenLabsVoiceId(config.elevenlabs?.voiceId || "21m00Tcm4TlvDq8ikWAM");
    this.modelId = config.elevenlabs?.modelId || "eleven_turbo_v2_5";

Env Variable Harvesting

High
Category
Data Exfiltration
Confidence
70% confidence
Finding

Code enumerates, copies, or searches environment variables for secrets. Bulk environment access can collect credentials unrelated to the skill's stated purpose.

Content

Scanner excerpt · src/tts.ts (reported line 96)May include surrounding context.

ts
private modelId: string;

  constructor(config: DiscordVoiceConfig) {
    this.apiKey = config.elevenlabs?.apiKey || process.env["ELEVENLABS_API_KEY"] || "";
    this.voiceId = validateElevenLabsVoiceId(config.elevenlabs?.voiceId || "21m00Tcm4TlvDq8ikWAM");
    this.modelId = config.elevenlabs?.modelId || "eleven_turbo_v2_5";

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README prominently describes capturing voice, transcribing it, and sending it to third-party STT/TTS providers, but it does not provide an explicit privacy notice, consent requirement, or data-handling warning. In a Discord voice setting, this can lead operators to deploy monitoring and external transmission of user speech without adequately informing participants, increasing privacy and compliance risk.

Content

No source excerpt is available for this finding.

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 32)May include surrounding context.

bash
# Ubuntu/Debian
sudo apt-get install ffmpeg build-essential python3

# Fedora/RHEL
sudo dnf install ffmpeg gcc-c++ make python3

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 67)May include surrounding context.

bash
# Ubuntu/Debian
sudo apt-get install ffmpeg build-essential python3

# Fedora/RHEL
sudo dnf install ffmpeg gcc-c++ make python3

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · README.md (reported line 35)May include surrounding context.

md
sudo apt-get install ffmpeg build-essential python3

# Fedora/RHEL
sudo dnf install ffmpeg gcc-c++ make python3

# macOS
brew install ffmpeg

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
70% confidence
Finding

Commands invoke sudo or root privileges. Verify this elevated access is necessary and justified.

Content

Scanner excerpt · SKILL.md (reported line 70)May include surrounding context.

md
sudo apt-get install ffmpeg build-essential python3

# Fedora/RHEL
sudo dnf install ffmpeg gcc-c++ make python3

# macOS
brew install ffmpeg

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 118)May include surrounding context.

md
## Configuration

| Option                 | Type              | Default                               | Description                                                                                                                                                                                   |
| ---------------------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`              | boolean           | `true`                                | Enable/disable the plugin                                                                                                                                                                     |
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 120)May include surrounding context.

md
| Option                 | Type              | Default                               | Description                                                                                                                                                                                   |
| ---------------------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`              | boolean           | `true`                                | Enable/disable the plugin                                                                                                                                                                     |
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |
| `sttFallbackProvider`  | string            | `undefined`                           | Single fallback (legacy). Prefer `sttFallbackProviders`.                                                                                                                                      |
| `sttFallbackProviders` | string[]          | `undefined`                           | Fallback STT when primary fails (quota, rate limit, Wyoming unreachable). E.g. `["local-whisper", "wyoming-whisper"]`.                                                                        |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 131)May include surrounding context.

md
| Option                 | Type              | Default                               | Description                                                                                                                                                                                   |
| ---------------------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`              | boolean           | `true`                                | Enable/disable the plugin                                                                                                                                                                     |
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |
| `sttFallbackProvider`  | string            | `undefined`                           | Single fallback (legacy). Prefer `sttFallbackProviders`.                                                                                                                                      |
| `sttFallbackProviders` | string[]          | `undefined`                           | Fallback STT when primary fails (quota, rate limit, Wyoming unreachable). E.g. `["local-whisper", "wyoming-whisper"]`.                                                                        |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 122)May include surrounding context.

md
| ---------------------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`              | boolean           | `true`                                | Enable/disable the plugin                                                                                                                                                                     |
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |
| `sttFallbackProvider`  | string            | `undefined`                           | Single fallback (legacy). Prefer `sttFallbackProviders`.                                                                                                                                      |
| `sttFallbackProviders` | string[]          | `undefined`                           | Fallback STT when primary fails (quota, rate limit, Wyoming unreachable). E.g. `["local-whisper", "wyoming-whisper"]`.                                                                        |
| `streamingSTT`         | boolean           | `true`                                | Use streaming STT (Deepgram only, ~1s faster)                                                                                                                                                 |
| `ttsProvider`          | string            | `"openai"`                            | `"openai"`, `"elevenlabs"`, `"deepgram"`, `"polly"`, `"edge"`, or `"kokoro"`                                                                                                                  |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 137)May include surrounding context.

md
| ---------------------- | ----------------- | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`              | boolean           | `true`                                | Enable/disable the plugin                                                                                                                                                                     |
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |
| `sttFallbackProvider`  | string            | `undefined`                           | Single fallback (legacy). Prefer `sttFallbackProviders`.                                                                                                                                      |
| `sttFallbackProviders` | string[]          | `undefined`                           | Fallback STT when primary fails (quota, rate limit, Wyoming unreachable). E.g. `["local-whisper", "wyoming-whisper"]`.                                                                        |
| `streamingSTT`         | boolean           | `true`                                | Use streaming STT (Deepgram only, ~1s faster)                                                                                                                                                 |
| `ttsProvider`          | string            | `"openai"`                            | `"openai"`, `"elevenlabs"`, `"deepgram"`, `"polly"`, `"edge"`, or `"kokoro"`                                                                                                                  |

Whitespace Padding

Medium
Category
Prompt Injection
Confidence
70% confidence
Finding

Large whitespace padding was detected (a block of blank lines or a long run of spaces). This can push injected instructions below or to the right of the visible area so a human reviewer never sees them while the agent still reads them. Manual review of the hidden content is recommended.

Content

Scanner excerpt · README.md (reported line 124)May include surrounding context.

md
| `sttProvider`          | string            | `"whisper"`                           | `"whisper"`, `"local-whisper"`, `"wyoming-whisper"`, `"gpt4o-mini"`, `"gpt4o-transcribe"`, `"gpt4o-transcribe-diarize"` (OpenAI), or `"deepgram"`                                             |
| `sttFallbackProvider`  | string            | `undefined`                           | Single fallback (legacy). Prefer `sttFallbackProviders`.                                                                                                                                      |
| `sttFallbackProviders` | string[]          | `undefined`                           | Fallback STT when primary fails (quota, rate limit, Wyoming unreachable). E.g. `["local-whisper", "wyoming-whisper"]`.                                                                        |
| `streamingSTT`         | boolean           | `true`                                | Use streaming STT (Deepgram only, ~1s faster)                                                                                                                                                 |
| `ttsProvider`          | string            | `"openai"`                            | `"openai"`, `"elevenlabs"`, `"deepgram"`, `"polly"`, `"edge"`, or `"kokoro"`                                                                                                                  |
| `ttsVoice`             | string            | `"nova"`                              | Deprecated – use provider-specific: `openai.voice`, `elevenlabs.voiceId`, `kokoro.voice`                                                                                                      |
| `vadSensitivity`       | string            | `"medium"`                            | `"low"`, `"medium"`, or `"high"`                                                                                                                                                              |

Static analysis

Detected: suspicious.env_credential_access, suspicious.exposed_secret_literal, suspicious.insecure_tls_verification

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
index.ts:156

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/streaming-tts.ts:56

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/stt.ts:38

Environment variable access combined with network send.

Critical
Code
suspicious.env_credential_access
Location
src/tts.ts:49

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/config.ts:269

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/streaming-tts.ts:116

File appears to expose a hardcoded API secret or token.

Critical
Code
suspicious.exposed_secret_literal
Location
src/tts.ts:96

HTTPS certificate verification is disabled.

Warn
Code
suspicious.insecure_tls_verification
Location
index.ts:158