NetBird → Tailscale Enterprise
NetBird ↔ Tailscale Enterprise: integration to migration path.
Your mesh is load-bearing — break it and every peer loses every route at once. So we never flip a switch. NetBird stands up behind your Tailscale Enterprise tailnet first, new peers and net-new sites land on NetBird, and only then does the existing fleet migrate cohort by cohort against a parallel mesh. No forced re-enrolment, no cutover day, and every cohort rolls back in minutes.
Both products run the same WireGuard suite, so this is a control-plane swap with a stable data plane — the honest exceptions are the Tailscale-only features (Funnel, Serve, tailnet lock, managed DERP) we call out below before you commit.
The idea
Share the identity. Swap the control plane.
The trick that makes this zero-downtime: the same upstream IdP — Keycloak or Okta — issues OIDC tokens to both clients, so one user identity drives both meshes and the group claim drives both Tailscale ACL groups and NetBird peer groups. The two stacks run as separate WireGuard interfaces with non-overlapping AllowedIPs, so no kernel route conflict exists. New peers enrol straight into NetBird while the tailnet keeps carrying everything else; then the existing fleet moves a cohort at a time using more-specific prefixes as the routing wedge — each cohort independent, each reversible. You are never betting the whole network on one big cutover.
The phases
Six steps. Each one reversible.
Baseline & inventory
We document every Tailscale node by role: its tags, ACL group membership, advertised routes, exit-node duty, Funnel/Serve usage, tailnet-lock signers and tailscaled version. Read-only — we touch nothing.
NetBird goes live behind the tailnet
NetBird Management, Signal and TURN stand up in HA against the same IdP Tailscale already uses, so one user identity drives both meshes. A canary cohort of ten runs both clients on disjoint test CIDRs. No production route is advertised on NetBird yet.
New peers land on NetBird
Every net-new site, laptop and ephemeral CI runner enrols into NetBird via Setup Keys, with its peer group driven by the IdP group claim. Existing tailnet peers are untouched; NetBird advertises disjoint or more-specific prefixes so no kernel route fights.
Existing peers migrate, cohort by cohort
We translate the Tailscale ACL slice into NetBird policy, gate it on a synthetic packet-matrix equivalence test, then advertise the cohort's CIDRs from a NetBird routing peer as a more-specific prefix alongside the existing tailnet route. The kernel prefers the more-specific path; we watch SIEM for stragglers before draining the old route.
Cut the tailnet to Funnel/Serve only
All east-west traffic is now on NetBird. The tailnet shrinks to Funnel/Serve nodes and a small admin jump cohort — or, if full retirement is the target, Funnel ingress is replaced (Cloudflare Tunnel + Access, API Gateway, or nginx + Let's Encrypt) and the tailnet drops to zero active nodes.
Retire the Tailscale tenant
We disable SCIM provisioning into Tailscale, revoke the remaining auth keys, and hold the tenant read-only for a 30-day evidence window before requesting deletion at the contract renewal boundary. Tailnet-lock signers are the last out.
Feature parity
Where NetBird matches Tailscale — and where it can't.
| Capability | NetBird | Tailscale Enterprise | Parity |
|---|---|---|---|
| Tunnel/transport | WireGuard peers/AllowedIPs (ChaCha20-Poly1305 + Curve25519) | WireGuard peers/AllowedIPs (same suite) | At parity |
| Identity federation | OIDC client (Keycloak/Okta/Authentik/Entra), group claim drives peer group | SSO (OIDC/SAML) + SCIM 2.0 group sync (Enterprise SKU) | Partial |
| ACL policy model | JSON peer → group → policy → rule via Management API | HuJSON ACL (groups, acls, tagOwners, autoApprovers, ssh) | At parity |
| NAT traversal / relay | Self-hosted Coturn (STUN/3478 + TLS/5349) + NetBird Relay + Signal hole-punch | Tailscale-operated DERP-as-STUN hole-punch | At parity |
| Global edge / PoP | Self-provisioned regional Coturn — geography is yours to build | Managed DERP fleet (~30 PoPs, global) | SaaS only |
| DNS | NetBird DNS, per-group/per-peer A records under a custom suffix | MagicDNS *.ts.net synthetic zone + custom DNS | At parity |
| Network routes | Routing peers advertise CIDRs, group-scoped consumption | Subnet routers + exit nodes | At parity |
| Control-plane integrity | Setup Key + IdP JWT node enrolment | Tailnet lock (offline-signer node-key signing, detects key insertion) | SaaS only |
| Public ingress | None | Funnel (public ingress) + Serve (HTTPS at peer) | SaaS only |
| Session recording | None native | Tailscale SSH session recording (Enterprise) | SaaS only |
| RBAC / admin | Self-hosted Management console + API | Tailscale admin console + API | At parity |
| Deployment & HA | Self-hosted Helm/Compose, two-plus Management nodes + shared Postgres, your on-call | Vendor-operated control plane + 24/7 NOC | SaaS only |
| Cost model | Self-hosted compute + ops (Apache-2.0, no per-seat) | Per-user-per-month seat licence + Enterprise tier | Partial |
| Compliance | Boundary inside your SSP (patching, key custody, IR) | Inherited vendor SOC 2 / ISO boundary | SaaS only |
What we're honest about
The caveats most vendors leave out.
Funnel and Serve have no NetBird equivalent
Tailscale Funnel (public ingress) and Serve (HTTPS terminating at a tailnet node) have no NetBird parity in 2026. We inventory every use in Phase 0 and replace it before Phase 4 — Cloudflare Tunnel + Access or nginx + Let's Encrypt for ingress, Caddy or nginx with Let's Encrypt for Serve. If a Funnel case is irreplaceable, we keep a small Funnel-only tailnet permanently rather than pretend it migrated.
Tailnet lock has no like-for-like replacement
Tailscale tailnet lock signs node keys with offline signers, so a control-plane compromise that inserts a rogue key is detectable. NetBird's Setup Key plus IdP JWT model does not give you that — it is a genuinely different threat model. If detecting control-plane key insertion is in scope, we say so explicitly and may keep sensitive nodes on a locked tailnet permanently.
Managed DERP becomes self-hosted Coturn
Tailscale operates a global DERP fleet of roughly thirty PoPs you never page on. On NetBird you run Coturn and Signal yourself, and for a roaming or CGNAT-heavy fleet you must provision relays in several regions to match that reach. This is the single most under-estimated cost of self-hosting — we budget the relay geography in Phase 0, not after a reachability complaint.
You own uptime and the compliance boundary
Once Tailscale is gone there is no vendor 24/7 NOC and no inherited SOC 2 / FedRAMP boundary — NetBird Management being down means no new enrolment or policy refresh (existing tunnels survive). We run it HA: two-plus Management nodes, multi-AZ Postgres, monitored TURN, paged on-call, a break-glass path and a tested DR restore. Managed, not just installed.
Why this beats a flag day
Reversible per cohort. Soaked before cancellation.
Every cohort cutover in Phase 3 rolls back in under 15 minutes — we re-advertise the Tailscale subnet route while the HuJSON entries are still live, so reversal is a route flip, not a rebuild. And the Tailscale tenant is never cancelled on faith: it sits read-only for a 30-day evidence window — well past the minimum 30-day soak we require before the contract is torn up — so if anything regresses you reactivate inside the window instead of negotiating a fresh Enterprise contract.
See whether your mesh migrates cleanly.
A 30-minute call with a senior network engineer. We inventory your tailnet by node role, flag the Funnel, Serve and tailnet-lock dependencies that need a replacement plan, and tell you honestly where NetBird wins on cost and where Tailscale's managed edge still earns its seat — before you commit.
Map my migration →