Watch
0
0
Fork
You've already forked hyperhive
0

make squid's allowed domains editable at runtime in the swarm ui

This commit is contained in:
atlas 2026-10-28 20:39:22 +01:00 • committed by mara
commit c9abc2a42b
2 changed files with 2307 additions and 35 deletions

View file

@ -306,8 +306,43 @@ host. It never decrypts TLS, so it holds no signing key. It caches nothing.
the canary widens the restricted list by that one name. The swarm's own
service names aren't on it: they resolve to the bridge or a private address,
which the rules below refuse, and agents reach them directly. Each entry
matches that exact name. A user on the unrestricted list reaches any
matches that exact name, or with a leading dot the name and its subdomains. A user on the unrestricted list reaches any
other name too, on ports 80 and 443. Everyone else gets a 403 for it.
`allowedDomains` is the hive's own list. Squid uses it until the swarm has a
list of its own (next bullet).
- **Swarm allow-list.** The operator adds domains in the swarm UI
([allowed domains](../swarm/ui.md#allowed-domains)); the swarm controller
keeps them in one value of the `egress-allow` bucket, each for every agent
or for one agent. Every 30 seconds `hive-c0re` reads it and writes two files
beside the users file, `services.hyperhive.squid.allowedFile`
(`/var/lib/hive-squid/allowed`) and `services.hyperhive.squid.agentAllowFile`
(`/var/lib/hive-squid/agent-allow.conf`), `hive-core:squid`, `0640`, and
logs `squid allow list: 2 swarm, 3 agent entries` when they change. The
swarm-wide names join the allow ACL, so a restricted user reaches them. A
per-agent entry is a rule for that agent's squid user, `http_access allow
<user> <names>`, in the generated `agent-allow.conf` that the configuration
includes at the point where the base list gets its allow: after every
destination deny and
`deny !authed`, so the rules under _Denied before any allow_ still bind it,
and before the unrestricted rule. Only this hive's agents get a rule.
`squid-unrestricted-reload.path` reloads squid when either file changes, so
there is no deploy or restart.
A name is a DNS name of at least two labels. One leading dot (`.example.com`)
also allows every subdomain, and is the only wildcard; the controller refuses
IP addresses, other wildcards, ports, paths and the base list's names when
you add the entry, and `hive-c0re` checks each name again and skips one that
fails, or that the base list or the canary covers, or that another entry of
the same list covers. A name that resolves to a private address stays a 403.
The swarm's list replaces the hive's `allowedDomains` as soon as it exists,
even when empty: add the names the hive allowed to the swarm's list
before relying on it. Until the controller has a list (it predates the
feature, or nobody added an entry) `allowedFile` holds `allowedDomains` and
`agent-allow.conf` is empty. A queue that stops answering for the bucket
leaves a file the swarm wrote untouched, and a failed read leaves both
files untouched. The first line of a file written from the swarm's list is a
`# source: swarm` comment. The queue grant a hive needs to read the list
comes with the controller's `swarm-nats-auth`; a hive that can't read it
times out, keeps its files and warns after about 90 seconds.
- **Unlisted names.** For a user who isn't on the unrestricted list, refused
after the destination checks, which look the name up on the host.
- **Denied before any allow.** Destinations that resolve to loopback,

View file

@ -112,7 +112,7 @@ with no icon keeps the hyperhive mark.
The tab also has an agent badge, with the agent's icon and name, ahead of the
connection badge. It opens the agent's details in a popover under the badge:
the same status, state, wanted state, inference settings, resource caps, permissions and linked accounts as the
the same status, state, wanted state, inference settings, resource caps, permissions, allowed domains and linked accounts as the
panel on `/agents`, without the terminal preview. The popover doesn't dim the
page. Selecting outside it, or Escape, closes it. From the keyboard, opening a
popover moves focus into it, and Escape puts focus back on the badge. The filter
@ -622,6 +622,38 @@ restarts the agent after its current turn. The panel reads
the reason and a **retry** button. `swarmctl agent permissions set` sets the
same grant from a shell.
### Allowed domains
The agent's detail panel lists the destinations it may reach through its
hive's egress proxy under **allowed domains**, beyond the base list every
agent has: the entries for every agent in the swarm (badge **swarm-wide**) and
the ones for this agent alone (badge with the agent's name). An entry matters
to a restricted agent. One with the unrestricted internet flag reaches any
name the proxy's private-range rules leave. **remove** drops one entry;
**add** opens a dialog with a domain box and a tick for every agent in the
swarm. The tick is off by default, so an entry is for this agent alone.
A domain is a DNS name of at least two labels, such as `github.com`. One
leading dot, as in `.githubusercontent.com`, also allows every subdomain; the
dot form is the only wildcard, because exact names can't list a service that
spreads over many hostnames, and an entry is the operator's choice. The
controller refuses IP addresses, other wildcards, ports and paths, and a name
the proxy already allows every agent (the base list). The dialog shows the
refusal's reason under the box and leaves what you typed. Adding does a
`POST /api/egress/allowed-domains` and removing a `DELETE` of the same path,
each with `{"domain": "github.com", "agent": "atlas"}` (leave out `agent` for
a swarm-wide entry); both answer the whole list, and `GET` reads it. Adding
an entry that exists changes nothing.
A saved change isn't instant. Each hive reads the list about every 30
seconds and reloads its proxy, so the name is reachable within a minute. The
proxy's private-range rules still apply: an entry whose name resolves to a
loopback, private or bridge address stays blocked. The first entry makes the
swarm's list replace the names a hive's own `allowedDomains` lists, so add
those names here too; a hive keeps its own list until then. See [the egress
proxy](../networking/network.md#egress-proxy-squid) for what each hive does
when the controller is old or unreachable.
### Creating an agent
The **+ agent** button opens a dialog of five steps, which you go through in