Services
A Service is an admin-registered, named local endpoint that Share tunnels are permitted to expose. Services are the outer fence around what a developer can put behind a tunnel: a Share request whose target does not resolve to a registered Service is rejected, regardless of which Share Policy the developer satisfies.
The Services tab lives at Share → Services in the admin dashboard.
What a Service Looks Like
Section titled “What a Service Looks Like”Each Service has two fields:
| Field | Description |
|---|---|
| Name | Human-readable label, e.g. Dev API, Staging Database |
| Backend Target | Internal endpoint the tunnel may forward to, e.g. https://dev-api.internal:8080 |
Name: Dev APIBackend Target: https://dev-api.internal:8080How Services Interact With Share Policies
Section titled “How Services Interact With Share Policies”The Service Registry and Share Policies enforce different concerns:
| Mechanism | Question it answers |
|---|---|
| Service Registry | Is this local target eligible to be tunneled at all? |
| Share Policy | Is this user allowed to create the tunnel, and is this request allowed through it? |
A Share Rule can pin to a specific Service — when set, that rule grants access to that one non-loopback Service and no other. A Share Rule with no Service set grants loopback targets only — there is no “any registered Service” wildcard, so a role that needs access to multiple non-loopback Services needs one Share Rule per Service. See Share Policies for the full rule model.
Loopback Targets
Section titled “Loopback Targets”Loopback targets (127.0.0.0/8, ::1, 0.0.0.0) are always permitted without a Service Registry lookup. This is the standard local-dev case — broch share my-app --target http://localhost:3000 does not require a registered Service.
Non-loopback targets must match a registered Service.
Resolution at Tunnel Creation
Section titled “Resolution at Tunnel Creation”Targets are matched by resolved IP and port, not by hostname. The authoritative resolver is the broch server’s, not the CLI client’s — a developer’s local /etc/hosts cannot influence the policy decision, only what the server itself sees.
When a developer runs broch share --target ...:
- The target hostname is resolved to an IP address (or set of addresses) by the broch server’s resolver.
- If every resolved address is loopback, the tunnel is allowed and the Service Registry is skipped. The four literal strings
localhost,127.0.0.1,[::1], and0.0.0.0are treated as loopback without a DNS lookup. Mixed sets (e.g. a hostname that resolves to both a loopback and a public address) are NOT treated as loopback — the broch server might pick the public address at connect time, so this case falls through to the Service Registry as a guard against DNS rebinding. - Otherwise, broch attempts a literal
host:portmatch against every Service’s Backend Target. If that fails, the resolved target IPs are compared against each Service’s resolved Backend Target IPs at the same port. If neither match succeeds, the tunnel is rejected.
This means a Service registered as dev-api.internal:8080 permits any target that resolves to the same IP and port on the server — including private aliases or entries in the broch server’s /etc/hosts.