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 — 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 — 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 — that's 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.