Security model
What's encrypted, what's public, what the edge can see, and the knobs that bound exposure.
Beamd's job is to put a local app on the public internet, so it's worth being precise about what that does and doesn't protect.
TLS everywhere
The edge terminates real TLS at :443 with Let's Encrypt certificates (no
self-signed warnings in production). The client's connection to the edge is a
single outbound TLS connection. Nothing is exposed or port-forwarded on your
side, and the bearer token only ever rides a verified connection.
Tunnel URLs are public
A tunnel URL is reachable by anyone who has the link. Beamd does not put a login in front of your app, so treat a tunnel like any public URL:
- Don't expose anything you wouldn't want a stranger to load.
- Names are single labels on a wildcard domain, so a guessable name
(
api,web) is, well, guessable. Use less obvious names for sensitive work, andbeamd closewhen you're done. - If your app has its own auth, it still applies. Beamd just forwards requests.
For self-hosters, namespacing developers under a slug
(*.<slug>.<base>) keeps one developer's names from colliding with another's,
but it doesn't make URLs private.
Separate domains (hosted)
The hosted service deliberately runs tunnels on a different registrable domain than the dashboard. Two reasons:
- A tunneled app is never same-site with the dashboard, so a malicious app behind a tunnel can't reach dashboard cookies or sessions.
- Free-tier and paid tunnels live on separate domains, so abuse on one can't damage the reputation of the other.
The edge holds no user data. It validates a token by asking the control plane and caches the answer for about a minute.
Limits that bound exposure
The edge enforces a few caps (configurable when you self-host, see the Configuration reference):
| Limit | Default | Effect |
|---|---|---|
max_request_body_bytes | 32 MiB | Oversized requests get HTTP 413 (-1 disables) |
max_tunnels_per_token | 25 | Cap on concurrent tunnels per credential |
Embedding previews (preview_embed)
By default Beamd preserves your app's framing policy. Set preview_embed: true
on the edge to strip X-Frame-Options and CSP frame-ancestors from tunnel
responses so a preview can be embedded cross-origin in an iframe. It's off by
default, so turn it on only when you intend for previews to be framed.
What the edge can see
The edge proxies your traffic, so it can see request/response bytes in transit (it's terminating TLS, which is how any reverse proxy works). When you self-host, that edge is your server: there's no third party in your data path. On the hosted service, the same trust applies as any hosting provider.