Zero Trust Without the Pain

March 6, 2026 · Security

Our security team wanted zero trust. Our developers wanted to ship features. These goals seemed incompatible until we changed how we thought about security.

Zero trust doesn't have to mean zero productivity. Done right, it can make development faster.

The Problem with Perimeter Security

Traditional security assumes everything inside the network is trusted. This worked when servers sat in data centers and developers worked in offices.

Now developers work from coffee shops. Services run on Kubernetes clusters that change hourly. The perimeter is gone. We needed something better.

Identity Is the New Perimeter

In zero trust, every request must prove:

1. Who is making the request? (Identity)
2. Are they allowed to do this? (Authorization)
3. Is the request coming from a trusted device/location? (Context)

This sounds like overhead. It's actually freeing. When every request is verified, you don't need to worry about network boundaries. Developers can access production from anywhere safely.

Service-to-Service Identity

The hardest part: services need identity too. We use SPIFFE/SPIRE for workload attestation. Every pod gets a cryptographically verified identity at startup.

Before: Service A trusts Service B because it's on the same network
After: Service A verifies Service B's SPIFFE ID and JWT token

This prevents lateral movement. If an attacker compromises one service, they can't automatically access others. Each service must authenticate independently.

Making Authorization Explicit

Most systems have implicit authorization. "Users can access their own data." This is easy to write but hard to audit and easy to get wrong.

We moved to policy-as-code using Open Policy Agent:

package api.authz

import future.keywords.if
import future.keywords.in

default allow := false

allow if {
    input.user.role == "admin"
}

allow if {
    input.user.id == input.resource.owner_id
    input.action in ["read", "update"]
}

Policies are version controlled, tested, and reviewed like code. Authorization logic isn't hidden in middleware. It's explicit and auditable.

The Developer Experience

Security that slows developers down gets bypassed. We automated everything:

Local development. Developers get short-lived tokens automatically. No manual authentication steps. The CLI handles it.

$ ssbeach dev
✓ Authenticated as [email protected]
✓ Tunnel established to production services
✓ Local proxy running on localhost:8080

CI/CD integration. Service accounts get identities at build time. No long-lived credentials. No secrets in environment variables.

IDE support. VS Code extension shows which resources the current identity can access. Developers know permissions before they run code.

Context-Aware Access

Not all access is equal. We consider context:

- Is the device managed?
- Is the location expected?
- Is the time of day unusual?
- Is the request pattern anomalous?

A developer accessing production from their laptop at 2 PM gets full access. The same developer from an unknown device at 3 AM gets challenged with MFA. Same identity, different risk, different treatment.

Audit Without Anxiety

Every request is logged with:

- Who (identity)
- What (action and resource)
- When (timestamp with timezone)
- Where (source IP, device fingerprint)
- Why (authorization decision with policy version)

This isn't just for compliance. It's for debugging. When something breaks, we can trace exactly what happened and who did it.

The Migration Strategy

We didn't flip a switch. We used a sidecar pattern:

Legacy services → Sidecar proxy → Zero trust identity
                ↓
New services → Native zero trust

Legacy services got zero trust through a proxy. New services implemented it natively. Over 18 months, we migrated everything without downtime.

The Surprising Benefit

Zero trust didn't slow us down. It sped us up. Developers no longer need VPNs to access production. On-call engineers can debug from their phones. External contractors get limited, audited access without network access.

Security became invisible. Developers think about features, not firewalls. And our security posture is stronger than ever.

Trust nothing. Verify everything. Ship faster.

← Back to Home