Continious Identity Verification at the Application Layer
Pomerium uses JSON Web Tokens (JWTs) to help your upstream services verify a user's identity and additional context (like group membership) at the application layer. In a zero trust environment, verifying that both the client and server are who they say they are is crucial. Pomerium handles user authentication, then mints a signed JWT for every verified and authorized request.
By validating that JWT, your application or service confirms:
- The request came from Pomerium (a trusted policy enforcement point).
- The user's identity is legitimate and authorized, according to policy.
- The JWT is specifically intended for the service (not some other application).
This article explains why identity & context verification at the application layer is important, how JWT-based verification works, and four different approaches you can use to verify JWTs:
- Manually (to understand the process)
- 3rd-party app with built-in JWT support (like Grafana)
- Custom application (using an existing JWT library or Pomerium's SDK)
- Sidecar (no code changes, e.g. Envoy proxy)
JWT Authentication Flow
- User authenticates
Pomerium redirects the user to your OIDC-compliant identity provider (IdP). - Pomerium issues a signed JWT
After the user is authenticated, Pomerium mints a new JWT. - JWT assertion header
The JWT goes in theX-Pomerium-Jwt-Assertion
header, following RFC7519 encoding. - Upstream service verifies
Your application (or a helper process) confirms the JWT's signature, audience, issuer, and timestamps.
If everything checks out, your service can trust the identity data in the token for additional authorization or logging.
Why JWT-Based Verification?
- Zero Trust: Enforces that every request is from a legitimate, authenticated user.
- Application Layer: Even if TLS terminates at Pomerium, the downstream service can verify the request is valid.
- Single Sign-On: A single IdP login flows downstream. Your app can read the user's email, groups, etc., from the JWT.
- Local Validation: JWTs are stateless. After an initial login, your service doesn't need to call the IdP again; it simply verifies the token signature.