Report suspected vulnerabilities through GitHub private vulnerability reporting. If that private form is unavailable, contact the maintainer through the repository's published GitHub profile and request a private reporting channel.
Do not open a public issue for an unpatched vulnerability or include device codes, bearer tokens, cookies, ChatGPT credentials, API keys, private workspace contents, or full authorization headers.
Include a concise impact statement, affected component/version, reproducible steps using synthetic data, expected and observed behavior, and a suggested mitigation where safe. We will acknowledge reports when a private channel is available and coordinate a fix and disclosure timeline with the reporter.
The browser talks to Home Assistant, and Home Assistant talks privately to the Bridge. Do not expose the App or Bridge as a browser endpoint. Use Home Assistant's supported LAN, VPN, Nabu Casa, Cloudflare, or HTTPS reverse-proxy access path, terminating that route at Home Assistant rather than proxying it through to the App or Bridge.
The App uses ChatGPT device login and does not use an OpenAI API key. In App
mode, keep workspaces under /config/workspaces; do not mount Home Assistant
configuration, host filesystems, or broad shares into the normal Bridge App. The App fails closed when its
tool-sandbox attestation is unavailable. Do not weaken AppArmor, container
permissions, or network restrictions to bypass it.
The optional Codex Host Access App is a deliberate exception with a separate installation and explicit consent. It shares the HAOS PID namespace and, with Protection mode disabled, enters the host environment as root. It can access host files, mounted storage, credentials, containers, services and the host's network. The ordinary Bridge App keeps its existing permissions.
Installing or privately pairing the companion does not enable it. A Home Assistant administrator must acknowledge the current machine-specific warning, then select host access for each chat or schedule. Scheduled work needs its own unattended acknowledgement. A changed environment or revoked grant blocks new work; the Bridge never silently substitutes another environment.
Root access is not a containment boundary. Commands can change access controls, read Codex and integration credentials, or start work outside the tracked process group. Cancellation and revocation prevent new Bridge commands and attempt to stop tracked work; they cannot undo changes or guarantee termination of independently started work. See the complete disclosure and installation guide.
Administrator chat activity can include bounded command previews. The Bridge omits commands with recognised credential patterns before saving activity, but this filter cannot identify every secret. Unrecognised credentials in command arguments may remain in private chat history and its backups. Avoid placing credentials in command arguments. Output, environment values and image paths are not added to these events. See chat activity for display limits and compatibility behaviour.
Automations are administrator-created records. Home Assistant owns the clock; the Bridge stores the prompt and target, enforces revision and idempotency checks, limits run history, and records skipped overlap/capacity/misfire cases. Treat a scheduled task as a request to claim work, not as an unconditional promise that a Codex turn will run. Stop or pause automations before changing a workspace or restoring a backup.
Skills and plugins are constrained to the selected workspace and the Codex
runtime's reported configuration. AGENTS.md writes are limited to the global
Codex home or the selected project root and keep private rollback snapshots.
Review instructions and third-party plugin/marketplace content as untrusted
input before enabling them.
MCP is disabled by default and requires the administrator to enable Enable MCP in the App configuration and restart it. When disabled, the App starts Codex with explicit disabled overrides for saved servers. Before accepting requests it checks that the effective configuration contains no enabled server, then removes the saved native MCP server table; cleanup failure keeps readiness unavailable. An empty table alone is insufficient because Codex merges tables. This does not alter skills, plugins, marketplaces, or instructions.
Public MCP configuration without static credentials is deliberately narrow: only outbound streamable-HTTP servers using HTTPS hostnames are accepted. Literal IPs and local/internal names are rejected, and available DNS answers are checked for non-public addresses before a server is saved. DNS checks are best effort, do not create a connection-time IP allowlist, and cannot prevent a trusted name's ownership or answers changing later. An administrator must still trust every configured provider. The local MCP option is a deliberate exception to the public-destination rule. It is disabled by default and requires separate acknowledgement for each LAN or HA App endpoint. Local connections use an authenticated loopback relay, never a direct native upstream URL. A private registry records the selected URL and approved RFC1918/ULA addresses. Every request resolves and checks the complete answer set against those addresses, then dials an approved IP directly with the original HTTP Host and verified TLS hostname. Redirects, environment proxies, loopback/link-local/metadata destinations and Supervisor access are rejected. A DNS address change requires removing and re-adding the connection. HTTP sends MCP data and any URL-path secret without encryption; the UI warns before consent. Only the fixed saved endpoint receives MCP protocol headers and bodies. The relay's generated capability header never reaches the upstream server. Request, stream and concurrency limits bound resource use. Disabling local access removes its native bindings and prevents their restoration without a new connection. Local OAuth is not supported in this release. Existing public HTTPS/OAuth behaviour is unchanged, including its best-effort DNS limitation.
MCP-02 permits administrator-supplied bearer tokens and explicitly named authentication headers. The private relay stores them in the App's restricted private registry and injects them only for the saved destination. Credentials are not encrypted separately from App storage: protect App backups, which include them, and revoke old credentials at their provider after restoring an old backup. They are never written to Codex configuration or workspace files. Credential requests use bounded, administrator-authenticated HTTP routes with fixed errors and no-store responses, avoiding WebSocket debug-message logging. The UI never reads saved values and clears submitted secrets even on failure. Public credential endpoints require HTTPS and connection-time public IP pinning; local HTTP also requires the existing unencrypted-transport acknowledgement. Removal blocks new upstream requests and cancels active relay requests without falling back to unauthenticated access. It cannot undo accepted server actions or revoke credentials at their provider. Destination changes require removing and recreating the connection. Routing/protocol headers, cookies, duplicate headers and control characters are rejected. The relay redacts literal and JSON-escaped reflected credentials across response chunks. A trusted server receives its credential and can misuse or transform it; redaction cannot make an untrusted provider safe.
ADR 0009 defines a separate execution boundary for MCP-03. It is disabled by default. Existing public HTTPS/OAuth and acknowledged LAN/App relay rules remain in force. Enabling MCP or installing an App update must not silently create or activate a stdio worker.
The first stdio release supports approved Python 3.14 packages on
amd64 only. Packages and dependencies are pinned in a root-owned catalogue
within the signed immutable App image, with source, exact version, file digests
and fixed entrypoint recorded in a manifest. Activation re-verifies the
package bytes. The administrator must see the source, fixed command, grants
and selected tools before approval. A package update stages a new paused
revision, verifies it, waits for active work, then switches atomically. Rollback
requires a previous revision still bundled in the App. Runtime package downloads,
user-uploaded executables, native Codex command entries and arbitrary
environment variables are not permitted.
Codex connects only to a generated, authenticated loopback HTTP endpoint owned by the trusted Bridge. The Bridge owns each stdio session and passes only bounded MCP JSON-RPC lines through private pipes. Its capability header, HTTP authentication, Supervisor token and Codex sign-in state must never reach the worker. A worker needs its own AppArmor child, Bubblewrap namespaces, locked seccomp filter, no usable capabilities, clean allowlisted environment and independent root startup proof. It sees only immutable package files and bounded disposable scratch space. The first release grants no workspace, Home Assistant, App-private or host files and no network access. File access for a particular chat requires a proven request-to-chat ownership boundary; the current global MCP binding does not provide that evidence.
New stdio connections start paused with no allowed tools. The administrator chooses tools after discovery; descriptions and safety annotations supplied by the package are untrusted. Configuration leases must keep pause, updates and tool policy consistent across chats and scheduled tasks. Admission requires a verified isolation proof and a resource budget coordinated with the optional browser worker. Time, process, memory, file-descriptor, stdout, stderr and message limits apply. Explicit cancellation, crashes, timeouts, restarts, pause, removal and failed updates must revoke sessions and clean up descendants and temporary state. Uncertain recovery blocks new work and shows a bounded recovery action; it must never fall back to running as the Bridge user. Native HAOS tests must prove these claims before publication.
OAuth login is
explicit and returns a one-shot authorization URL
with no-store handling; do not log, cache, or paste it. MCP elicitation is
declined until a separately reviewed consent flow exists. These controls do
not make the App or Bridge public and do not replace Home Assistant's own
remote-access boundary.
Unattended updates and recovery remain fail-closed. A missing or invalid App
sandbox attestation reports sandbox_unavailable; do not broaden mounts or
permissions to make a task continue. Keep a cold backup before App changes,
and do not claim arbitrary Supervisor image rollback until a prior immutable
tag and restore procedure have been tested.
The App is published as a signed, immutable image. Current component versions and user-facing changes are recorded in the release notes. A passing startup sandbox check does not establish browser-worker isolation, external proxy behaviour, or a complete restore. Keep those acceptance checks separate. Native web search and image generation remain provider-gated and do not relax model-controlled shell networking.
Artifact previews remain on the Home Assistant origin. PDFs are fetched only
through the administrator-authenticated artifact route, checked against an 8 MB
declared and observed size limit, and validated for a leading %PDF- signature.
Validated bytes are rendered on a canvas by the bundled local PDF.js renderer;
PDF.js scripting, eval, and XFA support are disabled. The panel does not use an
iframe or native browser PDF embed, and does not embed remote URLs, HTML, SVG,
XML, or an unvalidated PDF. Unsupported content keeps the safe open/download
fallback. This preview is not a Chrome/CDP endpoint and does not grant
model-controlled networking.
See ADR 0006 for the
separate isolation requirements for App-owned browser automation. The browser
is disabled by default and needs its own root startup proof after explicit
enablement. Its public-network policy, process boundary, quotas and failure
states are documented in the browser threat model.
The project can investigate vulnerabilities in the Integration, Bridge, App source, image build inputs, and documented deployment boundary. Report issues in Home Assistant, Nabu Casa, Cloudflare, ChatGPT, OpenAI, or other upstream products to their respective security processes as well.