Agent
The agent is one long-running process per machine that serves every endpoint you declare in the dashboard. Add, edit, or remove an endpoint at hle.world/dashboard and the agent converges within seconds — no restart, no SSH, no process per tunnel.
hle tunnel create | hle agent | |
|---|---|---|
| Tunnels per process | one | many |
| Configured in | the command line | the dashboard |
| Changing a tunnel | restart the command | takes effect in seconds |
| Credential | API key (hle_…) | agent token (hlea_…) |
Use hle tunnel create for a quick one-off share. Use the agent for anything you want
to keep running.
An endpoint’s target is any URL the agent can reach — not just services on its own machine, but anything on its network.
What an agent also unlocks
| Firepuncher | Reach any TCP port the agent can see — SSH, Postgres, RDP — with no port open anywhere |
| Service discovery | The agent inventories your Kubernetes Services and Docker containers so you can expose one in a click |
| Traffic & metrics | One chart and one metric strip for the agent, each endpoint, and every forward |
Install
The installer sets up the client, enrolls the machine, and installs a service that starts at boot — in one command:
curl -fsSL https://get.hle.world | sh -s -- --agentIt prompts for the agent token. To get one, go to Connections → New → Agent in the
dashboard and copy the hlea_… value. It is
shown only once.
For unattended installs (cloud-init, Ansible, CI), pass the token instead:
curl -fsSL https://get.hle.world | sh -s -- --agent --token hlea_xxxxxInstaller options
| Flag | Effect |
|---|---|
--agent | Enroll the machine and install the agent service |
--token <hlea_…> | Provide the token non-interactively (implies --agent) |
--no-service | Enroll only — don’t install a service |
--user | Per-user service (no sudo) |
--system | System-wide service, starts at boot (needs sudo) |
--version <v> | Pin a specific hle-client version |
Without --user or --system the scope is auto-detected: running as root
installs a system service, otherwise a per-user one.
Manual setup
If you already have the client installed:
hle agent enroll # prompts for the tokenhle daemon install agent # install + start the background serviceOr run it in the foreground to watch what it does:
hle agent runAdd endpoints
Everything else happens in the dashboard, under Connections → Agents → your agent → Endpoints. Each endpoint has:
- Label — used in the public hostname (e.g.
ha→ha-x7k.hle.world) - Local URL — where the agent should forward to (e.g.
http://localhost:8123) - Domain — the base domain, or one of your custom zones
- Auth — SSO or open
A typical homelab agent:
| Label | Local URL | Public URL | Auth |
|---|---|---|---|
ha | http://homeassistant:8123 | ha-x7k.hle.world | SSO |
jelly | http://nas:8096 | jelly.example.com | SSO |
git | http://git:3000 | git-x7k.hle.world | SSO |
Manage the service
hle daemon status --agent # is it running?hle daemon uninstall --agent # stop, disable, and remove itUnder the hood this is a systemd unit (hle-agent.service) on Linux and a
launchd job (world.hle.agent) on macOS. Read the logs with:
# Linux, system servicesudo journalctl -u hle-agent -f
# Linux, per-user servicejournalctl --user -u hle-agent -f
# macOStail -f ~/Library/Logs/hle/agent.logUpdating an agent
hle updateIt upgrades the client, rebuilds the service against it and restarts it. Say
yes when it offers the restart, or the agent keeps running the previous release
while hle version reports the new one.
Do not re-run the install script to update an agent. It builds from scratch, which replaces the client underneath the running process and leaves the service describing the install it replaced.
If the agent is reachable only through a tunnel it carries — a firewall, a remote box with no other way in — note that restarting it drops your own connection for a second or two. The restart is detached from your shell so the agent still comes back if the session dies with it.
Per-user services and logout
A per-user systemd service stops when you log out unless lingering is enabled:
sudo loginctl enable-linger $USERA system service (--system) has no such caveat — prefer it on a headless box.
Where the token lives
hle agent enroll writes the token to ~/.config/hle/agent.toml with mode
0600. It is never written into the service definition, so the unit file is
safe to read, back up, or commit as a template.
A system service runs as a specific user (--run-as, defaulting to whoever ran
the install) and reads that user’s agent.toml. If you enroll as one user and
install the service as another, the agent won’t find the token — enroll as the
same user, or set HLE_AGENT_TOKEN in the unit’s environment.
You can also supply the token entirely by environment variable, which is what the container images do:
export HLE_AGENT_TOKEN=hlea_xxxxxhle agent runRotating or removing a token
Tokens can’t be retrieved after creation. To rotate one, create a new agent in the dashboard, re-enroll, and restart the service:
hle agent enroll # paste the new tokenhle daemon uninstall --agenthle daemon install agentTo remove the saved token from a machine:
hle agent logoutContainers and platforms
- Docker —
HLE_AGENT_TOKENwith theagentprofile - Home Assistant — the
agent_tokenadd-on option - Proxmox — one agent per node or LXC
- Unraid — agent container template
Troubleshooting
The agent shows offline in the dashboard. Check the service is running
(hle daemon status --agent) and look at the logs. The agent needs outbound
HTTPS to hle.world:443; it never accepts inbound connections.
An endpoint shows an error. The agent could reach the server but not your
local service. Verify the local URL from the machine running the agent — inside a
container, localhost is the container, not the host.
“No agent token” on service start. The service is running as a user without
~/.config/hle/agent.toml. See Where the token lives.
A “Duplicate” badge, or “Another machine is using this agent’s token”. Two copies are running on one token. They take every tunnel off each other roughly once a second, so the agent reports online the whole time while nothing it serves ever settles.
Run hle daemon list on each machine to find the copy you did not mean to run.
The usual cause is a foreground hle agent run left alongside the service —
often on the same machine, which is why the warning can name the host you are
already on. If both machines should be agents, enrol the second one separately
from the dashboard rather than copying the token.
The warning clears itself 15 minutes after the last refused connection. It does not need dismissing: while the duplicate is running the attempts never stop for long, so a quarter of an hour of silence means it has been stopped. Each refusal is also recorded under the agent’s connection events, which stay after the banner goes.