Security¶
This page is about who can make Hylo do what over a network or through a config. Keeping the robot within limits is a different subject: see safety.
A config is code
A component in a config can be named by module:attr as well as by a registered name, and the registry imports
and calls it with the config's params (Registry.resolve in core/registry.py). A config, an override
(--set agent.type=...) or a campaign patch can therefore run any importable callable with any arguments, as
the user who runs Hylo. Treat everyone who can submit a config as someone with a shell on that machine.
What is exposed where¶
| Service | Default bind | Authentication | Who can do what |
|---|---|---|---|
hylo serve policy |
127.0.0.1:8000 |
optional shared token: Authorization: Bearer <token> or openpi's Api-Key <token> (--token) |
anyone with the token gets actions from the served policy |
hylo serve env / hylo serve agent |
127.0.0.1 |
optional bearer token (--token-env NAME reads it from the environment) |
the component is fixed when the server starts; clients cannot choose what is loaded |
hylo serve workcell |
127.0.0.1:8100 |
optional bearer token on HTTP, ?token= on the event stream; /healthz is open |
anyone with the token can start episodes and send operator events to a robot |
hylo playground (studio) |
127.0.0.1:8765 |
optional --token, or role tokens --role-token viewer=... operator=... approver=... |
see roles |
Every service binds to the loopback interface unless told otherwise (--host 0.0.0.0). Tokens travel in clear text
over http:// and ws://: none of the servers terminates TLS.
Recommendations¶
- Keep services on loopback and reach them through an SSH tunnel (
ssh -L 8100:127.0.0.1:8100 robot-host) or a reverse proxy that terminates TLS and authenticates users. Usewss:///https://through that proxy. - Set a token on everything that leaves loopback, from an environment variable, never from a file in a repository (the deployments repository keeps tokens out of its configs). Use one token per service, so that revoking one does not stop the others.
- Give studio role tokens whenever more than one person can reach it. Without role tokens (and without
--token) the local user has every role. - Install plugins you trust. A plugin is Python code that runs with your permissions; the registry loads it by
name from its entry points.
hylo pluginslists what is installed and from which package. - Review candidate patches before approving (
approval: manualin a campaign): a patch can change any component. Generators only produce config patches, and model-generated code is never executed, but a patch can still name amodule:attr. Stage 0 refuses patches to the protected scopes (safety,benchmark,trace,scorers,env,evolution,schema_version) and checks the provenance of referenced artifacts; it does not restrict which components a patch names. - Treat run directories as data you produced. Traces, manifests and artifacts are JSON, msgpack and
.npzfiles; Hylo never unpickles them (core.codec,core.remote.wire: object dtypes are refused). A learner or adapter that loads third-party checkpoints follows that library's rules (for example PyTorchtorch.load).
Studio roles¶
| Role | Can |
|---|---|
| viewer | read everything; press the e-stop of a workcell (stopping is never gated behind a higher role) |
| operator | everything a viewer can, plus start live runs, jobs (run, evolve, learn (with any --python interpreter), calibrate) and workcell episodes, and send operator events |
| approver | everything an operator can, plus approve or roll back a campaign's promotion |
Because jobs and live runs take configs and overrides, the operator role can run code on the studio machine (see the warning at the top). Give it to people you would give a shell to.
Remote components¶
Remote environments and agents (env.remote, the remote agent, remote.ws) exchange msgpack messages with
numpy arrays encoded explicitly (core.remote.wire); pickle is never used, and object or void dtypes are refused.
A subprocess component (env.remote: {runtime: ...}) is started by Hylo itself from this machine's
profile; a WebSocket component (hylo serve env|agent) is chosen by whoever starts
the server, not by its clients.