Definition
- Zero trust – replaces "trust inside the network" with "never trust, always verify" on every request, regardless of origin.
- Mutual TLS (mTLS) – both client and server present certificates, so only known entities can connect.
- OAuth2/JWT – every request carries a verified, short-lived identity token that the gateway validates.
- Dynamic access control – a policy engine (OPA) evaluates authorization based on current policy, not hardcoded roles.
- Anomaly detection – continuous behavioral monitoring that catches suspicious patterns even from authenticated callers.
- Defense in depth – services behind the gateway also verify identity; the gateway alone is not sufficient.
The old way was like a bank where, once you were past the front gate, you could walk into any room freely because you were "inside." Zero trust is like a modern National Bank of India where every single door, even inside, checks your badge, confirms you are allowed into that exact room for that exact task right now, verifies the badge is genuine and not expired, and a security team watches for odd behavior like someone suddenly trying a hundred doors in a minute.
Understanding the Concepts
What is mutual TLS (mTLS)?
Ordinary TLS proves the server's identity to the client. Mutual TLS also makes the client prove its identity using a client certificate. This ensures only known clients and services can connect.
# Spring Boot mTLS configuration
server:
ssl:
enabled: true
key-store: classpath:gateway-keystore.p12
key-store-password: changeit
trust-store: classpath:truststore.p12
trust-store-password: changeit
client-auth: need # Require client certificate
// Without mTLS: any client can connect if it knows the URL // With mTLS: client must present a trusted certificate // Unknown client → connection refused at TLS handshake // No request reaches the gateway → strongest perimeter defense
How does OAuth2/JWT provide request-level identity?
Every request carries a JWT signed by the authorization server. The gateway verifies the signature, expiry, issuer, and audience before trusting the identity.
package com.bank.gateway.security;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class JwtConfig {
@Bean
public JwtDecoder jwtDecoder() {
return NimbusJwtDecoder.withJwkSetUri(
"https://auth.nbi.example.com/.well-known/jwks.json")
.build();
// Fetches public keys once, caches them
// Verifies signature, expiry, issuer on every request
}
}
// JWT payload:
// {sub: "CUST-1001", scope: "transfer read", exp: 1705313400}
// Gateway checks:
// 1. Signature valid? (against cached public key)
// 2. Expired? (exp > now)
// 3. Issuer matches? (iss = auth.nbi.example.com)
// 4. Audience matches? (aud = banking-api)
// All pass → trusted identity → forward X-User-Id: CUST-1001
What is dynamic access control with OPA?
Authentication answers "who are you?" Authorization answers "are you allowed to do this specific thing right now?" A policy engine like Open Policy Agent (OPA) makes authorization contextual and dynamic.
# OPA policy: transfer authorization
package bank.transfer
default allow = false
allow {
input.token.scope[_] == "transfer"
input.amount <= 500000
not input.location_flagged
}
allow {
input.token.scope[_] == "transfer"
input.token.role == "SENIOR_MANAGER"
# Senior managers can transfer any amount
}
// Request: transfer 50000 INR, scope=transfer, location=normal // OPA: allow = true → gateway forwards request // Request: transfer 1000000 INR, scope=transfer, location=flagged // OPA: allow = false → gateway returns 403 Forbidden // No code change needed to adjust policy: update OPA rules only
How does anomaly detection work?
Even authenticated callers can be compromised. The gateway monitors behavior continuously and flags suspicious patterns.
// Anomaly detection signals:
// 1. Sudden spike: CUST-1001 normally makes 5 requests/min,
// now making 500/min → possible credential stuffing
// 2. Unusual location: first login from India, now from Russia
// within 30 minutes → impossible travel
// 3. Pattern: trying every account ID sequentially
// → enumeration attack
// Gateway response to anomalies:
// Mild: increase logging, flag for review
// Moderate: require step-up authentication (OTP)
// Severe: block the request, revoke the token
How do the four pillars work together?
A request must pass all four checks before reaching the backend service.
// Zero-trust gateway flow:
// 1. mTLS: client presents certificate → connection established
// 2. JWT: token verified (signature, expiry, issuer) → identity proven
// 3. OPA policy: authorized for this action + context → access granted
// 4. Anomaly check: behavior normal → request proceeds
// 5. Forward: minimal verified context (X-User-Id) over mTLS to service
// Only after ALL FOUR does the request reach the backend
Why is the gateway necessary but not sufficient?
In zero trust, every hop re-verifies. Services behind the gateway must validate the forwarded identity and use mTLS service-to-service.
// WRONG: service blindly trusts the gateway
public BigDecimal getBalance(HttpServletRequest request) {
String userId = request.getHeader("X-User-Id");
// Trust it completely because "the gateway checked"
return accountRepo.getBalance(userId);
}
// CORRECT: service validates the forwarded identity
public BigDecimal getBalance(HttpServletRequest request) {
String userId = request.getHeader("X-User-Id");
// Verify the request came over mTLS from a trusted gateway
// Verify X-User-Id is present and well-formed
if (userId == null || !isValidFormat(userId)) {
throw new UnauthorizedException("Invalid identity context");
}
return accountRepo.getBalance(userId);
}
What is token hygiene?
Short-lived tokens limit the damage from theft. Never log tokens. Consider token binding to tie a token to a specific client.
// Token hygiene rules:
// 1. Short TTL: access token expires in 5-15 minutes
// 2. Refresh token: longer-lived, used to get new access tokens
// 3. Never log the token value (log token ID or hash instead)
// 4. Token binding: tie token to client TLS certificate
// → stolen token unusable from a different machine
// 5. Revocation check: for high-risk operations, verify token not revoked
What are common mistakes? (wrong vs correct)
// WRONG: trust everything inside the network
// Internal service calls without mTLS or identity verification
// Compromised service can call any other service freely
// CORRECT: zero trust inside the network
// Every service-to-service call uses mTLS
// Every call carries verified identity
// Every service checks authorization
// WRONG: long-lived tokens (24 hours)
// Stolen token → 24 hours of unauthorized access
// CORRECT: short-lived tokens (15 minutes)
// Stolen token → 15 minutes of exposure, then useless
What should a senior engineer know?
A senior engineer implements all four pillars and understands that zero trust is a spectrum. They start with mTLS and JWT, add OPA for dynamic policies, and layer in anomaly detection. They never skip defense in depth.
// Zero-trust maturity levels:
// Level 1: JWT at gateway, services trust X-User-Id header
// Level 2: mTLS at gateway + between services
// Level 3: OPA dynamic policies, short-lived tokens
// Level 4: Anomaly detection, token binding, continuous verification
// Each level adds protection; skip none in banking
Visual Overview
Zero-Trust Gateway Flow
───────────────────────
Client
│
│── mTLS handshake (client cert) ──▶ Gateway
│ │
│ ┌───────┤ 1. mTLS: client is known entity
│ │ │ 2. JWT: verify signature, expiry
│ │ │ 3. OPA: authorize this action
│ │ │ 4. Anomaly: behavior normal?
│ │ │
│ │ ALL PASS?
│ │ ├── YES → forward with X-User-Id
│ │ └── NO → reject (401/403)
│ │
│ └───────▶ Backend Service (over mTLS)
│ │
│ Validates X-User-Id
│ Checks own authorization
│ (defense in depth)
Key Takeaway
Zero-trust security replaces the old "trust everything inside the network" model with "never trust, always verify" on every request. At the gateway, zero trust is enforced through four pillars: mutual TLS so both client and server prove their identity, OAuth2/JWT so every request carries a verified short-lived identity, dynamic access control through a policy engine like OPA so authorization reflects current rules and context, and anomaly detection so suspicious behavior is caught even from authenticated callers.
At National Bank of India, mTLS stopped a compromised internal machine from calling the Payment Service because without a trusted client certificate the connection was refused at the TLS handshake. Short-lived JWTs limited the damage when a token was briefly leaked, and OPA policies correctly refused a large transfer from an unusual location even though the token was technically valid.
The key nuance is defense in depth: the gateway is necessary but not sufficient. Services behind the gateway also verify the forwarded identity and use mTLS service-to-service, because in zero trust every hop re-verifies. Token hygiene, meaning short TTLs, never logging tokens, and token binding, ensures a stolen token is both short-lived and hard to reuse.
Remember one sentence: zero trust at the gateway means mTLS for transport identity, JWT for request identity, OPA for dynamic authorization, and anomaly detection for continuous verification, and services behind the gateway still verify because every hop re-verifies.
---