← All writing
Platform engineeringNetworkingProduct designOperations

Access is a product, not a firewall rule

Why the right private-access decision can be to stop maintaining the mechanism and start designing the experience.

It is easy to call private access an infrastructure detail.

Give each device a tunnel, assign an address, add a firewall rule, and record the result in a runbook. The packet path may be correct. That does not mean the experience is coherent.

The distinction became clear when the home compute model changed. A Proxmox host is a management boundary. Plex, DNS filtering, and other services inside guests are the resources people actually want to use. Treating the host’s VPN identity as the service-access model would have kept the network tidy by making the user experience obscure.

That is usually a sign that the wrong thing has become the product.

A service is not a peer

The former design used a custom WireGuard hub. It bound a device key to an overlay address, then used gateway policy to decide what that address could reach. It was deliberately narrow, replaceable, and well suited to a small host-based topology.

But a management host is not a useful destination in its own right. Adding host DNAT, proxy rules, or one more kind of peer would have preserved the mechanism while moving the real model further from the thing it needed to express.

A person does not need permission to reach 10.x.y.z. They need permission to use Plex, an operator dashboard, a game server, or an internet exit node.

That is a resource and capability model. It deserves an access product that understands devices, groups, resources, ports, policies, and a client experience—not a growing set of special cases around a packet filter.

Keep the products separate

The revised platform uses NetBird for private access. Its job is to enrol a device, connect it, and grant the smallest useful network capability. An approved user should install one client, sign in once, and then use the resource they were granted. They should not receive a WireGuard profile, scan a QR code, learn an address range, or know which hypervisor currently runs a service.

The platform console has a different job. It knows whether a task is healthy, which Proxmox host has a valid allocation, whether a drain is safe, and whether an exclusive writer has been fenced. It can show an operator that a service is unavailable or link to an access record. It should not become another device enrolment portal or a second network-policy editor.

Those boundaries make the user experience easier to describe:

  • Public applications remain on their deliberately public paths.
  • Private users get an access client and named capabilities.
  • Operators use the console for service and capacity operations.
  • NetBird owns device and network access; the console owns platform state.

One identity source joins the two products. It prevents two user directories, two group models, and two recovery stories from quietly becoming the price of one private service.

Managed does not mean unowned

The same reasoning changes the cloud substrate. GKE Autopilot takes over node and control-plane operation because those layers are not where this platform needs a bespoke implementation. That does not remove platform work. It moves the attention to the parts that remain consequential:

  • workload identity and secret boundaries;
  • GitOps delivery and policy review;
  • public and private service surfaces;
  • cost ceilings and capacity requests;
  • backup, restore, and failure evidence; and
  • the handoff between cloud control and home execution.

NetBird’s controller remains independently recoverable on EC2 because private access should not depend on the workload cluster being healthy. Its stable DNS, public UDP edge, configuration, and backed-up state are an explicit small service boundary. It is not the return of a bespoke gateway appliance.

This is not less engineering. It is less undifferentiated engineering.

A boundary can be correct and still be temporary

Separating the old gateway appliance from its Terraform envelope was the right decision for that appliance. Keeping it as the platform changed would not prove consistency; it would turn an old boundary into a constraint on the next product.

The better test is whether a component still earns the complexity it asks its operators and users to carry.

In this case, a managed Kubernetes substrate removes commodity recovery work. A dedicated access product removes custom client and policy work. The platform keeps the decisions that require its own context: what should run, where it can run safely, what state needs protection, and what a user is actually allowed to do.

That is the point of an architecture decision record. Not to prove that the first diagram was right, but to make the next correction legible.

These decisions are accepted architecture, not deployment evidence. The remaining work is to prove the GKE, identity, NetBird recovery, and migration gates before calling the new path operational.