BlogCybersecurity
Cybersecurity

Implementing Zero Trust Architecture with Keycloak and mTLS

How we design zero-trust security for enterprise applications using Keycloak SSO, mutual TLS, and network segmentation.

Sindika Security Feb 25, 2026 9 min read

Your firewall is not your security strategy. The moment an attacker gets past it — through a phished credential, a compromised VPN, or a supply chain vulnerability — they have unrestricted lateral movement across your entire infrastructure. Your database, your secrets, your admin panels — all one hop away.

Zero Trust Architecture eliminates this by treating every request as untrusted, regardless of where it comes from. Inside the network or outside — every call must prove its identity, demonstrate authorization, and communicate over encrypted channels. Here's how we implement it using Keycloak for identity and mTLS for service-to-service authentication.

“We replaced a VPN-only security model with Keycloak SSO, mutual TLS between all services, and Kubernetes NetworkPolicies. The result: a breach in one microservice can't reach any other. Every access is authenticated, authorized, and logged.”

— Sindika Security

Chapter 1: The Perimeter Is Dead

Traditional perimeter security assumes that everything inside your network is trusted. A VPN gets you in, and once you're in, you have access to everything. This “castle and moat” model made sense in 2005 when servers lived in on-premises data centers. It's catastrophically inadequate in 2026.

Modern infrastructure spans cloud VPCs, edge devices, SaaS APIs, contractor laptops, and mobile apps. There is no perimeter. Zero Trust accepts this reality and replaces location-based trust with identity-based verification for every single request.

Traditional Perimeter vs Zero Trust❌ Perimeter Security"Hard shell, soft center"Firewall at the edge onlyTrust everything insideVPN = full accessFlat internal networkOne breach = total compromiseImplicit trust by IP✅ Zero Trust"Never trust, always verify"Verify every requestLeast-privilege accessMicro-segmented networksMutual TLS (mTLS) everywhereBreach radius is one serviceIdentity-based access

Perimeter security: one breach = everything compromised. Zero Trust: one breach = one service, contained and logged.

Zero Trust Security Layers

LayerToolWhat It DoesPriority
IdentityKeycloak + OIDCAuthenticate every user and serviceCritical
TransportmTLS + Internal CAEncrypt and authenticate all trafficCritical
NetworkNetworkPolicyMicro-segment pod communicationHigh
ApplicationJWT + RBACAuthorize every API requestCritical
DataEncryption at restEncrypt databases and volumesHigh
AuditStructured loggingLog every access decisionHigh

Chapter 2: Identity as the New Perimeter — Keycloak SSO

In Zero Trust, identity is the foundation. Every user, every service, every API call must be authenticated. Keycloak provides enterprise-grade identity management with OIDC, SAML, and OAuth 2.0 — all self-hosted, so your authentication data never leaves your infrastructure.

Keycloak SSO Architecture👤 User🔐 KeycloakOIDC / SAML / OAuth 2.0JWT Token🖥️ FrontendReact / Next.jsValidates JWT🛡️ API GatewayNginx / KongValidates JWT⚙️ Service A.NET 9 APIValidates JWT🤖 Service BPython MLValidates JWT

All services validate JWT tokens issued by Keycloak. A single login authenticates the user across every application in the platform.

OIDC / OAuth 2.0

Industry-standard authentication protocols. Every frontend gets SSO. Every API validates JWT tokens. Stateless, scalable, and interoperable.

Realm Configuration

Enforce HTTPS everywhere, disable self-registration, enable brute-force protection (lock after 5 failures for 5 minutes). Security by default.

Client Types

Public clients for SPAs (no secrets, PKCE flow). Confidential clients for server-side APIs (with service accounts for machine-to-machine auth).

Role Hierarchy

Realm roles (admin, operator, viewer) with inheritance. Client-specific roles for fine-grained access (invoice-approver, report-viewer).

✅ Why Keycloak (Not Auth0 / Firebase Auth)

  • Self-hosted — user credentials, session data, and login events never leave your infrastructure. Critical for data sovereignty and regulatory compliance.
  • No per-user pricing — Auth0 charges per MAU. Keycloak is free for 10 users or 10 million. Cost-effective at enterprise scale without licensing surprises.
  • Full customization — custom login themes, attribute mappers, identity brokering (LDAP, Active Directory), and custom authentication flows tailored to your organization.
  • Enterprise federation — connect to corporate LDAP/AD directories. Employees use their existing credentials. No password sync, no migration, no disruption.

Chapter 3: The OIDC Authentication Flow

Understanding the Authorization Code flow is essential for implementing Keycloak correctly. It's the most secure flow for web applications and the one recommended for any browser-based frontend.

OIDC Authorization Code Flow1. Login ClickRedirect to Keycloak👤2. AuthenticateKeycloak login page🔐3. Auth CodeRedirect back + code📨4. ExchangeCode → JWT tokens🎫JWT contains: user ID, email, roles, organization, permissions, expiryAccess token (short-lived: 5 min) + Refresh token (long-lived: 30 min) + ID token (user info)

The authorization code flow: user authenticates with Keycloak, receives an auth code, exchanges it for JWT tokens. The access token is short-lived (5 min).

Access Token

Short-lived (5 minutes). Contains user identity, roles, and permissions. Validated by every API on every request. Stateless — no server-side session needed.

Refresh Token

Longer-lived (30 minutes). Used to obtain a new access token without re-authentication. Stored securely in the browser — never sent to APIs.

ID Token

Contains user profile information (name, email, organization). Used by the frontend to display user info. Never sent to backend APIs.

Every API endpoint is protected by role-based authorization. The JWT token carries the user's roles, and the middleware validates the token's signature, expiry, audience, and issuer on every single request. No session cookies, no server-side state — stateless authentication that scales horizontally across any number of service instances.

Chapter 4: Mutual TLS — Services Authenticate Each Other

JWT tokens handle user-to-service authentication. But what about service-to-service communication? In a microservices architecture, Service A calls Service B hundreds of times per second. How does Service B know the request is from the real Service A and not a compromised pod spoofing its identity?

Mutual TLS (mTLS) solves this. In standard TLS, only the server presents a certificate. In mTLS, both sides present certificates — the client proves its identity to the server, and the server proves its identity to the client. Both certificates are signed by the same internal Certificate Authority (CA).

Mutual TLS (mTLS) HandshakeService AClient cert 🔑Presents identityto prove who it isService BServer cert 🔑Both sides verifyeach other's identity1. Client Hello + Client Certificate2. Server Hello + Server Certificate🏛️ Internal CASigns both certificates✅ Encrypted channel + Both parties authenticated — no imposters

1. Create Internal CA

Generate a 4096-bit RSA key pair as your root of trust. This CA signs all service certificates. Store the private key in a hardware security module (HSM) or Vault.

2. Issue Service Certs

Each service gets its own certificate signed by the CA. Certificates include the service identity (e.g., service-a.internal) and expire after 365 days.

3. Mount in K8s/Compose

Service certificates are stored as Kubernetes Secrets or Docker secrets. Mounted read-only into containers at startup. No certificates in source code or images.

4. Configure mTLS

The reverse proxy (Nginx/Envoy) requires client certificates for all internal traffic. Unauthorized services without valid certificates are rejected at the TLS layer.

🤔 mTLS Operational Challenges

  • Certificate rotation — certificates expire. Automate renewal with cert-manager in Kubernetes or a cron job for Compose. An expired cert = total service outage.
  • Debugging is harder — you can't simply call an mTLS endpoint without the correct client certificate. Keep a debug cert for development and troubleshooting.
  • CA key management — the CA private key is the crown jewel. If compromised, an attacker can mint certificates for any service. Store it in a HSM or HashiCorp Vault.
  • Service mesh alternative — Istio/Linkerd handle mTLS automatically with sidecar proxies. Worth considering at 20+ microservices to avoid manual cert management overhead.

Chapter 5: Network Micro-Segmentation

Zero Trust at the network layer means no service can talk to any other service unless explicitly allowed. In Kubernetes, this is implemented with NetworkPolicies. In Docker Compose, it's separate Docker networks. The principle is the same: deny all, allow explicitly.

Network Micro-Segmentation🔒 DMZ (Public)Nginx IngressAPI GatewayStatic AssetsIngress from internet allowed🔒 App Zone (Internal)Auth ServiceBusiness APIWorkerOnly from DMZ via mTLS🔒 Data Zone (Restricted)PostgreSQLRedisMinIONo direct external access🔒 Management ZoneGrafanaLokiPrometheusAdmin VPN access only

Four network zones with explicit traffic rules. The data zone has no direct external access. Admin tools require VPN access.

Step 1: Default Deny

Apply a blanket policy that blocks ALL ingress and egress traffic for ALL pods. This is the foundation — nothing communicates unless explicitly permitted.

Step 2: Allow Specific Paths

Add individual allow rules: API service → PostgreSQL on port 5432. Nginx → API on port 8080. Each rule specifies source, destination, and port. Everything else remains blocked.

Step 3: Verify Blast Radius

Test: if an attacker compromises the API service, they can reach PostgreSQL (intended) but cannot reach Redis, MinIO, Grafana, or any other service. The blast radius is one service.

Chapter 6: Role-Based Access Control (RBAC)

Authentication answers “who are you?” Authorization answers “what can you do?” Zero Trust requires both. We implement authorization through Keycloak realm roles embedded in JWT tokens, validated by every service on every request.

Realm Roles

Platform-wide roles (admin, operator, viewer) with inheritance. Admin inherits operator permissions; operator inherits viewer. Defined in Keycloak, not in code.

Client-Specific Roles

Fine-grained roles per application (invoice-approver, report-viewer). A user can be an admin in one app and a viewer in another.

Custom JWT Claims

Embed organization, department, and employee ID in the token. APIs filter data by the user's org — multi-tenancy without separate databases.

Short Token Lifetimes

Access tokens expire in 5 minutes. If a token is stolen, the exploitation window is tiny. Refresh tokens extend sessions transparently.

✅ RBAC Best Practices

  • Least privilege — users get the minimum roles needed. An operator doesn't need admin access. A report viewer doesn't need write permissions.
  • Role hierarchy in Keycloak, not in code — define role inheritance centrally. Application code only checks “does this user have role X?” — never implements hierarchy logic.
  • Attribute-based data filtering — embed organization/department in the JWT. The API filters database queries by the user's org automatically. Multi-tenancy without complexity.
  • Regular access reviews — quarterly review of who has what roles. People change teams, leave the company, or accumulate permissions over time. Automate with Keycloak's admin API.

Chapter 7: Audit Logging — Trust but Verify

Zero Trust without audit logging is security theater. If you can't answer “who accessed what, from where, at what time?” — you're not doing Zero Trust. Every authentication decision, every authorization check, and every sensitive data access must be logged, timestamped, and searchable.

Structured Format

JSON logs with consistent fields: timestamp, user ID, action, resource, IP address, authorization decision, and response time. Machine-parseable, human-readable.

Every Decision Logged

Log both ALLOW and DENY decisions. A spike in authorization denials from one user or IP is often the first signal of a compromised account escalating privileges.

Immutable Storage

Audit logs are write-once, append-only. An attacker who compromises a service cannot modify the logs that recorded their intrusion. Ship logs to a separate system.

Alerting on Anomalies

Feed audit logs into your monitoring system. Alert on patterns: 10+ failed auth attempts, access from new countries, unusual data access volumes, privilege escalation attempts.

Log denials with even more detail than approvals. Capture the denied action, the missing role or permission, the source IP, and the user agent. These denial logs are your early warning system — they reveal attackers probing your authorization boundaries before they find a way through.

Chapter 8: The Pragmatic Implementation Roadmap

Zero Trust isn't a switch you flip — it's a gradual transformation. Trying to implement everything at once will paralyze your team. Here's the phased approach we use, ordered by impact and complexity:

Phase 1 (Week 1–2): Identity Foundation

  • Deploy Keycloak with PostgreSQL backend
  • Configure OIDC for all web applications
  • Implement JWT validation on every API
  • Enable MFA for all admin and operator accounts

Phase 2 (Week 3–4): Network Segmentation

  • Implement default-deny NetworkPolicies
  • Separate infrastructure into DMZ, app, data, and management zones
  • Move all internal services off public networks
  • Enable TLS for all internal communication

Phase 3 (Month 2): mTLS + RBAC

  • Deploy internal CA infrastructure
  • Enable mTLS between critical service pairs
  • Implement fine-grained RBAC policies with Keycloak
  • Add custom JWT claims for multi-tenant data filtering

Phase 4 (Month 3): Audit + Hardening

  • Structured audit logging on all access decisions
  • Anomaly detection on authentication events
  • Automated certificate rotation pipeline
  • Penetration testing and remediation cycle

“The most important step is Phase 1 — getting Keycloak deployed and JWT validation on every API. That single change eliminates 80% of unauthorized access risk. After that, each phase reduces the blast radius further.”

— Sindika Security

The Bottom Line

Zero Trust isn't paranoia — it's realism. Keycloak for identity, mTLS for service authentication, NetworkPolicies for segmentation, and audit logging for visibility. Four layers that transform your security posture from “hope the firewall holds” to “every request is verified, every access is logged.”

Start with identity. Add segmentation. Layer in mTLS. Instrument everything. Each phase makes the next breach smaller, slower, and more visible.