Repository navigation
v0.17.0: secure transport — LAN-scoped by design, loud when it matters - #18
Merged
Merged
Conversation
…warning
Add a top-level "tls" config block that serves HTTPS without requiring
mTLS. Cert/key default to the internal CA server leaf written by --init,
so "tls": {"enabled": true} is a one-line fix on any initialized data
directory. auth.mtls remains the optional client-certificate layer on
top and existing mtls-only configs serve TLS exactly as before.
At startup, when server.listen binds a non-loopback address and TLS is
not enabled, log a prominent multi-line INSECURE TRANSPORT warning
naming what is exposed (bearer tokens, secret values, dashboard
cookies when enabled) and the one-line fix. Warn only — never refuse
to start. Plaintext loopback remains the silent, supported default.
New internal/transport package carries loopback detection and the
shared warning text for the server, CLI, and MCP transport.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…intext warnings MCP Streamable HTTP mode gains --tls-cert/--tls-key flags (env: PHOENIX_MCP_TLS_CERT/PHOENIX_MCP_TLS_KEY); the --init server leaf works as-is. On a non-loopback bind without TLS it logs the same INSECURE TRANSPORT warning as the server and still starts. The CLI warns on stderr (and proceeds) when PHOENIX_SERVER is plain http:// to a non-loopback address; the Go SDK does the same once per distinct server URL. Loopback http:// stays silent — it is the supported default. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Covers: silent loopback plaintext default, INSECURE TRANSPORT warning on non-loopback binds (asserted via an unbindable TEST-NET-1 address so no listener leaves loopback), the dashboard exposure line, tls.enabled HTTPS with the --init leaf, mtls-only backward compatibility, CLI warn-but-succeed posture, and MCP HTTP TLS serving plus its warning and lone --tls-cert rejection. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
threat-model.md gains a deployment-envelope section: Phoenix is LAN-scoped by design, internet/WAN exposure is out of scope and unsupported; LAN is in scope but not a trust boundary; plaintext loopback is the safe default and crossing a wire means enabling TLS. Mitigation claims re-audited against the envelope: source-IP binding and per-IP rate limiting are scoped to LAN-envelope addresses, DDoS resistance is a non-goal, and the dashboard deployment options now lead with loopback and native TLS instead of requiring mTLS. lan-deployment.md is rewritten onto the tls: block — HTTPS is one config line with the --init certificate, and mTLS moves to a clearly optional step 3 (still required for cert issuance and require_mtls policies). Client setup now shows the bearer-over-TLS variant, and the guide documents the startup warning operators will see if they skip TLS on a non-loopback bind. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
configuration.md documents the tls block (fields, --init leaf default, independence from mtls) and rewrites the transport-security section and deployment table around it; the Docker note now pairs 0.0.0.0 with TLS or a loopback port mapping. authentication.md states up front that transport (tls block) is separate from authentication and that no auth method requires mTLS for HTTPS; drops a stale .home hostname from the mTLS example. integrations.md: MCP HTTP examples bind loopback and document --tls-cert/--tls-key; https:// examples now carry PHOENIX_CA_CERT; the Compose example's non-loopback plaintext PHOENIX_SERVER is explicitly annotated (single-host bridge, no published port) with a TLS variant alongside — no silent non-loopback http:// remains. getting-started.md sets the loopback expectation explicitly, walks LAN setup through tls.enabled, and names the startup warning. dashboard.md reorders transport options to loopback/native TLS/reverse proxy and documents the warning. README.md carries the LAN-scoped deployment envelope where evaluators see it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Add PHOENIX_CA_CERT to every https:// client example (multi-agent-setup, migration-env-to-phoenix, sealed-responses, session-identity) so the documented enrollment story — CA cert once, https:// URL — actually validates against the internal CA, and note in multi-agent-setup that loopback plaintext without a CA cert is the expected single-machine setup. Replace the two stale phoenix.home hostnames with the generic service name used elsewhere. Repo-wide check: the only remaining non-loopback http:// example is the annotated single-host Compose block in integrations.md; examples/, docker-compose.yml, and the Dockerfile are loopback-only already. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
New config surface (tls: block), new MCP TLS flags, and new warning behavior on insecure transport. No breaking change: existing configs, including auth.mtls.enabled, behave identically. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
staticcheck v0.8.0 requires Go >= 1.26. CI runs Go 1.25 with GOTOOLCHAIN=local, so it cannot auto-upgrade and `@latest` fails at install time — breaking every build regardless of the code under test. It passed locally only because a developer shell defaults to GOTOOLCHAIN=auto and silently fetches a newer toolchain. Pin to v0.7.0, verified clean under Go 1.25 with GOTOOLCHAIN=local, and bump it deliberately alongside go-version. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phoenix is LAN-scoped by design. Use outside a LAN — internet/WAN exposure, public ingress, hostile-network operation — is out of scope and unsupported. Being in scope is not the same as being trusted: a LAN includes containers on shared bridges, IoT devices, and anything that has compromised one host, so TLS matters whenever a request crosses a wire.
Plaintext on loopback stays the default and is unchanged.
The defect this fixes
The default was safe only because it was loopback, and nothing signalled when that stopped being true. Editing
server.listento0.0.0.0:9090— an edit typically made for an unrelated reason — silently moved bearer tokens and secret values onto the wire. The startup log named the address and said nothing about transport.This fixes the signal, not the default.
Changes
tls:config block, independent ofmtls:. TLS serving previously existed only inside the mTLS block, so operators had to enable client-certificate authentication just to get HTTPS —docs/lan-deployment.mdliterally instructed exactly that."tls": {"enabled": true}now works alone, defaulting to the server leaf--initalready generates.mtls:becomes purely the client-certificate layer.--tls-cert/--tls-key, orPHOENIX_MCP_TLS_CERT/PHOENIX_MCP_TLS_KEY), with the same warning.http://. Warn and proceed.threat-model.mdgains a deployment-envelope section and its mitigations were re-audited against it;lan-deployment.mdrewritten ontotls:with mTLS as a separate optional step. No silent non-loopbackhttp://examples remain.Compatibility
No action required on upgrade. Existing configs behave identically, including
auth.mtls.enabled: true, which still implies TLS. Binding non-loopback without TLS now prints a warning — that is the point, and the fix is one line.Validation
gofmt,go vet,staticcheck, andgo test ./...clean. e2e: 18 pass, 2 environmental skips (09 Docker, 12 1Password), including new scenario 19 and scenario 18's v0.13.5 upgrade path.Verified separately that a real
0.0.0.0bind both emits the banner and continues to serve — scenario 19 asserts the warning via an unbindable address, which proves the warning fires but not that the server still works, so that was checked by hand.🤖 Generated with Claude Code