Zero trust is simple to state and hard to implement. The practical lever you can use today is the proxy. Put identity and policy enforcement at service boundaries, terminate or forward requests through policy-aware proxies, and authenticate every connection with short lived credentials. This tutorial shows two pragmatic, open-source patterns you can build from: a mesh sidecar pattern that enforces workload identity and request authorization, and an edge identity proxy pattern for outward-facing apps and APIs.

Why proxies matter

Proxies are enforcement points. Use them to stop implicit trust and to centralize the checks you care about: who called, how was the caller authenticated, what does the caller want to do, and does the current context allow it. For internal traffic you want mTLS-based workload identity plus policy evaluation. For edge traffic you want an identity-aware reverse proxy that integrates with OIDC/OAuth and can mutate or reject requests before they hit your applications.

Core components I recommend

  • Workload identity and short lived certs: SPIFFE / SPIRE for issuing SVIDs and managing X.509 or JWT identities to workloads.
  • L7 proxy: Envoy as a sidecar or gateway for rich filtering and external auth integration.
  • Policy decision and enforcement: Open Policy Agent with the Envoy external authorization integration.
  • Edge identity gateway: Ory Oathkeeper as an open-source Identity and Access Proxy for OIDC/OAuth flows and header mutators.
  • Certificate management for edge proxies or Envoy SDS: smallstep step-ca and step-sds for simple private CA and SDS support.
  • Identity provider for human/agent authentication: Keycloak is a solid open-source OIDC provider that integrates well with reverse proxies.

Pattern A: Mesh sidecar for internal zero-trust (Envoy + SPIRE + OPA)

When to use it

Use this pattern for greenfield cloud native services or when you can inject sidecars into pods. It gives the strongest per-workload identity and per-request policy enforcement.

High level steps

  1. Prepare a Kubernetes test cluster. Kind or minikube are fine for a lab. The upstream SPIRE and Envoy tutorials assume a cluster and a load balancer for some exercises.

  2. Deploy SPIRE server and agent. Create registration entries for nodes and workloads you will protect. SPIRE issues SVIDs (X.509 or JWT) that represent the workload identity.

  3. Deploy Envoy as a sidecar in front of each workload that must accept or make requests. Configure Envoy to use the local SPIRE agent for SDS so Envoy can present and rotate workload certificates automatically. The SPIFFE/SPIRE docs include example Envoy configurations showing SDS integration.

  4. Add OPA as an external authorizer. Use Envoy’s external authorization filter to forward CheckRequest messages to an OPA sidecar or service. Write Rego policies that consume request headers, path, method, and the SPIFFE identity presented by the calling Envoy. The official OPA Envoy tutorial and examples show the exact listener filter and OPA config needed.

Example flow (minimal)

  • Client service A calls service B.
  • Envoy sidecar for A establishes an mTLS connection to Envoy sidecar for B using SPIRE issued certs. Envoy attaches a JWT-SVID or presents an X.509 SVID depending on your choice.
  • Envoy at B sends an external authz check to OPA with attributes including the caller identity, request path, and HTTP headers.
  • OPA evaluates a Rego policy and returns allow or deny. If allowed, Envoy forwards traffic to the workload. If denied, Envoy rejects the request.

Minimal Rego example (conceptual)

package http.authz

default allow = false

allow { input.attributes.request.http.path == “/health” }

allow { input.attributes.source.identity == “spiffe://example.org/ns/default/sa/frontend” input.attributes.request.http.method == “GET” }

(Deploy this policy in OPA and configure Envoy ext_authz to call OPA over gRPC.)

Operational notes for the mesh

  • Start in audit mode. Envoy and OPA support dry run or logging only modes so you can iterate policies without breaking traffic.
  • Use short lived identities from SPIRE and automate rotation. SDS or SPIRE SDS patterns reduce manual cert churn.
  • Keep policy logic out of services. Use OPA bundles and CI pipelines for policy distribution.

Pattern B: Edge identity proxy for public APIs (Ory Oathkeeper + Keycloak + step-ca)

When to use it

When you need to modernize an edge API or web app without a full mesh rollout. This pattern centralizes authentication, authorization, and header injection for upstream services.

High level steps

  1. Deploy an identity provider such as Keycloak and configure your realm and clients. Keycloak includes guidance for operating behind reverse proxies and for secure OIDC endpoints.

  2. Deploy Ory Oathkeeper as your Identity and Access Proxy (IAP). Create rules that map incoming URLs to upstream services and define authenticators, authorizers, and mutators. Oathkeeper supports OIDC flows and can enrich forwarded requests with user identity tokens or headers.

  3. Terminate TLS at Oathkeeper or at an Envoy gateway in front of Oathkeeper. For private CA and automated certificate delivery to the gateway, run step-ca and step-sds to deliver certs to Envoy or gateway SDS. This makes cert management and rotation straightforward.

Example rules.yaml snippet for Ory Oathkeeper (conceptual)

  • id: allow-api upstream: url: https://internal.api.svc.cluster.local match: url: https://api.example.com/resource methods:
    • GET authenticators:
    • handler: oauth2_introspection authorizer: handler: allow mutators:
    • handler: id_token

This example has Oathkeeper validate the incoming token via OAuth2 introspection, allow the request and inject an identity token for the upstream.

Operational notes for the edge

  • Protect the OIDC endpoints. Keep the Keycloak admin interfaces off public networks and put them behind a management plane.
  • Use audit logs from Oathkeeper and from your identity provider to correlate decisions with actions.
  • For gradual rollout, use header based routing to send a portion of traffic through Oathkeeper while the rest goes direct.

Putting the pieces together and migration strategy

Start by protecting the edge with an identity proxy. That gives immediate value for user facing apps and APIs. Then incrementally add workload identity for internal services. A typical migration path is:

  1. Deploy Ory Oathkeeper or an Envoy gateway in front of public APIs and integrate with Keycloak. Validate auth flows and token enrichment.
  2. Stand up SPIRE in a staging environment and experiment with issuing SVIDs to a small set of backend services. Verify Envoy SDS integration.
  3. Add OPA for authorization checks and test policies in dry run. Push policies through your CI pipeline and enable enforcement gradually.

Tips from the lab

  • Keep policies simple and auditable. Start with allow-lists and expand to context aware policies that use caller identity, time, and request attributes.
  • Monitor latency. External authorization adds a decision hop. Co-locating OPA as a sidecar or using local policy evaluation reduces latency.
  • Automate certificate and identity bootstrap so developers do not have to manage keys. SDS providers like step-sds or SPIRE SDS solve this problem for Envoy.

Final words

Zero trust is a program, not a single product. Open-source proxies give you practical control points that are deployable today. Use a well defined rollout plan: protect the edge first, introduce workload identities, centralize authorization with OPA, measure everything, and iterate. If you want a compact lab to start, follow the SPIRE Envoy examples for mTLS and the OPA Envoy tutorial to wire up authorization. Then add Ory Oathkeeper and Keycloak to expand identity controls for users and partners.