NetBird Zero-Trust Networking: Policy-Driven Access Control for Self-Hosters
Traditional network security draws a perimeter around your infrastructure and trusts everything inside it. Once a device connects to the VPN, it can reach every service, every port, every machine. This model breaks down the moment a single device is compromised -- an attacker with access to one developer laptop can pivot to databases, admin panels, and production servers.
Zero-trust networking flips this model: no device is trusted by default, every connection requires explicit authorization, and access is granted based on identity, device posture, and policy -- not network location.
NetBird implements zero-trust network access (ZTNA) on top of WireGuard, giving you policy-driven access control for your entire self-hosted infrastructure. This article focuses specifically on designing and implementing zero-trust policies with NetBird -- the access control engine, group segmentation strategies, posture checks, and SSO-driven identity verification that make zero-trust practical for homelabs and small organizations.

Zero-Trust Principles Applied to Self-Hosting
Before configuring anything, it helps to understand the core zero-trust principles and how they map to a self-hosted environment:
1. Verify explicitly
Every connection request is authenticated and authorized. When a developer's laptop tries to reach a production server, NetBird checks: Who is this user? What groups do they belong to? Is there a policy that permits this specific connection?
2. Least-privilege access
Devices only get access to the specific resources they need. Your monitoring server can scrape metrics from application servers on port 9090, but it cannot SSH into them. Your CI/CD runner can deploy to staging, but it cannot reach the production database.
3. Assume breach
Design your network as if any device could be compromised at any time. Segment aggressively so that a compromised device's blast radius is limited to the resources it was authorized to access.
4. Continuous verification
Access decisions aren't one-time events. NetBird continuously evaluates peer connectivity and can enforce posture checks -- device-level requirements that must be met before access is granted.
Designing Your Access Control Model
The power of NetBird's zero-trust model comes from three building blocks: groups, policies, and posture checks. Getting these right is the difference between actual zero-trust and "we installed a VPN and called it zero-trust."
Group Architecture
Groups are the foundation of your access control model. Resist the urge to create a flat list of groups -- instead, design a hierarchy that reflects how access flows in your organization.
By role:
developers-- engineering team machinesadmins-- infrastructure administratorscontractors-- temporary access, time-limited
By environment:
production-- production servers and databasesstaging-- staging environmentdevelopment-- dev/test infrastructure
By function:
monitoring-- Prometheus, Grafana, alertingdatabases-- PostgreSQL, Redis, MongoDB instancesweb-servers-- public-facing application serversci-cd-- build runners and deployment agents
By location or trust level:
office-network-- devices on the corporate networkremote-- work-from-home devicesmobile-- phones and tablets
A well-designed group architecture lets you express complex policies with simple rules. "Developers can access staging but not production" becomes a two-line policy rather than a per-device configuration.
Policy Design Patterns
NetBird policies define which groups can communicate, on which ports, using which protocols. Here are proven patterns for self-hosted environments:
Pattern 1: Environment isolation
Prevent staging and production from talking to each other. This is the single most important policy for any organization running multiple environments.
| Source | Destination | Ports | Action |
|---|---|---|---|
| staging | staging | All | Allow |
| production | production | All | Allow |
| staging | production | Any | Deny |
| production | staging | Any | Deny |
Pattern 2: Role-based service access
Map job functions to service access. A developer needs SSH and application ports. A database administrator needs database ports. Neither needs the other's access.
| Source | Destination | Ports | Action |
|---|---|---|---|
| developers | web-servers | TCP 22, 80, 443, 3000, 8080 | Allow |
| developers | databases | TCP 5432, 6379 | Deny |
| db-admins | databases | TCP 5432, 6379, 27017 | Allow |
| db-admins | web-servers | Any | Deny |
Pattern 3: Monitoring exemption
Monitoring infrastructure needs broad read access but no write access. NetBird's port-level policies make this clean.
| Source | Destination | Ports | Action |
|---|---|---|---|
| monitoring | production | TCP 9090, 9100, 9113 | Allow |
| monitoring | databases | TCP 9187 | Allow |
| monitoring | web-servers | TCP 9117 | Allow |
| monitoring | Any | TCP 22 | Deny |
Pattern 4: CI/CD deployment paths
Build runners need deployment access to specific targets, nothing more.
| Source | Destination | Ports | Action |
|---|---|---|---|
| ci-cd | staging | TCP 22, 443 | Allow |
| ci-cd | production | TCP 22, 443 | Allow (with approval) |
| ci-cd | databases | Any | Deny |
Implementing Policies via the Dashboard
In the NetBird dashboard, navigate to Access Control > Policies and create policies using the group-based rules above.
Each policy requires:
- Name -- descriptive name (e.g., "Developers to Staging SSH")
- Source groups -- which groups initiate the connection
- Destination groups -- which groups receive the connection
- Ports and protocols -- TCP/UDP port ranges
- Action -- Allow or Deny
- Bidirectional -- whether the policy applies in both directions
# You can also manage policies via the NetBird API
curl -X POST https://netbird.yourdomain.com/api/policies \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Developers to Staging",
"description": "Allow developer machines to access staging servers",
"enabled": true,
"rules": [
{
"name": "SSH and HTTP access",
"enabled": true,
"sources": ["developers-group-id"],
"destinations": ["staging-group-id"],
"bidirectional": false,
"protocol": "tcp",
"ports": ["22", "80", "443", "3000", "8080"],
"action": "accept"
}
]
}'
Posture Checks: Device-Level Trust
Policies answer "Can this group access that group?" Posture checks answer "Is this specific device trustworthy enough to use the access it's been granted?"
NetBird supports several posture check types:
Operating system version
Require peers to run a minimum OS version. This prevents outdated, unpatched devices from accessing your network.
{
"name": "Minimum OS Version",
"checks": {
"nb_os_version": {
"linux": {
"min_kernel_version": "5.15.0"
},
"darwin": {
"min_version": "14.0"
},
"windows": {
"min_kernel_version": "10.0.22000"
}
}
}
}
NetBird client version
Ensure all peers run a recent NetBird client. Older clients may lack security fixes.
{
"name": "Minimum Client Version",
"checks": {
"nb_version": {
"min_version": "0.28.0"
}
}
}
Geo-location restrictions
Restrict access based on the geographic location of the peer's IP address. If your team is entirely US-based, block connections from unexpected countries.
{
"name": "US Only Access",
"checks": {
"geo_location": {
"locations": [
{
"country_code": "US",
"action": "allow"
}
],
"action": "deny"
}
}
}
Peer network range
Only allow peers connecting from specific network ranges -- useful for ensuring devices are on trusted networks.
{
"name": "Office Network Only",
"checks": {
"peer_network_range": {
"ranges": ["203.0.113.0/24", "198.51.100.0/24"],
"action": "allow"
}
}
}
Posture checks are assigned to policies. A policy can require multiple posture checks -- for example, "Developers can access production only if they're running a patched OS, a current NetBird client, and connecting from the US."
Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.
SSO Integration for Identity-Driven Access
Zero-trust networking depends on strong identity. NetBird integrates with any OIDC-compatible identity provider, which means your VPN access is tied to the same identities that control your other systems.
Supported identity providers
- Authentik -- self-hosted, full-featured
- Keycloak -- self-hosted, enterprise-grade
- Zitadel -- cloud-native, self-hostable
- Auth0 -- managed service
- Google Workspace -- for Google-based organizations
- Azure AD / Entra ID -- for Microsoft-based organizations
- Okta -- enterprise SSO
Configuration example with Authentik
If you're already running Authentik (a popular self-hosted identity provider), connecting it to NetBird takes a few steps:
- In Authentik, create an OAuth2/OpenID Provider for NetBird
- Set the redirect URI to
https://netbird.yourdomain.com/auth/callback - Note the client ID, client secret, and issuer URL
- Configure NetBird's management server:
{
"HttpConfig": {
"AuthAudience": "your-netbird-client-id",
"AuthIssuer": "https://authentik.yourdomain.com/application/o/netbird/",
"OIDCConfigEndpoint": "https://authentik.yourdomain.com/application/o/netbird/.well-known/openid-configuration"
}
}
Identity-based group assignment
With SSO connected, you can automatically assign peers to groups based on their identity provider attributes:
- Users in the
engineeringgroup in Authentik automatically join thedevelopersgroup in NetBird - Users in the
opsgroup automatically join theadminsgroup - Contractors with a specific attribute get added to a time-limited
contractorsgroup
This eliminates manual group management. When someone joins the engineering team in your identity provider, they automatically get the right network access. When they leave, their access is revoked immediately.
NetBird vs. Tailscale vs. Headscale: Zero-Trust Capabilities
All three tools provide WireGuard-based mesh networking, but their zero-trust capabilities differ significantly.
| Zero-Trust Feature | NetBird | Tailscale | Headscale |
|---|---|---|---|
| Group-based policies | Built-in, granular | ACLs (JSON/HuJSON) | ACLs (same as Tailscale) |
| Port-level access control | Yes | Yes | Yes |
| Posture checks | OS version, geo, network | Device approval only | Limited |
| SSO/OIDC integration | Native, any provider | Google, Microsoft, GitHub, OIDC | OIDC |
| Self-hosted policy engine | Yes | No (SaaS only) | Yes |
| Policy API | REST API | Tailnet API | Limited |
| Network segmentation | Groups + policies | Tags + ACLs | Tags + ACLs |
| Automatic group sync from IDP | Yes | Limited | No |
| Geo-based restrictions | Yes | No | No |
| Custom posture checks | Extensible | No | No |
| Web UI for policy management | Yes | Yes (SaaS) | Third-party |
When NetBird's zero-trust model wins
NetBird's advantage is in the granularity and self-hosted nature of its policy engine. If you need:
- Posture checks that go beyond simple device approval (OS version, geo-location, network range)
- IDP-synced groups that automatically update network access when team membership changes
- A self-hosted policy engine where your access control rules never leave your infrastructure
- API-driven policy management for infrastructure-as-code approaches
NetBird is the strongest option.
When Tailscale ACLs are sufficient
Tailscale's ACL system is powerful and well-documented. For many organizations, defining ACLs in a JSON file and pushing them via the Tailnet API is entirely adequate. Tailscale's advantage is simplicity -- there's no policy engine to self-host, and the ACL syntax is battle-tested.
If you're using Tailscale's hosted service and don't need geo-restrictions or OS-version posture checks, Tailscale's ACLs may be all you need.
Headscale's limitations
Headscale implements Tailscale's ACL system on a self-hosted coordination server. It works well for basic access control, but it lacks the richer posture check and group-sync features that NetBird offers. Headscale is best viewed as "self-hosted Tailscale" rather than a zero-trust platform.
Advanced Network Design with NetBird
Network routes for legacy infrastructure
Not every device can run a NetBird agent. For legacy hardware, IoT devices, or network segments that need to be accessible, NetBird's network routes feature turns a peer into a gateway.
NetBird Peer (gateway) ──── 192.168.10.0/24 (IoT VLAN)
└── 10.0.50.0/24 (legacy servers)
Create a network route in the dashboard:
- Go to Network > Routes
- Add route:
192.168.10.0/24viagateway-peer - Assign the route to groups that need access (e.g.,
admins) - Other groups cannot reach this network at all
This extends zero-trust to networks that can't run agents -- the gateway peer enforces the access policy.
DNS-based service discovery
NetBird's DNS management lets you create a service discovery layer across your zero-trust network:
db-primary.netbird.internalresolves to your primary databasegrafana.netbird.internalresolves to your monitoring dashboard*.staging.netbird.internalresolves to staging services
Combined with access policies, DNS becomes an access layer: even if a device knows the DNS name of a production database, the connection is blocked unless a policy permits it.
Exit nodes for internet traffic
You can designate NetBird peers as exit nodes, routing all internet traffic from specific groups through a controlled egress point. This is useful for:
- Routing contractor traffic through your network for audit logging
- Ensuring all DNS queries from remote devices go through your filtered DNS
- Providing a consistent source IP for services that whitelist by IP address
Auditing and Compliance
Zero-trust isn't just about access control -- it's about proving that access control works.
Activity logs
NetBird logs all peer connections, policy evaluations, and group membership changes. Access these through the dashboard under Activity or via the API:
curl -X GET https://netbird.yourdomain.com/api/events \
-H "Authorization: Token YOUR_API_TOKEN" \
-H "Content-Type: application/json"
Policy review workflow
For regulated environments, establish a policy review cadence:
- Export current policies via the API monthly
- Compare against your access control matrix
- Review group memberships against your identity provider
- Audit posture check compliance rates
- Document exceptions and their justifications
Integrating with external SIEM
Forward NetBird's activity logs to your SIEM (Grafana Loki, Elasticsearch, Splunk) for centralized security monitoring. The management server outputs structured logs that can be parsed by standard log collectors:
# docker-compose.yml addition for log forwarding
services:
management:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
# Or use fluentd/fluentbit for real-time forwarding
Honest Assessment
NetBird's zero-trust model excels when you:
- Run a multi-environment infrastructure (dev/staging/production) that needs strict segmentation
- Want access policies tied to identity provider group membership
- Need posture checks beyond simple device approval
- Require audit trails for compliance
- Want to manage everything via API for infrastructure-as-code
The model adds complexity when:
- You have fewer than 10 devices and a flat network topology
- Everyone on the network should access everything (a small homelab with one user)
- You don't have an identity provider set up yet (NetBird requires OIDC)
The bottom line: Zero-trust networking is not just a buzzword -- it's a concrete set of access control patterns that NetBird implements well. For self-hosters who've grown past "everything talks to everything" and need real network segmentation tied to identity, NetBird's policy engine is one of the best self-hosted options available. The investment in designing proper groups and policies pays off the first time you need to revoke a contractor's access or isolate a compromised device.
