feat(platform): PortAccess — 80 and 443 without root (T42) - #18
Merged
Conversation
…cket filter (T42)
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.
Makes ports 80 and 443 reachable by a front end this daemon runs as an ordinary user: a no-op on
Windows,
cap_net_bind_serviceon Linux, a pf redirect plus a boot-time job on macOS — and re-checksit on every daemon start.
Design:
docs/superpowers/specs/2026-08-23-t42-port-access-design.md.What lands
A read-only
PortAccesscapability onHostanswers three questions — which mechanism does thismachine use, which port must a program bind to answer 80, is the grant already there — and the
write is two new
PrivilegedOpvariants thatmixengine-elevatevalidates itself. The daemon probesat start-up and enqueues a grant only when the probe says one is missing, which makes the producer
and the after-update re-probe the same code.
Nothing above
mixengine-platformgains a#[cfg]:PortAccessMethodis the data that exists socore, daemon and CLI can stay free of one.
Decisions worth reading
ADR 0012 — a LaunchDaemon runs
/sbin/pfctl -e -f /etc/pf.confat boot on macOS. pf is disabledon every boot and
pfctl -eneeds root, so a redirect that is only installed works until the firstreboot and then silently stops. This is the first thing MixEngine installs that acts without anybody
asking, so
CLAUDE.md's "no persistent root process, ever" is qualified rather than quietly bent:one fixed command, root-owned, no argument from anywhere,
KeepAlivefalse.Revoke names its target. A Linux capability lives on a file, so taking it back means naming that
file; reusing
PortAccessPlanwould have carriedportsinto an operation that does not read them,which is the field the split exists to forbid.
nftablesis not here. The roadmap allowed for it;setcapwas measured to work and to bereadable back without privilege, so a second Linux mechanism would have been a branch nothing
exercises.
T88b is closed by this task. Probing at every start catches a capability lost to something that
was not an update and needs no hook in the updater. Two tasks describing one behaviour is what was
avoided.
What was proven on a real machine
CI's
systemjob, all three runners green:the kernel when the file is overwritten, and taken away again. The loss is the half that matters:
it is what the argument for granting a capability on a user-writable file rests on.
pfctl -eloads it, a server on 8080 is reached through127.0.0.1:80, and after revoke/etc/pf.confis byte-identical to the one Apple ships withnothing of ours left in
/etc/pf.anchorsor/Library/LaunchDaemons.It is asserted in the
testjob with everything else.Not here, on purpose
A front end that actually listens on the granted port, and a site reachable end to end, are T43.
Reporting and repairing port access is T47. A producer for
PortAccessRevokeis T87's, and theoperation ships built, validated and tested with none.
Recorded debt: two accounts on one machine share one grant, and on macOS one anchor with one pair
of redirect targets — the second home's front end will want 8080 too and will fail to bind it. The
same debt T41 recorded for the hosts file, for the same reason.