Security model
loadout writes a file your shell executes at every login, puts executables on your PATH, and holds the keys to your keychain entries. Each of those is a place where getting it wrong is serious rather than annoying.
Secrets never enter a file loadout controls
Section titled “Secrets never enter a file loadout controls”Configuration holds credential names and which entry is active. Values live in the OS keychain.
Two mechanisms enforce it:
loadout scanmatches high-signal credential shapes —ghp_,npm_,AKIA, JWTs, PEM blocks, literalpassword:fields — and refuses them.sync pushruns the same scan before the commit, not before the push, so a pasted token never enters git history at all. Once committed, removing it needs a rewrite and the value must be treated as leaked anyway.
Entropy heuristics were rejected deliberately: they fire constantly on hostnames and paths, and a check that cries wolf gets disabled.
Credential output is single-quoted with embedded quotes escaped, because it is eval-ed. A token containing $(...) or backticks cannot execute anything.
Anything on PATH is verified
Section titled “Anything on PATH is verified”Managed binaries are the one feature that downloads code and then runs it.
- HTTPS on every redirect hop, not just the configured URL. Release hosts redirect to CDNs, and a redirect to
http://would otherwise be followed silently. - Checksums are verified before install, not after.
- Archive members with absolute or
..paths are refused, and extraction is size-capped, so an archive cannot write outside its target. - Writes land via rename, so an interruption cannot leave a half-written executable on your
PATH. - Provenance is recorded.
bin listshows the exact URL each binary came from. - The managed directory is appended to
PATH, so a managed binary cannot shadow a system tool.
loadout update applies the same rules to itself, and refuses a release that publishes no checksum rather than installing it unverified.
The web interface is an RCE API for your account
Section titled “The web interface is an RCE API for your account”This is the sharpest edge in the project, and it is worth stating in those terms: the interface rewrites what your shell runs at login. Anyone who can drive it can run arbitrary code as you, the next time you open a terminal.
Binding to 127.0.0.1 keeps other machines out. It does not keep other pages out — any site open in your browser can issue requests to localhost. Three checks precede every request:
- A per-run token, generated at startup and compared in constant time, so the comparison cannot be used as an oracle to guess it byte by byte. It reaches the page in the query string, because a navigation cannot set a header, and the page moves it into
sessionStorageand strips it from the URL immediately. - Origin must be ours. Any other site’s
Originis refused before the token is considered. - Host must be loopback. This is the DNS rebinding defence: an attacker pointing a hostname they control at
127.0.0.1gets aHostheader that does not match.
Static assets are the one deliberate exception, served without a token, because a <link> or <script> tag cannot present one. They are inert files compiled into the binary, identical for every user, and disclose nothing.
Credential values are never sent to the page. It is told only whether a value exists.
Why no reverse proxy
Section titled “Why no reverse proxy”Putting the interface behind a public hostname does not work by design — the loopback check refuses it with a 403 before any handler runs.
Allowing a configured hostname would be a small change and is deliberately not offered. That check is the rebinding defence, and removing it leaves a single per-run token in a URL as the only thing between the internet and this API. URLs leak through history, referrer headers, proxy logs and screen shares. The token is valid for the whole life of the process, with no revocation and no audit trail.
SSH port forwarding gives the same access over a credential you already have, with nothing new exposed. That is the supported answer.
What is out of scope
Section titled “What is out of scope”- A compromised machine. loadout runs as you and can do what you can. It is not a sandbox.
- Your keychain’s own security. loadout stores and retrieves; the keychain decides when to prompt.
- What you put in a custom alias. Custom entries are rendered as given.
- Your configuration repository’s access control. Use a private repository — even without secrets, it names your hosts, paths and identities.
Reporting
Section titled “Reporting”Report privately through the security policy rather than opening a public issue.
Useful in a report: what you can make it do, not just what looks wrong. The distinction between a token in a URL and arbitrary code execution is the whole reason the loopback check exists, so a report that names the impact gets a faster answer.