First run
Running a real local HTTPS stack means touching things the operating system protects: DNS resolution, the certificate trust store, and — on macOS and Linux — the privileged ports. rexenv asks once for each, the first time it actually needs it.
None of them phone home. All of them are undone by a single Settings → Remove system changes — see Uninstall.
macOS asks three times.
1. Admin password — the DNS resolver
Section titled “1. Admin password — the DNS resolver”What it writes: /etc/resolver/rex
Why: so https://yoursite.rex resolves to your own machine, in every browser and every
terminal, without you editing /etc/hosts for each new site. rexenv runs a small DNS server
that answers *.rex with 127.0.0.1; the resolver file is what tells macOS to ask it.
If you configure another TLD in Settings — .test, or anything else — it installs its own
resolver file the same way, and asks again at that point.
The dialog reads rexenv in bold, with rexenv’s logo on the lock, and says what it is for. If one ever reads “osascript wants to make changes.” instead, it is still rexenv asking — that is the plain fallback used when the branded prompt cannot start, and the app log says so.
2. Keychain — trusting the local certificate authority
Section titled “2. Keychain — trusting the local certificate authority”What it writes: a trust setting for rexenv’s own certificate authority, in your login keychain.
Why: so your local sites get a real green lock instead of an interstitial warning. rexenv generates a CA on your machine, trusts it for you, and signs one leaf certificate per site domain with it.
That CA signs only your local sites. It never leaves your Mac, it is not shared between machines, and removing the trust is part of the uninstall step.
macOS will ask for your login password rather than an admin password here — the login keychain is a user-level store, which is exactly why rexenv uses it.
3. Admin password — ports 80 and 443
Section titled “3. Admin password — ports 80 and 443”What it does: lets rexenv’s edge proxy bind the privileged ports.
Why: because https://yoursite.rex with no port number means port 443, and on macOS only
root may bind below 1024. The edge is the only privileged piece of rexenv; everything else —
PHP, the databases, the mail catcher — runs unprivileged on high ports.
The edge’s admin interface is a unix socket with 0600 permissions, never a TCP port. A TCP
admin API on a root-owned proxy would be arbitrary file read and write as root for anything
that could reach it.
Windows asks twice, and the second one is Windows’ own dialog rather than rexenv’s.
1. One UAC prompt — the .rex DNS rule
Section titled “1. One UAC prompt — the .rex DNS rule”What it writes: an NRPT rule —
Add-DnsClientNrptRule -Namespace .rex -NameServers 127.0.0.1 — plus a scheduled task,
\rexenv\dns-agent, that keeps rexenv’s DNS answerer running on 127.0.0.1:53 at logon.
Why: so https://yoursite.rex resolves to this computer, in every browser and every
terminal. Other TLDs get their own rule on first use.
rexenv says so before Windows does, in its own dialog — “rexenv wants to add a DNS resolver so .rex sites open on this PC. Windows will ask for your permission next.” — and the UAC prompt follows your OK.
2. Windows’ certificate dialog — trusting the local CA
Section titled “2. Windows’ certificate dialog — trusting the local CA”What it writes: rexenv’s local certificate authority into your user’s Root store — never the machine’s.
Why: so your local sites get a real green lock instead of an interstitial warning. rexenv generates the CA on your machine and signs one leaf certificate per site domain with it.
The dialog is Windows’ own: “Security Warning: You are about to install a certificate from a certification authority…”. Because the store is yours rather than the machine’s, it needs no elevation and affects no other account. Answering No cancels the step and rexenv offers it again later rather than pretending it worked.
There is no third prompt
Section titled “There is no third prompt”On macOS the edge server needs an admin password to bind ports 80 and 443. On Windows it does not — measured under an ordinary unelevated account, the bundled Caddy binds both.
It binds 127.0.0.1 only, which is also why there is no Windows Defender Firewall alert, and why your sites are reachable from this computer alone. Tunnels are unaffected: cloudflared dials out to localhost rather than opening a port.
Linux asks twice, and both are your desktop’s own password dialog — polkit, through
pkexec. Installed from the .deb, the dialog names rexenv and says what it is for:
rexenv needs administrator permission to change system settings — the .rex DNS route, the HTTPS edge, or the local certificate authority.
From an AppImage the same dialog reads “run /bin/sh as the super user” instead: the sentence
comes from a polkit action file, and only the .deb installs one. Either way, polkit keeps no
grant between dialogs — rexenv’s action is set that way on purpose, so a root step you did
not expect can never ride on a password you typed for another one. That is also why the first
dialog does two things: the DNS route and the certificate store are one command now, where
0.8.9 asked for each separately, two minutes apart on a re-run.
1. Password — the .rex DNS route, and the certificate authority in the system store
Section titled “1. Password — the .rex DNS route, and the certificate authority in the system store”Onboarding says what is coming — “Linux will ask for permission (resolver + certificate)” — and one dialog writes both halves.
The .rex DNS route
Section titled “The .rex DNS route”What it writes: /etc/rexenv/dns.d/rex (a marker), /usr/local/lib/rexenv/dns-route.sh,
and a root unit, rexenv-dns-route.service, which brings up a dummy network link, rexenv0.
.rex is that link’s only routing domain and it carries no default route, so *.rex goes
to rexenv’s resolver on 127.0.0.1:15353 and no other name does.
Why this shape: a global systemd-resolved drop-in — the obvious Linux copy of macOS’s
/etc/resolver/rex — was tried first, and it sent every name on the machine to rexenv’s
resolver. The link carries one address, 192.0.2.53/32, from a range reserved for
documentation that no real network uses, because systemd-resolved gives no DNS scope to a
link without a real address. The first Linux release’s link had none, so .rex resolved only
where another machine answered it; updating from it, rexenv offers this step once more.
Another TLD configured in Settings gets its own marker in /etc/rexenv/dns.d/, and asks again
at that point.
“Installed” means routing, not files. The route counts as installed only while
systemd-resolved actually shows rexenv0 with a DNS scope, rexenv’s resolver as its server and
.rex as its domain. A link that has lost them reads as missing, and the setup step — one
password dialog — puts them back. Re-applying keeps the link itself: it used to be deleted and
re-created each time, and 3 of 50 re-applies lost their settings to systemd-resolved cleaning
up the old link a moment late.
The local certificate authority, in two stores
Section titled “The local certificate authority, in two stores”What it writes: rexenv’s CA into your browsers’ certificate databases —
~/.pki/nssdb for Chrome and Chromium, the snap Chromium’s own database once that snap has
run, and every Firefox profile’s own database — with no prompt, through certutil. And
into the system store, /usr/local/share/ca-certificates/rexenv-local-ca.crt plus
update-ca-certificates: that is the root half of the dialog, and it is skipped when the
store already holds this certificate.
Why both: Linux has no single trust store. Browsers read their NSS databases and ignore the
system store; curl, PHP and WP-CLI read the system store and ignore NSS. A snap browser cannot
see your ~/.pki at all. So “CA trusted” in Settings means both hold the current CA, and a
site gets a green lock in the browser and a clean curl https://yoursite.rex from the same
certificate.
The CA signs only your local sites and never leaves the machine. Unlike macOS’s login
keychain and Windows’ user Root store, the system store is machine-wide — there is no per-user
store that curl and PHP read — so on Linux that half of the trust is not scoped to your
account.
2. Password — ports 80 and 443
Section titled “2. Password — ports 80 and 443”What it writes: /etc/systemd/system/rexenv-edge.service, and a root-owned copy of Caddy
under /usr/local/lib/rexenv/. systemd runs the edge as root and restarts it if it dies.
Why: https://yoursite.rex with no port number means port 443, and only root may bind
below 1024. It is asked when the stack first starts, not in the setup step. The edge is the only
privileged piece of rexenv; PHP, the databases and the mail catcher run as you on high ports.
Stop all stops the edge too — it disables the unit, so a reboot does not bring it back — and stopping or starting it is a root operation, so each asks for your password once.
The edge’s admin interface is a unix socket owned by you, never a TCP port. A TCP admin API on a root-owned proxy would be arbitrary file read and write as root for anything that could reach it.
After the prompts
Section titled “After the prompts”You should be able to create a site and open it immediately. Quickstart walks the first one.
If a prompt was dismissed by accident, nothing is broken — rexenv asks again the next time it needs that capability, and Settings can trigger each one on demand.