Attach a cluster to your own tailnet
Bridge a Longbridge cluster into a Tailscale tailnet you already operate — your coordination plane, your ACLs — with a managed connector. Covers the copy-paste ACL stanza, both authentication modes, and reaching services by name.
A Mesh network is a tailnet Longbridge runs the coordination plane for. But if you already run your own Tailscale tailnet (or a self-hosted Headscale), you can bridge a cluster straight into it instead — same managed connector, but it joins your network under your ACLs. Your existing machines reach the cluster’s pods and services with nothing new to install.
The trade is ownership: because it’s your tailnet, you own the two policy decisions Longbridge otherwise makes for you — which tag the connector carries, and whether its advertised routes are approved. Both live in your tailnet’s ACL, and this guide gives you the stanza to paste.
You’ll need: a cluster with at least one node, Console access (or the Terraform provider), and admin on a Tailscale tailnet. A QEMU VM makes a fine throwaway node.
1. Choose a tag
The connector joins your tailnet as a tagged node — never a user’s device. Pick a tag
you’ll recognize, for example tag:corp. It’s yours, in your namespace; the only tags
Longbridge refuses are its own reserved tag:lb-*.
2. Add the ACL stanza
Paste this into your tailnet’s ACL (Tailscale admin console → Access controls), adjusting the tag and the CIDRs to match. It does two things: lets you own the tag, and auto-approves the routes the connector advertises so you don’t hand-approve them every time the connector restarts.
{
"tagOwners": {
"tag:corp": ["autogroup:admin"]
},
"autoApprovers": {
"routes": {
"10.244.0.0/16": ["tag:corp"],
"10.96.0.0/16": ["tag:corp"]
}
}
}
tagOwnerslets an admin mint credentials that stamptag:corpon a device — the connector is one such device.autoApprovers.routessays a device taggedtag:corpmay advertise those CIDRs and have them approved automatically. They are the cluster’s pod and service ranges (10.244.0.0/16and10.96.0.0/16by default; a carved cluster uses the ranges you chose). Without this the attachment staysAwaiting approvaluntil you approve the routes by hand.
3. Create a credential
Longbridge joins the connector with a credential you supply. Two modes — pick one:
- Auth key — the simplest. In the Tailscale admin console, mint a reusable,
pre-approved, tagged auth key (tag
tag:corp). Longbridge uses it verbatim. Works with a self-hosted Headscale too. - OAuth client — the tidiest for the long run. Create an OAuth client with the
auth_keysscope and the tagtag:corp. Longbridge mints a fresh, ephemeral key per connector from it, so there’s no long-lived shared secret in the cluster. OAuth is a Tailscale-managed-tailnet feature; a self-hosted Headscale uses an auth key.
Your credential is sent to the shard and stored there as a Kubernetes Secret in the cluster’s management namespace. It is never persisted by the Console.
4. Attach
In the Console, open the cluster’s Networking tab and choose Attach external
network. Pick your authentication mode, paste the credential, and enter the tag
(tag:corp) and — for a self-hosted Headscale — its login server. Leave the routes at
Pods + services unless you want to expose less.
Prefer code? The Terraform resource does the same:
resource "longbridge_control_plane_external_attachment" "corp" {
cluster = "test"
auth_mode = "oauth"
tag = "tag:corp"
# login_server defaults to Tailscale's own; set it for a self-hosted Headscale.
client_id = var.tailscale_client_id
client_secret = var.tailscale_client_secret
# or, for auth_mode = "authKey":
# auth_key = var.tailscale_auth_key
}
The credential attributes are write-only — Terraform sends them on create and never reads them back, so they won’t show up in a later plan.
5. Check it’s serving
The attachment reports two things it can actually observe:
connectorReady— the connector is up in the cluster.routesApproved— the connector’s owntailscale statusshows your tailnet has approved the advertised routes. If you added the auto-approver in step 2 this flips to Serving on its own; if it’s stuck on Awaiting approval, your ACL auto-approver isn’t matching the tag or the CIDRs.
Once it’s Serving, any machine on your tailnet reaches the cluster by ClusterIP:
curl http://10.96.0.10 # e.g. a Service's ClusterIP
Reach services by name (optional)
Routing works by IP out of the box. To resolve cluster names, point a Tailscale
split-DNS nameserver at the cluster’s in-cluster DNS: in Access controls → DNS,
add a nameserver for the cluster.local domain pointing at kube-dns’s ClusterIP
(usually the .10 of the service range, 10.96.0.10). Because the connector advertises
the whole service range, that address is reachable, so your machines resolve
my-svc.my-ns.svc.cluster.local and connect. (The per-cluster *.cluster.internal
rewrite that managed networks offer is Longbridge-side and doesn’t apply here.)
Detach
Detach from the cluster’s Networking tab, or terraform destroy the resource. The
connector leaves the cluster and its machine deregisters from your tailnet; the cluster
keeps running untouched. Re-attach any time.