Skip to content

Security: CmdDraven/btw

SECURITY.md

Security

Scope and operating model

Evangelotron is a local-first Linux command-line utility. It has no daemon, remote control endpoint, plugin loader, telemetry, automatic update check, cloud TTS, or automatic package installation. Local playback needs local system binaries; direct Cast stays on the LAN; Home Assistant traffic goes only to the endpoint configured by the user.

The threat model assumes that distro/message text and LAN device names may be hostile data, configuration may be malformed, services may hang or misbehave, and Home Assistant bearer tokens are sensitive. It does not attempt to defend against an attacker with root access on the same host.

Only configure devices and services that you own or are authorized to control.

Authorization

Discovery is not authorization. Direct Cast control is limited to UUIDs or exact friendly names explicitly listed in [cast].targets. Exact names that match multiple devices fail as ambiguous. known_hosts is only a discovery hint, and --all means configured sink classes—not every device on the LAN.

Home Assistant communication is restricted to the configured base endpoint. Redirects are not followed to another host. evangelotron doctor --network uses the non-mutating authenticated GET /api/; normal HA announcement uses the documented configured event endpoint.

Credentials and transport

Home Assistant tokens are referenced through a configured environment-variable name or an absolute token-file path. Configuration does not contain the token value. Static doctor reports only the reference and its local presence or file permission state; it does not print environment values or read token-file contents. Network operations resolve credentials lazily and redact failures.

HTTPS retains normal certificate verification. Plain HTTP is accepted only when allow_insecure_http = true; doctor still warns because a bearer token can be observed by anyone able to inspect that path. No certificate bypass is attempted automatically.

Temporary Cast media exposure

For direct Cast playback, Evangelotron creates a purpose-built standard-library HTTP server that:

  • binds to a kernel-selected route-reachable local address;
  • uses an OS-assigned ephemeral port;
  • exposes exactly one generated audio asset;
  • uses a cryptographically random, unguessable path;
  • accepts only GET and HEAD for that exact path;
  • returns 404 for every other path;
  • has no directory listing, upload path, or access log;
  • closes after bounded playback handoff or a hard lifetime.

The temporary URL contains no credentials or message metadata. Another local or LAN process that learns the URL while it is active may fetch the asset; the random path, narrow bind, and short lifetime reduce rather than eliminate that risk.

Process and network safety

User/config-derived values remain subprocess data and are never assembled into shell commands. Network discovery, HA requests, Cast connection/playback, and the temporary server all have explicit time bounds. Cast receiver volume is never changed automatically. Active or unknown media is skipped unless the user explicitly opts into interruption.

One per-user cooldown reservation limits accidental repeat invocation. Its advisory lock protects only the atomic reservation and is released before synthesis, playback, or network operations.

Generated WAV files, discovery resources, Cast connections, HTTP listeners, threads, timers, and locks are cleaned during normal completion, failures, and handled interruption. An abrupt SIGKILL can prevent cleanup; a temporary audio file may then remain until its runtime/temporary directory is cleaned.

Configuration is treated as local user-controlled input. btw validates its schema but does not rewrite configuration, repair permissions, or install missing software.

Privacy

The project does not collect analytics, inventory devices persistently, upload generated audio, or contact a public service. The HA event contains only its documented schema fields. Cast discovery results are printed only when explicitly requested and are not written into configuration.

Reporting a security issue

Do not include bearer tokens, private device inventories, generated audio, or other secrets in a public report. Use a private contact mechanism offered by the repository host or maintainer if one is demonstrably available; otherwise ask the maintainer for an appropriate private reporting channel before sending sensitive details. This document does not claim that a particular hosted private-vulnerability feature is enabled.

The repository has not yet completed its dedicated release-readiness audit and does not claim a final security verdict.

There aren't any published security advisories