Back to guides

mTLS vs JWT vs OAuth for Service Auth

By Davy Rogers

Three main approaches to authenticating service-to-service communication, compared. No single approach is best - the right choice depends on your infrastructure, team, and threat model.

Quick Comparison

mTLSJWT (self-issued)OAuth 2.0 Client Credentials
What proves identityX.509 certificateSigned tokenAccess token from auth server
Where identity is verifiedTLS handshake (transport layer)Application layerApplication layer
Claims/scopesNo (just identity)YesYes
Needs an auth serverNo (needs a CA)NoYes
Token/cert lifetimeHours to monthsMinutesMinutes
RevocationCRL or OCSP (can be slow)Wait for expiry or use blocklistRevoke at auth server
Setup effortHighLowMedium

mTLS in Detail

Mutual TLS authenticates both sides of a connection at the transport layer. Each service has an X.509 certificate signed by a trusted Certificate Authority.

Strengths:

  • Authentication happens before any application code runs.
  • No tokens to manage, rotate, or store.
  • Works natively in service meshes (Istio, Linkerd).

Weaknesses:

  • Certificate management is complex without automation.
  • No built-in concept of scopes or claims - just identity.
  • Certificate revocation (CRL/OCSP) can be slow or unreliable.

Best for: zero-trust networks, service meshes, environments where transport-level identity is required.

Reference: Istio - Mutual TLS Authentication

JWT (Self-Issued) in Detail

Each service signs its own tokens using a private key. Receiving services verify the signature using the public key.

Strengths:

  • Self-contained - no network call to verify (if using JWKS).
  • Supports claims: scopes, roles, tenant IDs.
  • Works across networks and cloud boundaries.

Weaknesses:

  • Cannot revoke individual tokens (stateless by design).
  • Key distribution requires a JWKS endpoint or shared config.
  • Easy to get wrong (algorithm confusion, missing aud validation).

Best for: environments where services need to pass context (scopes, roles) and mTLS is not practical.

Reference: RFC 7519 - JSON Web Token

OAuth 2.0 Client Credentials in Detail

Services obtain short-lived access tokens from a centralized authorization server using client credentials (client ID + secret or assertion).

Strengths:

  • Centralized control: issue, rotate, and revoke from one place.
  • Fine-grained scopes managed at the auth server.
  • Familiar pattern if your team already uses OAuth.

Weaknesses:

  • Auth server is a single point of failure.
  • Extra network hop for every token issuance.
  • More infrastructure to run and maintain.

Best for: organizations with existing identity infrastructure (Auth0, Keycloak, Entra ID) that want centralized policy.

Reference: RFC 6749 - Client Credentials Grant

Decision Framework

Use mTLS if:

  • You run Kubernetes with a service mesh (Istio, Linkerd).
  • You need transport-level identity (zero-trust, compliance requirements).
  • You do not need to pass claims or scopes between services.
  • Your platform manages certificates automatically.

Use JWT if:

  • Services need to exchange claims (user context, roles, scopes).
  • You want a lightweight solution without an auth server dependency.
  • Services are distributed across networks (multi-cloud, hybrid).
  • You can enforce short token lifetimes (5 minutes or less).

Use OAuth Client Credentials if:

  • You already have an identity provider (Auth0, Keycloak, Entra ID).
  • You want centralized visibility and control over service permissions.
  • You need easy revocation (disable a client at the auth server).
  • Teams prefer a managed solution over key distribution.

Combining Approaches

These are not mutually exclusive. Common combinations:

  • mTLS + JWT: mTLS for transport identity, JWT for application-level claims and scopes.
  • mTLS + OAuth: mTLS between services in the mesh, OAuth Client Credentials for cross-boundary calls.
  • OAuth with JWT tokens: the auth server issues JWTs as access tokens, combining centralized issuance with local verification.

Anti-Patterns

  • Static shared secrets between services. No rotation, no scoping, no audit trail.
  • Long-lived tokens (hours/days) without revocation strategy.
  • Trusting network location instead of identity. Containers move, IPs change.
  • mTLS with permissive authorization. mTLS proves identity but does not authorize actions - add application-level checks.

Related Guides

Published 04 Mar 2026

Frequently asked questions

When should I pick mTLS for service-to-service auth?
When both ends are within your trust domain, you can run a private CA or service mesh, and you want strong identity at the transport layer. Service meshes (Istio, Linkerd, Consul) make this practical.
When does JWT make more sense than mTLS?
When the relying party needs to make authorisation decisions based on claims that change per-request (user identity, scopes, tenant), or when you cross network boundaries you do not control.
Where does OAuth fit in service-to-service?
For third-party APIs, multi-tenant SaaS, or any case where a service is acting on behalf of a user. The client_credentials grant is the right shape for pure machine-to-machine.
Can I combine these?
Yes - a common production pattern is mTLS for transport identity inside the mesh, plus a short-lived JWT in the request for caller-specific claims. Defence in depth without much extra complexity.

Related

Want a professional to look at it?Get an AppSec Health Check.