Most server-management tooling works by reaching in: a management daemon listening on its own port, an SSH key a control panel deployed for itself, a tunnel it expects you to poke a hole for. Every one of those is a door on your server that has to stay open for the platform to keep working. Sproobo's agent never listens for anything. It only ever dials out.
The industry default is an open door
The common pattern for fleet management is some variant of "the platform connects to your server." That means an inbound port has to stay reachable — often SSH, sometimes a bespoke management port — and your firewall has to be configured to let it through. On a box behind NAT, in a private VPC, or on a residential connection with no static IP, that inbound path often doesn't exist at all without extra plumbing: port forwarding, a VPN, a reverse SSH tunnel someone has to babysit. And every inbound port, no matter how it's locked down, is one more thing that can be scanned, targeted, and eventually misconfigured.
None of that is a criticism of any one tool — it's the default shape of the problem when the platform needs to reach a server it doesn't control the network path to. Sproobo just answers it differently.
The agent only ever dials out
The on-server agent is a single static Go binary, and it never binds a listening socket for Sproobo to connect to. Instead it opens two outbound connections, both over standard HTTPS ports so they pass through the same firewall rules and corporate proxies that already let ordinary web traffic out:
- Control channel — a persistent WebSocket over WSS/443. Plan tasks flow down to the agent; heartbeats and small events flow back up.
- Bulk channel — HTTPS POST. Fact snapshots, deploy logs, and larger results go up this way instead of crowding the control socket.
Because both channels are outbound, a server behind NAT, inside a private network, or sitting on a connection with no forwarded ports at all works exactly the same as a public cloud box with a static IP. There is no inbound firewall hole to open for Sproobo, ever — see the full lifecycle on Servers & enrollment.
An identity that gets redeemed once, not remembered forever
Joining the fleet starts with a single-use enroll token embedded in the bootstrap one-liner. It's burned the instant it's redeemed — there's no expiry timer counting down in the background, because a token that only works once has nothing left for a clock to protect. Redeeming it is also the only moment the server needs anything from you beyond root SSH; after that, the agent carries its own credential.
SPROOBO_ENROLL_TOKEN='<your-token>' bash -c "$(curl -fsSL 'https://cp.sproobo.com/dl/bootstrap.sh')"That token is exchanged for an mTLS client certificate, and every connection on both channels is authenticated against it. The certificate is short-lived and auto-rotated before it expires: the control plane issues a new one, the agent adopts it, and only then is the old one revoked. That overlap window matters — if rotation fails partway through, both certificates stay valid until the new one is confirmed working, so a rotation glitch can't lock a server out of talking to Sproobo. A revoked or unrecognized certificate is rejected outright and the server gets flagged for re-enrollment. The full trust-boundary writeup is on Security model.
Bootstrap itself — installing Docker, the agent, and the firewall baseline — takes a couple of minutes. The flip from bootstrapping to ready isn't part of that wait: it happens within seconds of the agent's first successful dial-out, once its certificate is live.
A thin executor, not a remote shell
Outbound-only transport only gets you half of a trustworthy agent. The other half is what the agent is allowed to do once it's connected — and the answer is deliberately narrow. The control plane compiles desired state into a declarative plan; the agent executes a small, generic set of typed step primitives against it: bring an image, ensure a container, ensure a mount, ensure a proxy route, ensure a certificate, ensure a firewall rule, run one bounded exec, probe a health check, collect facts. It never freelances a shell command on its own initiative.
That split has a payoff beyond safety: deploy and provisioning behavior lives in the control plane's compiler, not in the agent binary. A change to how a plan gets built ships centrally, the next time that server checks in for tasks — it doesn't require rolling a new binary out across every enrolled server one host at a time. The agent binary itself does still get its own periodic, health-gated updates for the primitive set and the transport layer; it's just not the thing that has to change every time deploy logic does.
Lockout prevention is a rule, not a preference
None of this is worth much if the platform could ever wall you out of your own box. So lockout prevention is treated as absolute: no operation — a firewall rule change, an agent update, anything else, whether a human clicked it or an AI agent requested it through the same audited API — is allowed to close break-glass SSH on port 22 or sever the agent's control channel. Your own root access always keeps working, by construction, not by policy someone has to remember to enforce.
Outbound-only, mTLS-identified, tightly scoped to a handful of typed steps, and structurally barred from ever cutting off your own access — that combination is what lets an agent live on infrastructure you own without becoming one more thing you have to defend. Walk the whole enroll-to-deploy path on Getting started.