Repository navigation
feat(xtcp2): listener model, authenticated socket by default (FP-3) - #295
Merged
Merged
Conversation
First of three FP-3 commits: config and package, no daemon wiring yet.
- proto: EndpointClass (health, metrics, metrics-detail, ip, debug,
grpc-read, grpc-admin), Listener{name, endpoint, auth, admin_auth,
serves}, repeated listeners = 162; ListenerAuth gains raw_token_file and
hmac_shared_key_file so per-listener credentials are paths, never
secrets in the config; grpc_port no longer required (legacy only)
- pkg/listeners: Default (one UDS /run/xtcp2/metrics.sock 0600, raw auth,
health+metrics+metrics-detail), Validate (class on one listener, no
gRPC/HTTP mix, TCP must be typed, disabled auth only on UDS, loopback or
health-only, debug/grpc-admin need an admin credential, ip needs
ip_paths, no inline credentials), Resolve (endpoint, TTL 1 + loopback
accept filter on loopback TCP, token files), ParseSpec/ParseList for
-listener and LISTENERS; errors wrap ErrConfig (exit 64)
- pkg/secretfile: the FP-2 _FILE reader, shared by cmd and listeners
- RedactSecrets also blanks listener credentials; the redaction test now
walks repeated fields and allow-lists the *_file path fields
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Wire the listener model into the daemon:
- Validate the config and resolve every listener and its credentials
before anything binds; a bad listener config or token file exits 64.
- With no listener configured, serve health, metrics and metrics-detail
on /run/xtcp2/metrics.sock (0600, raw bearer token). gRPC, pprof and
/ip are served only by a listener that names them.
- -listener (repeatable) / LISTENERS describe listeners. The -prom*,
-grpc* and -linkMonitorIPListen settings still work, expanded with a
deprecation line; giving both forms exits 64. The expanded Prometheus
listener no longer serves pprof.
- One HTTP mux per listener from the classes it serves; pprof only on a
debug listener, /debug/pprof/cmdline never.
- gRPC servers start per listener; grpc-read registers no admin
services.
- -healthcheck finds the health listener from the same config.
- An empty -listenerAuthMode / LISTENER_AUTH_MODE is unset, not
disabled, so the raw default cannot be switched off by accident.
- ConfigService.Set refuses a listener config startup would refuse.
- xtcp2_listener_active{name,network,class}.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
The daemon no longer listens on :8889 unless told to, so the clients dial unix:/run/xtcp2/grpc.sock (listeners.DefaultGRPCSocketPath), the documented place for a gRPC listener. -network tcp with -target/-port still reaches a TCP listener. Co-Authored-By: Claude Opus 5.5 <[email protected]>
- pkg/listeners: an unset auth mode is inferred from the credential given (an hmac file means hmac, a token means raw), for admin auth too. - NixOS module: `listeners` and `listenerTokenFile` options; with no token file a token is generated once under /var/lib/xtcp2. linkMonitor.ipListen becomes a loopback ip listener. - microVMs: explicit TCP listeners with a fixed test token; the self-test, scrape-auth, linkmonitor and ip-listen tests send it. uds-security keeps the socket-only shape. - OCI daemon images expose no ports. - Docs and CHANGELOG for the listener model, the deprecated flags and the client defaults. - Lint fixes in the listener wiring; a short socket dir for TestProbeReadyUnix (sun_path is 108 bytes). Co-Authored-By: Claude Opus 5.5 <[email protected]>
Set validated the listeners before restoring the redacted credentials and never read the per-listener token files. A Get -> Set round trip with an inferred admin auth was refused, and a missing or open token file was accepted, the restart scheduled, then startup failed with the daemon down. Set now runs listeners.Resolve, as startup does, after the secret preservation and on a clone so file contents never reach the response. The table covers both failures. Co-Authored-By: Claude Opus 5.5 <[email protected]>
Named constants for repeated strings, explicit UNSPECIFIED network cases, and preallocated slices. Co-Authored-By: Claude Opus 5.5 <[email protected]>
randomizedcoder
force-pushed
the
sec/fp3-listener-model
branch
from
November 12, 2026 04:40
10a261c to
bc73a8e
Compare
randomizedcoder
force-pushed
the
sec/fp2-secrets-s3-tls
branch
from
November 12, 2026 04:40
821ce98 to
5328f1b
Compare
Owner
Author
|
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.
Phase F1, FP-3 of the focused container hardening plan (#291). Based on FP-2. Breaking: see CHANGELOG.
-listener(repeatable) /LISTENERS, each with an endpoint, auth, admin auth and the endpoint classes it serves (health, metrics, metrics-detail, ip, debug, grpc-read, grpc-admin). Rules live in the newpkg/listeners./run/xtcp2/metrics.sock, mode 0600, raw token fromLISTENER_RAW_TOKEN_FILE, serving health and metrics. No TCP listener. A missing token exits 64.debug;/debug/pprof/cmdlineis never registered.grpc-readregisters read-only service adapters, so admin RPCs are not reachable on it at all.-prom*,-grpc*and-linkMonitorIPListenflags still work, expanded into listeners with aDEPRECATEDline; mixing them with-listenerexits 64. An unset auth mode is inferred from the credential given.-healthcheckprobes whichever listener serveshealth.ConfigService.Setvalidates listeners. Gaugextcp2_listener_active{name,network,class}.xtcp2ctlandxtcp2clientdialunix:/run/xtcp2/grpc.sockby default;-network tcpfor TCP.listenersandlistenerTokenFileoptions; with no token file, one is generated once under/var/lib/xtcp2. OCI daemon images expose no ports.Verified: Go tests and race on
cmd/xtcp2,pkg/xtcp,pkg/listeners; golangci-lint, go-sec, flavor checks; microVMs uds-security lifecycle, scrape-auth, linkmonitor, ip-listen.🤖 Generated with Claude Code