Zero Trust Architecture

Zero trust explained as an engineering change rather than a product: per-request authorization, policy decision and enforcement points, device posture, workload identity and mTLS, a staged migration off the VPN, and what zero trust does not fix.

Zero Trust Architecture discards the implicit trust inherent in traditional network perimeters. It operates on the principle that no user, device, or service should be trusted by default, regardless of network location. Verification is required for every access attempt, identity is continuously validated, and access is granted on a least-privilege basis. This matters when workloads span hybrid clouds, when remote and mobile access is the norm, and when the cost of a single compromised credential must be limited to the smallest possible blast radius.

Verifying Identity on Every Request

Token Introspection & JWT Validation

When a client contacts a protected service, the request carries an access token—typically a JWT or an opaque token referenced via an introspection endpoint. The gateway or reverse proxy validates the token signature, checks expiration, and queries the token introspection service for revocation status. A successful validation yields HTTP 200; failure returns 401 with a body that includes one of a small set of standard error strings: invalid_token, token_revoked, insufficient_scope, or token_expired.

Concrete test:

curl -v https://api.example.com/orders \
  -H "Authorization: Bearer $ACCESS_TOKEN"

If the token is expired, the response includes {"error":"invalid_token","error_description":"The token has expired."} and the connection is rejected with a TLS-level 401.

Real-world flag detail: many token introspection endpoints (as defined in RFC 7662) accept a token parameter via POST body or token query string. The token_type_hint flag may be included to narrow the search scope, but omitting it is safe—the service searches all active token stores.

Device & MFA Posture Check

Zero Trust extends beyond the token to the presenter. The identity provider may attach device compliance flags (e.g., device_compliant: true, mfa_enrolled: true) to the token claims or return them via a separate device-attestation API. The enforcing component reads these flags and may reject the request if the device is unmanaged, jailbroken, or lacks the required MFA factor. A common sharp edge here is clock skew between the identity provider and the enforcing service: a token issued just before a clock rollback can appear valid for a window that the enforcing service, with a slightly later clock, rejects as expired, producing token_expired even though the JWT exp claim is still future-dated relative to the issuer.

Enforcing Least-Privilege Access

Policy Evaluation Against Request Context

Access decisions are never based on the token alone. The enforcing component assembles a policy decision request containing the subject (identity), resource, action, and contextual attributes (time of day, source IP, device posture, classification labels). This composite is fed to a policy engine that evaluates an ordered set of rules and returns a single decision: permit, deny, or indeterminate (requiring additional factors).

To see how an authorization check resolves on a live cluster, the kubectl CLI provides an immediate test:

kubectl auth can-i create pods --as=user:[email protected]

The command returns yes if the effective policy permits the action, no if denied, or unknown if the decision depends on attributes not present in the current context. This mirrors the broader Zero Trust pattern: the decision is not based on the identity alone but on the conjunction of identity, resource, action, and context. A policy that is too permissive (e.g., kubectl auth can-i create pods --as=*) will return yes for all subjects, which is the equivalent of the “default‑allow” pitfall in a Zero Trust deployment. Conversely, a policy that is too restrictive may produce no for legitimate requests, forcing a re‑evaluation of the rule set or the addition of contextual conditions (such as requiring device_compliant: true).

Policy rules are typically expressed in a declarative language (e.g., Rego, OPA syntax, or vendor‑native formats) and stored as policy bundles that the enforcement point loads at startup and refreshes periodically. The exact format varies by platform, but the evaluation mechanics are consistent: input JSON (or protobuf) containing the decision request fields is mapped to the policy language’s data model, the rules are evaluated in order, and the first matching rule determines the outcome. Misordered rules or overlapping conditions are a common source of unexpected decisions, which is why most policy engines provide a dry‑run mode to validate rule logic against sample inputs before promotion to production.

Just‑in‑Time & Ephemeral Credentials

Long‑lived API keys or service accounts are incompatible with Zero Trust because their compromise yields unlimited retroactive access. Instead, ZTA implementations issue short‑lived tokens—often minutes to an hour—after the full identity + device + policy check chain completes. These tokens are frequently carrier‑grade (e.g., JWT with nbf and exp claims) and may be bound to a specific client certificate or mTLS session. When the token expires, the subject must re‑authenticate, re‑prove device posture, and go through the policy evaluation loop again. A practical pattern is to front all service calls with an API gateway that intercepts the request, validates the token, and if the token is missing or expired, redirects the client to an authentication gateway that initiates the MFA + device‑check flow before issuing a fresh token.

Segmenting & Monitoring Traffic

Micro‑segmentation via Network Policies

In containerized environments, Zero Trust is enforced at the network layer through explicit allow/deny rules that describe which pod may talk to which other pod, on which ports, and with which protocol. A network policy resource expresses these rules declaratively. The following manifest creates a policy that permits only pods labeled role: frontend to receive connections on port 443 from pods labeled role: backend:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-backend-to-frontend-tls
spec:
  podSelector:
    matchLabels:
      role: frontend
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: backend
          ports:
            - protocol: TCP
              port: 443

Applying this with kubectl apply -f allow-backend-to-frontend-tls.yaml results in the enforcement point rejecting any pod that does not match the role: frontend label from accepting inbound connections on port 443 from non‑matching sources. A common misconfiguration is omitting the podSelector in the from section, which defaults to allowing traffic from all pods—a trap that silently reverts the policy to a permissive state. The error that surfaces is not always immediate; often the first observable symptom is unexpected inbound traffic that was intended to be blocked, discovered only during audit or penetration testing.

mTLS Enforcement for Service‑to‑Service Calls

Mutual TLS is a cornerstone of Zero Trust service meshes. Both the client and the server present X.509 certificates signed by a trusted certificate authority, and the TLS handshake fails if either side cannot verify the peer’s certificate chain. To test the handshake from a client instance, the following OpenSSL command exercises the connection:

openssl s_client -connect backend.service.namespace.svc:443 \
  -cert client.crt -key client.key -CAfile ca.crt

A successful handshake prints Verify return code: 0 (ok) and the application protocol proceeds. If the client certificate is expired, revoked, or signed by a CA not trusted by the server, the output includes SSL alert write: fatal: handshake failure and the connection is terminated before any application data is exchanged. A sharp edge in mTLS deployment is certificate rotation cadence: when server certificates are rotated without updating the trusted CA bundle on all clients, or when client certificates expire and are not renewed, services enter a state where healthy requests are uniformly rejected with TLS handshake failures, producing cascading outages that are difficult to diagnose because the error surface is at the transport layer, far removed from application‑level logs.

Detecting & Responding to Policy Violations

Continuous Audit Log Correlation

Every access attempt—whether permitted or denied—should generate a structured audit event that includes at minimum: timestamp, requesting identity, presented token (hash or opaque ID), resource identifier, action, policy decision, and contextual attributes (source IP, device posture, MFA status). These events flow into a centralized log aggregation system (e.g., Elasticsearch, Loki, or Splunk) where they can be correlated with network flow logs, authentication service logs, and device compliance records. A typical query pattern looks for sequences where a single identity produces a high frequency of deny decisions across diverse resources within a short window, which may indicate credential misuse or token theft.

Alerting on Anomalies

Alert rules are authored over the aggregated audit stream. Common thresholds include: more than five deny decisions for the same identity within ten minutes; a permit decision followed immediately by a deny on the same resource within one minute (suggesting a token replay or rotation race); and any permit decision where the device_compliant flag flipped from true to false between the token issuance and the request time. These alerts feed into an incident response playbook that isolates the affected identity, revokes active tokens, and triggers a conditional access re‑evaluation.

Sharp Edges & Common Pitfalls

This page was rewritten on 17 October 2026. It replaced a templated version that was not specific to its own title. How these pages are written and checked. If anything here is wrong, tell us at [email protected] and we will correct it.