TLS 1.3 & OAuth 2.0
[!WARNING] The Lateral Movement Threat: In legacy networks, an attacker breaching a single low-priority container (like a forgotten image rendering service) has free reign to pivot internally to the payment database. The perimeter is a myth. Zero Trust (mTLS): Every microservice must cryptographically prove its identity for every single call, regardless of network location.
In a modern distributed system, the network is inherently hostile. The outdated “castle-and-moat” security model assumes anyone inside the corporate VPN or VPC is trustworthy. But modern breaches (like the infamous Capital One SSRF attack or Target’s HVAC vendor breach) prove that once an attacker bypasses the perimeter, they can move laterally with impunity.
You must adopt a Zero Trust Architecture. This means:
- Encrypting all traffic in transit (TLS) to prevent eavesdropping.
- Cryptographically verifying identity for every single call (mTLS for services, OAuth/OIDC for users).
1. TLS 1.3: The Speed of Security
Transport Layer Security (TLS) encrypts data between Client and Server. Old versions (SSL, TLS 1.0, 1.1) are dead. TLS 1.2 is standard. TLS 1.3 is the future.
1.1 Why TLS 1.3?
TLS 1.3 removed obsolete, vulnerable cryptographic algorithms (like RSA key exchange and SHA-1) and streamlined the connection process.
- Faster Handshake (1-RTT): In TLS 1.2, establishing a secure connection took 2 Round Trips. In TLS 1.3, it takes 1-RTT.
- How it works: The client guesses which key exchange algorithm the server supports and sends its cryptographic key shares immediately in the first message (“Client Hello”).
- Perfect Forward Secrecy (PFS) by Default: If a nation-state actor records years of your encrypted traffic and suddenly steals your server’s private key today, they cannot decrypt the historical traffic.
- How it works: TLS 1.3 mandates Ephemeral Diffie-Hellman (ECDHE). A unique, ephemeral session key is generated for every single connection, independently of the server’s long-term private key.
- 0-RTT Resumption: If a client recently connected to a server, it can securely send encrypted application data in its very first packet (0-RTT), eliminating handshake latency entirely.
- The Replay Attack Risk: An attacker on the network could intercept a 0-RTT packet (e.g.,
POST /buy-stock) and resend it multiple times. - The Mitigation: Modern load balancers and web servers strictly limit 0-RTT data to safe, idempotent HTTP methods (like
GET). Non-idempotent requests (POST,PUT) force a standard 1-RTT handshake.
- The Replay Attack Risk: An attacker on the network could intercept a 0-RTT packet (e.g.,
Interactive Visualizer: TLS 1.3 Handshake
Watch the packets fly. See how the keys are exchanged.
[!TIP] Try it yourself: Click “Start Handshake” to see the 1-RTT exchange. Notice how the Client sends the Key Share immediately.
TLS 1.3 Handshake Simulator
Phase: Idle
2. mTLS: Zero Trust for Microservices
Standard TLS is one-way: the client verifies the server’s identity (so you know you’re talking to google.com and not a phishing site), but the server doesn’t know who the client is until a password or token is sent.
In a microservices architecture, relying on internal network boundaries (like VPCs) is insufficient. We need Mutual TLS (mTLS), where both sides present an X.509 certificate.
- Service A (Order) presents
cert_A. - Service B (Payment) presents
cert_B. - If
OrdercallsPayment,Paymentcryptographically verifiescert_Abefore processing the HTTP request. - If a compromised container (Hacker) tries to call
Paymentwithout a valid certificate, the connection is instantly rejected at the TCP/TLS layer—before the request ever reaches the application logic.
2.1 The Identity Problem: SPIFFE & Service Mesh
Managing thousands of certificates, rotating them before they expire, and securely delivering them to containers is a logistical nightmare. Do not build this yourself.
Modern infrastructure solves this using a Service Mesh (like Istio or Linkerd) combined with the SPIFFE (Secure Production Identity Framework for Everyone) standard.
- Node Attestation: When a pod boots up, a local agent verifies its identity using cloud provider metadata (e.g., AWS IAM roles or Kubernetes Service Accounts).
- Short-Lived Certificates: The agent issues a highly short-lived certificate (valid for hours, not years) called a SVID (SPIFFE Verifiable Identity Document).
- The Sidecar Proxy (Envoy): Your application code runs in plaintext, completely unaware of TLS. All traffic is intercepted by a local sidecar proxy (Envoy). The sidecar handles the complex mTLS handshake, encryption, and certificate rotation transparently.
The Service Mesh mTLS Architecture
3. OAuth 2.0 & OIDC
To secure user-facing APIs, you need to understand the difference between Authentication and Authorization.
- Authentication (AuthN): “Who are you?” (Identity). Handled by OIDC (OpenID Connect).
- Authorization (AuthZ): “What are you allowed to do?” (Permissions). Handled by OAuth 2.0.
3.1 The Analogy: The Valet Key
Imagine you want a 3rd-party app (like a budgeting tool) to read your bank transactions. Historically, apps asked for your actual bank username and password—a massive security risk.
OAuth 2.0 solves this using the Valet Key analogy:
- Master Key: Can open the trunk, glovebox, and drive anywhere. (Your Password).
- Valet Key: Can only start the engine and drive within a 5-mile radius. (An Access Token).
OAuth 2.0 allows a central Authorization Server to issue temporary “Valet Keys” (Access Tokens) with restricted scopes (e.g., read:transactions) to 3rd-party apps, meaning you never share your Master Key.
3.2 The OAuth 2.0 Roles
To design a system using OAuth, you must understand the four primary actors:
- Resource Owner: The User (You).
- Client: The App wanting access (e.g., the Budgeting App).
- Authorization Server: The Identity Provider (e.g., Okta, Auth0, or Google Login) that authenticates the user and issues tokens.
- Resource Server: The API holding the data (e.g., The Bank’s API).
3.3 The Authorization Code Flow (with PKCE)
This is the industry-standard flow for modern web and mobile apps. It ensures that tokens are never exposed in the browser’s URL history.
- The Request: The User clicks “Log in with Google” on the Client App.
- The Redirect: The Client redirects the User’s browser to the Authorization Server, attaching a cryptographic secret called a PKCE Code Challenge.
- Authentication: The User logs in and approves the requested permissions (Consent).
- The Auth Code: The Authorization Server redirects the User back to the Client with a temporary, single-use Authorization Code.
- The Exchange: The Client’s backend server directly contacts the Authorization Server, presenting the Auth Code and the PKCE Code Verifier. If they match, the server returns an Access Token and an ID Token.
- API Call: The Client uses the Access Token to fetch data from the Resource Server.
[!WARNING] The Implicit Flow is Dead: Older Single Page Applications (SPAs) used the “Implicit Flow”, which returned the Access Token directly in the URL fragment (
#token=...). This is highly vulnerable to token leakage and is now officially deprecated in favor of Auth Code + PKCE.
3.4 Token Types: Access vs. ID Tokens
A common mistake in system design is conflating these two tokens:
- Access Token: Used to access APIs (The Resource Server). It is often opaque to the Client. Its audience is the API.
- ID Token: A JWT strictly meant for the Client (the Frontend). It contains the user’s profile information (name, email) so the UI can render “Welcome, Alice”. Never send an ID Token to an API for authorization.
3.5 JWT (JSON Web Token): Stateless Portability
Tokens are typically formatted as JWTs (JSON Web Tokens). A JWT is a Stateless token; it contains the actual authorization data (Claims) cryptographically signed by the Authorization Server.
Structure: Header.Payload.Signature
- HS256: Symmetric Signing. The Authorization Server and Resource Server share the same secret key. Faster, but risky if the Resource Server is compromised (since it has the key to forge tokens).
- RS256: Asymmetric Signing. The Authorization Server signs with a Private Key. The Resource Server verifies using a Public Key (fetched via a standard JWKS endpoint). Mandatory for distributed microservices.
The Revocation Problem
Because JWTs are stateless, the Resource Server validates them purely via cryptography, without querying the database.
- The Catch: If a user is banned, their existing JWT remains mathematically valid until it expires.
- The Solution: Keep JWT lifetimes exceedingly short (e.g., 15 minutes). Use long-lived Refresh Tokens to silently obtain new JWTs. When a user is banned, you simply revoke their Refresh Token in the database.
Interactive Visualizer: JWT Decoder
Explore the anatomy of a Token. Try to forge a token by changing the payload!
[!TIP] Try it yourself: Click “Simulate Tampering” to change the payload. Notice how the Signature becomes invalid because the hash doesn’t match.
{
"alg": "HS256",
"typ": "JWT"
}
{
"sub": "u_123",
"name": "John Doe",
"admin": true
}
HMACSHA256( base64(header) + "." + base64(payload), secret)
3.3 Case Study: Securing a Microservices Architecture (PEDALS)
Let’s design the security architecture for a new financial application, strictly following the PEDALS framework.
- Process Requirements:
- Functional: Users must authenticate. Services must authorize requests based on user roles and service identity.
- Non-Functional: High security (prevent Man-in-the-Middle), low latency for auth checks, auditability.
- Estimate:
- Assume 1M active users, 10M internal service-to-service calls per day.
- Auth latency must be < 50ms per request.
- Data Model:
- Users Table:
(user_id, hashed_password, role). - Tokens: Stateless JWTs, avoiding heavy database lookups per request.
- Users Table:
- Architecture:
- External Gateway: Terminates TLS 1.3 from the public internet. Verifies JWT signature and expiration.
- Internal Mesh: All internal communication happens over mTLS. Service A cannot talk to Service B unless Service B explicitly authorizes Service A’s certificate.
- Auth Service (IdP): Issues JWTs via OAuth 2.0 / OIDC.
- Localized Details:
- Token Tampering: Use RS256 for JWTs. The Gateway verifies the token using the Auth Service’s public key (retrieved via JWKS endpoint).
- Token Revocation: Since JWTs are stateless, handle revocation via a short expiration time (e.g., 15 mins) and a long-lived Refresh Token.
- Scale:
- To scale token verification without bottlenecking the Auth Service, the Gateway caches the public keys.
- mTLS is offloaded to sidecar proxies (e.g., Envoy in an Istio mesh) so application code remains unaware of encryption details.
4. Summary
| Protocol | Purpose | Key Feature |
|---|---|---|
| TLS 1.3 | Encryption in Transit | 1-RTT Handshake. Forward Secrecy. |
| mTLS | Service-to-Service Auth | Both sides verify certificates. Zero Trust. |
| OAuth 2.0 | Authorization | Delegated access (Valet Key). |
| OIDC | Authentication | Adds Identity Layer (ID Token) on top of OAuth. |
| JWT | Stateless Token | Self-contained. Verify signature to trust data. |