Skip to content

fix(stt): route transcription inputs through the shared read guard - #58056

Closed
Frowtek wants to merge 1 commit into
NousResearch:mainfrom
Frowtek:fix/stt-credential-read-guard
Closed

Frowtek wants to merge 1 commit into
NousResearch:mainfrom
Frowtek:fix/stt-credential-read-guard

Conversation

@Frowtek

@Frowtek Frowtek commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

transcribe_audio reads a local file and hands it to the configured STT
provider. For the hosted providers (Groq, OpenAI, Mistral, xAI, ElevenLabs)
that ships the file's raw bytes to a third-party API.

The shared local-input read guard (agent.file_safety.get_read_block_error)
was already added to image-gen (587be5b, "guard local provider inputs against
credential reads"
) and xAI video-gen (1042329), but the STT tools were
missed. So the agent can still feed a .env, auth.json,
.anthropic_oauth.json, or a mcp-tokens/ file to transcription and have its
plaintext leave the machine.

This routes transcribe_audio through the same guard (before validation and
provider dispatch), refusing those paths up front. It is defense-in-depth,
not a security boundary
— the guard's own message says so, and the terminal
tool can still reach the file — it just restores parity with the image/video-gen
tools.

Related Issue

N/A — no tracking issue. Parity follow-up to 587be5b (image-gen) and
1042329 (xai video-gen), which added the same guard to sibling tools.

Fixes #

Type of Change

  • 🐛 Bug fix (non-breaking change that fixes an issue)
  • ✨ New feature (non-breaking change that adds functionality)
  • 🔒 Security fix
  • 📝 Documentation update
  • ✅ Tests (adding or improving test coverage)
  • ♻️ Refactor (no behavior change)
  • 🎯 New skill (bundled or hub)

Changes Made

  • tools/transcription_tools.py — call get_read_block_error(file_path) at the
    top of transcribe_audio, before audio validation / provider dispatch;
    return the guard's error dict when a read is blocked.
  • tests/tools/test_transcription_tools.py — add
    TestTranscribeCredentialReadGuard.

How to Test

  1. Point the STT path at a secret-bearing file:
    from tools.transcription_tools import transcribe_audio
    r = transcribe_audio("/path/to/.env")
    assert r["success"] is False and "cannot be read" in r["error"]
  2. Confirm the block happens before dispatch (the error is the read-guard
    message, not "Unsupported format" and not a provider error).
  3. Run the tests:
    pytest tests/tools/test_transcription_tools.py -q
    

Checklist

Code

  • I've read the Contributing Guide
  • My commit messages follow Conventional Commits (fix(scope):, feat(scope):, etc.)
  • I searched for existing PRs to make sure this isn't a duplicate
  • My PR contains only changes related to this fix/feature (no unrelated commits)
  • I've run the affected suite and it passes: pytest tests/tools/test_transcription_tools.py -q107 passed, 1 skipped
  • I've added tests for my changes (required for bug fixes, strongly encouraged for features)

Documentation & Housekeeping

  • I've updated relevant documentation (README, docs/, docstrings) — N/A (no doc-facing change)
  • I've updated cli-config.yaml.example if I added/changed config keys — N/A (no config keys)
  • I've updated CONTRIBUTING.md or AGENTS.md if I changed architecture or workflows — N/A
  • I've considered cross-platform impact (Windows, macOS) per the compatibility guide — path-agnostic; the guard resolves the same on every OS
  • I've updated tool descriptions/schemas if I changed tool behavior — N/A (rejects a narrow set of secret paths; no schema change)

Screenshots / Logs

Mutation check — without the guard, the same .env input instead reaches audio
validation:

- Access denied: .../.env is a secret-bearing environment file and cannot be
  read to prevent credential leakage. ...
+ Unsupported format: . Supported: .aac, .flac, .m4a, .mp3, .mp4, ...

With the guard, transcribe_audio returns the read-guard message before any
provider is contacted.

`transcribe_audio` reads a local file and hands it to the configured STT
provider — for the hosted providers (Groq, OpenAI, Mistral, xAI, ElevenLabs)
that ships the file's bytes to a third-party API. The same local-input read
guard was added to image-gen (587be5b) and xAI video-gen (1042329) to keep
the agent from feeding credential/secret stores to a provider, but STT was
missed.

Call `get_read_block_error(file_path)` at the top of `transcribe_audio`, before
validation/dispatch, so a `.env`, `auth.json`, `.anthropic_oauth.json`,
`mcp-tokens/`, etc. is refused up front instead of being transcribed (and, for
hosted providers, exfiltrated). This is defense-in-depth, not a security
boundary — the guard's own message says so — but it restores parity with the
image/video-gen tools.

Regression test: a `.env` file is refused with the shared read-guard message
before any provider dispatch (mutation-verified).
@alt-glitch alt-glitch added type/security Security vulnerability or hardening tool/tts Text-to-speech and transcription P3 Low — cosmetic, nice to have sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data duplicate This issue or pull request already exists labels Jul 4, 2026
@alt-glitch

Copy link
Copy Markdown
Contributor

This was generated by AI during triage.

Duplicate of #57963 — both route local STT input paths in tools/transcription_tools.py through agent.file_safety.get_read_block_error() before cloud provider dispatch (same defense-in-depth parity fix as image-gen/video-gen). #57963 is the earlier open PR (guards inside _validate_audio_file); this one guards at the top of transcribe_audio — same mechanism. Keeping #57963 as canonical; maintainer picks.

@teknium1

Copy link
Copy Markdown
Collaborator

Merged into main via consolidated salvage PR #73514 (merge e807b7106c). Your read-side guard routing transcribe_audio inputs through the shared get_read_block_error was cherry-picked with your authorship (verified gateway temp-dir voice notes pass clean).

Your contribution is credited to you in git history. Thank you! Closing this PR as merged-via-salvage.

@teknium1 teknium1 closed this Jul 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

duplicate This issue or pull request already exists P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-security-boundary Sweeper risk: may affect sandboxing, auth, credentials, or sensitive data tool/tts Text-to-speech and transcription type/security Security vulnerability or hardening

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants