Skip to content

Sharing Local Services

broch share creates a public HTTPS tunnel to a service running on your local machine. The tunnel stays open as long as the CLI process is running.

Share is deny-by-default: an admin at your organization decides who can create tunnels and what inbound traffic is allowed through them. For broch share to succeed, two things must line up:

  • A Share Policy applies to one of your IdP roles. Policies are bound to roles like engineering or contractors. If no policy applies to any of your roles, tunnel creation is denied.
  • Inbound requests match an allowed rule. Once your tunnel is up, each request is evaluated against the policy’s rules. An admin can require, for example, that requests originate from a specific network range, or carry a specific webhook signature header.

If broch share returns a permissions error, the most common causes are that your IdP role isn’t covered by any Share Policy, or that your access token doesn’t include the role claim the policy expects. Talk to your admin — they can see exactly which policies and roles are configured in the admin dashboard.

Any HTTP or HTTPS service that the Broch server resolves to a loopback address. That includes the four conventional loopback strings — localhost, 127.0.0.1, [::1], 0.0.0.0 — and any hostname whose DNS lookup on the server returns a loopback IP.

Terminal window
# Standard local dev server
broch share my-app --target http://localhost:3000
# Local HTTPS with a self-signed cert
broch share my-app --target https://localhost:8443
# Bound to IPv6 loopback
broch share my-app --target http://[::1]:3000

You can run multiple tunnels simultaneously — each gets its own public URL:

Terminal window
broch share frontend --target http://localhost:5173
broch share api --target http://localhost:8080

The hostname in --target becomes the Host header sent to your local app. Use the same hostname your app expects — for virtual hosting, mkcert-issued certs, or names mapped via the server-side /etc/hosts.

Any target that the broch server resolves to a non-loopback address (or doesn’t resolve at all) is admin-managed. This typically includes:

  • Other hosts on your network (e.g. 192.168.1.50:8080)
  • Internal hostnames that resolve to a non-loopback IP (e.g. staging.internal:8443)
  • Hostnames the broch server can’t resolve at all

Trying to share one of these without an admin-registered Service returns:

❌ Target '<host>:<port>' does not resolve to a loopback address and is not a registered Service.

To unblock yourself, ask your Broch admin to:

  1. Register the target as a Service — each Service maps a backend target (scheme://host:port) to a name in the admin dashboard. See Administration → Services for what a Service looks like and how the registry resolves matches.
  2. Add a Share Rule pointing at that Service to a Share Policy that covers your IdP role — without the rule, the policy denies access to that specific target even if you can otherwise create tunnels. See Administration → Share Policies for the rule model.

Once both are in place:

Terminal window
broch share staging --target http://staging.internal:8443

Tunnel URLs follow the format {name}-{tag}.tunnels.yourcompany.com, where the tag is a 6-letter code that keeps your session names unique. Set yours once with:

Terminal window
broch user tag abcdef

After that, broch share my-app always produces my-app-abcdef.tunnels.yourcompany.com.

While the tunnel is up, the CLI prints a dim one-line summary for every inbound request:

my-app ← GET → 200 / (5ms)
my-app ← POST → 201 /api/users (12ms)

This is on by default — no flag required.

Pass --inspect to additionally capture request/response bodies and serve a local inspector UI:

Terminal window
broch share my-app --target http://localhost:3000 --inspect

The inspector binds to 127.0.0.1 (default port 4040, falling through to 4041–4049 if busy) and prints its URL alongside the tunnel URL on startup. Open it in your browser to see the last 50 requests, expand details, and click Replay to fire any request again at your local target. Capture is memory-only — nothing is written to disk and nothing leaves your machine.

By default the proxy rewrites a few headers (Host, Referer, Location, Set-Cookie) so local apps work through the tunnel. To forward requests unmodified instead, pass --no-rewrite. For details on what the proxy rewrites, how to turn it off, and known limitations, see Proxy Behavior & Limitations.