The Core Principle#
Zero trust networking operates on a simple premise: no network location is inherently trusted. Being inside the corporate network, inside a VPC, or inside a Kubernetes cluster does not grant access to anything. Every request must be authenticated, authorized, and encrypted regardless of where it originates.
This is a departure from the traditional castle-and-moat model where a VPN places you “inside” the network and everything inside is implicitly trusted. That model fails because attackers who breach the perimeter have unrestricted lateral movement. Zero trust eliminates the concept of inside versus outside.
BeyondCorp: Where Zero Trust Started#
Google published BeyondCorp in 2014 after years of internal use. The model combines three factors for every access decision:
User identity: who is making the request, verified through strong authentication (SSO, MFA). Not just a username and password – the identity system must confirm the user is who they claim to be.
Device trust: what device is making the request, verified through device certificates, health checks (OS patches current, disk encryption enabled, EDR running). A valid user on an untrusted device is denied access.
Context: when and where is the request happening. Time-based policies (restrict access outside business hours), location-based policies (flag access from unusual geographies), and risk scoring (unusual patterns trigger step-up authentication).
The access decision happens at a centralized access proxy. Every request flows through the proxy, which evaluates all three factors against the access policy for the target resource. No VPN is involved. The application is never directly exposed – only the access proxy faces the internet.
WireGuard: The Foundation#
WireGuard is a modern VPN protocol built into the Linux kernel. It is fast (kernel-level packet processing), simple (around 4,000 lines of code vs OpenVPN’s 100,000+), and uses modern cryptography (Curve25519, ChaCha20, Poly1305, BLAKE2s).
Configuration is minimal. Each peer has a public/private key pair and a list of allowed IP ranges:
# /etc/wireguard/wg0.conf on Server
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.100.0.1/24
ListenPort = 51820
[Peer]
PublicKey = CLIENT_PUBLIC_KEY
AllowedIPs = 10.100.0.2/32
# /etc/wireguard/wg0.conf on Client
[Interface]
PrivateKey = CLIENT_PRIVATE_KEY
Address = 10.100.0.2/24
[Peer]
PublicKey = SERVER_PUBLIC_KEY
Endpoint = vpn.example.com:51820
AllowedIPs = 10.100.0.0/24, 10.0.0.0/16
PersistentKeepalive = 25# Bring up the tunnel
wg-quick up wg0
# Verify the connection
wg showWireGuard uses AllowedIPs for both routing and cryptographic enforcement. Packets from a peer are only accepted if the source IP matches the peer’s AllowedIPs. This is not just routing – it is a security boundary.
Use WireGuard directly when: you need a site-to-site tunnel between data centers, you want full control over the VPN configuration, you are building a custom mesh between a small number of known nodes.
Tailscale: Zero-Config Mesh Networking#
Tailscale builds on WireGuard to create a mesh VPN that requires no infrastructure. Every device connects to every other device directly (via NAT traversal using DERP relay servers as fallback). There is no central VPN server that all traffic flows through.
Key capabilities:
Zero configuration: install the agent, authenticate with SSO, and the device joins the network. No key exchange, no endpoint configuration, no port forwarding.
ACLs: define access policies in a JSON or HuJSON file that maps user groups to allowed destinations:
{
"acls": [
{
"action": "accept",
"src": ["group:platform-team"],
"dst": ["tag:k8s-node:*"]
},
{
"action": "accept",
"src": ["group:developers"],
"dst": ["tag:staging:80,443"]
}
],
"tagOwners": {
"tag:k8s-node": ["group:platform-team"],
"tag:staging": ["group:platform-team"]
}
}SSO integration: authenticate with your existing identity provider (Okta, Azure AD, Google, GitHub). User identity drives ACL decisions.
MagicDNS: every device gets a DNS name on the tailnet (myserver.tailnet-name.ts.net). No need to remember IP addresses.
Subnet routing: expose entire subnets through a Tailscale node. A single node in your VPC can advertise the VPC CIDR, giving tailnet access to all services without installing Tailscale on every machine.
Choose Tailscale when: you need to connect distributed infrastructure across clouds and on-premise, you want developer access to internal services without exposing public endpoints, you need a VPN that works through restrictive NATs and firewalls. Tailscale is free for personal use with up to 100 devices and reasonably priced for teams.
Boundary: Identity-Based Infrastructure Access#
HashiCorp Boundary provides identity-based access to infrastructure without a VPN. Instead of granting network-level access, Boundary creates authenticated, authorized, time-limited sessions to specific resources.
# Connect to a database through Boundary
boundary connect postgres -target-id ttcp_1234567890 -dbname myapp
# Connect via SSH
boundary connect ssh -target-id ttcp_0987654321 -username admin
# Connect with credential injection (user never sees the password)
boundary connect postgres -target-id ttcp_1234567890 -dbname myapp
# Boundary injects credentials from Vault automaticallyKey Boundary concepts:
Targets define what a user can connect to: a specific host and port, with an associated credential source. The user connects to the target by name, not by knowing the actual hostname or IP.
Credential injection: Boundary retrieves credentials from Vault and injects them into the session. The user never sees the database password, SSH key, or API token. When the session ends, the credentials can be revoked.
Session recording: every session through Boundary can be recorded for compliance and forensic purposes. SSH sessions, database queries, RDP sessions – all captured with full audit trail.
Choose Boundary when: you need fine-grained access control per resource (not network-level), you need credential injection so users never handle production passwords, you need session recording for compliance, you are already using Vault and want integrated credential management.
Kubernetes Zero Trust#
Inside a Kubernetes cluster, zero trust means encrypting all pod-to-pod communication, authenticating every service, and authorizing every request.
Service mesh mTLS: Istio and Linkerd automatically inject sidecar proxies that establish mutual TLS between all pods. Every connection is encrypted and both sides verify each other’s identity. No application code changes required.
# Istio PeerAuthentication: require mTLS for all pods in namespace
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
name: default
namespace: production
spec:
mtls:
mode: STRICTNetwork policies: restrict which pods can communicate. Default deny all traffic, then allow specific paths:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- EgressSPIFFE/SPIRE: the Secure Production Identity Framework for Everyone assigns cryptographic identities (X.509 certificates called SVIDs) to workloads. SPIRE is the runtime that issues and rotates these identities automatically. Each workload gets a SPIFFE ID like spiffe://cluster.local/ns/production/sa/frontend and a short-lived certificate that proves it. The certificates rotate automatically (typically every hour), so there is nothing to manage manually.
Implementation Layers#
Zero trust is not a single product. It is a set of controls applied at multiple layers:
Network layer: micro-segmentation prevents lateral movement. No flat networks. East-west traffic (service to service) is encrypted. Firewall rules are granular: allow specific source to specific destination on specific port.
Identity layer: strong authentication for all users and services. Multi-factor authentication is mandatory. SSO provides centralized authentication. Service identities use certificates or tokens, not shared passwords.
Device layer: device health checks before granting access. Certificate-based device identity ensures only managed devices connect. Endpoint detection and response (EDR) status factors into access decisions.
Application layer: context-aware access policies evaluate every request. Access is continuously verified – not just at connection time. Session duration is limited. Anomalous behavior triggers re-authentication.
Comparison: When to Use What#
| WireGuard | Tailscale | Traditional VPN | Boundary | |
|---|---|---|---|---|
| Model | Point-to-point tunnel | Mesh VPN | Hub-and-spoke | Session proxy |
| Setup effort | Medium (manual config) | Low (agent + SSO) | High (server + clients) | Medium (server + Vault) |
| Access granularity | Network level (IPs) | Network level (ACLs) | Network level (broad) | Resource level (per target) |
| Credential handling | N/A (network only) | N/A (network only) | N/A (network only) | Injection from Vault |
| Audit | Connection logs | Connection logs | Connection logs | Full session recording |
| NAT traversal | Manual (port forward) | Automatic (DERP) | Varies | N/A (outbound only) |
| Best for | Site-to-site | Team access | Legacy compliance | Fine-grained access |
Common Gotchas#
Zero trust does not mean no firewalls. Defense in depth still applies. Zero trust is an additional layer, not a replacement. Keep your network policies, host firewalls, and cloud security groups. If the zero trust layer fails (misconfiguration, software bug), the underlying network controls still provide protection.
Over-engineering for small teams. A 5-person startup does not need Boundary, SPIFFE/SPIRE, and a dedicated Keycloak deployment. Tailscale with SSO and Kubernetes network policies covers most needs. Add complexity when the team or compliance requirements demand it. Start simple: Tailscale for remote access, network policies for pod isolation, and SSO for all tools. Layer on service mesh mTLS and Boundary when you outgrow the basics.
Forgetting egress controls. Zero trust focuses heavily on ingress (who can reach my services). Egress is equally important. A compromised pod that can reach the internet can exfiltrate data. Apply egress network policies and DNS filtering to restrict outbound connections to known-good destinations.