JWT Service Plugin
Enterprise Feature
JWT Service Plugin is available as an add-on as part of an enterprise plan. If you would like to purchase this feature, please contact us at sales@zuplo.com or reach out to your account manager.
Most enterprise features can be used in a trial mode for a limited time. Feel free to use enterprise features for development and testing purposes.
The JWT Service Plugin allows you to create and issue short-lived JSON Web Tokens (JWTs) within your Zuplo API. This plugin is useful for scenarios where you need to issue tokens for authentication, authorization, or other purposes.
The plugin essentially turns your Zuplo API into its own identity provider that
can issue JWTs. Your Zuplo API will also serve the standard
/.well-known/openid-configuration endpoint and associated JWKS endpoint which
can be used by clients to discover the public keys used to verify the JWTs
issued by your API.
JWT Token
By default, this service issues JWTs using the EdDSA algorithm. This is the
recommended algorithm for new applications due to its strong security properties
and performance characteristics. However, not every library supports EdDSA, so
you should ensure that your client library can
handle this algorithm. If you need a different algorithm (for example, for
compatibility with an existing key pair or client library), use the algorithm
configuration option.
Use Cases
Some of the common use cases for the JWT service plugin include:
- Securing downstream APIs by issuing JWTs that can be used to verify that the request is coming from your Zuplo API
- Securing requests to other Zuplo API gateways (for example, when using the Federated Gateway capability on Zuplo managed dedicated deployments.)
- Calling third-party APIs that can be configured with federated identity such as AWS, Azure, or Google Cloud.
- Issuing short lived tokens for client side applications
Setup
To set up the JWT Service Plugin, you need to register it in your
zuplo.runtime.ts file.
modules/zuplo.runtime.ts
Configuration Options
The JWT Service Plugin accepts optional configuration to customize its behavior. You can pass a configuration object to the constructor:
modules/zuplo.runtime.ts
Available Options
-
basePath(optional): The base path for the JWT issuer endpoint. Default is"/__zuplo/issuer". This affects the issuer URL and OIDC configuration endpoints. -
algorithm(optional): The asymmetric signing algorithm used for issued JWTs. Default is"EdDSA". Supported values areEdDSA,RS256,RS384,RS512,PS256,PS384,PS512,ES256,ES384, andES512. The algorithm must match the configured key pair — for example, an RSA key requires anRS*orPS*value and an Ed25519 key requiresEdDSA. Symmetric algorithms (likeHS256) aren't supported because the plugin publishes a JWKS endpoint. -
expiresIn(optional): Sets the default expiration time for JWTs. Default is"1h". Can be either:- A number: Direct value in seconds (for example,
300for 5 minutes) - A string: Time span format (for example,
"5 minutes","1 hour","7 days")
Valid time units include:
- Seconds:
"sec","secs","second","seconds","s" - Minutes:
"minute","minutes","min","mins","m" - Hours:
"hour","hours","hr","hrs","h" - Days:
"day","days","d" - Weeks:
"week","weeks","w" - Years:
"year","years","yr","yrs","y"(365.25 days)
Examples:
CodeNote: Individual JWT creation can override this default by specifying
expiresInin thesignJwtmethod. - A number: Direct value in seconds (for example,
Usage
Once the plugin is registered, you can use it to issue JWTs in custom handlers or policies.
modules/handlers/jwt-issue.ts
JWT Issuer and OIDC Configuration
When the JWT Service Plugin is enabled, your Zuplo API acts as an identity provider with the following endpoints:
- Issuer URL:
https://{deploymentName}.zuplo.app/__zuplo/issuer(or your custom domain if configured) - OIDC Configuration:
https://{deploymentName}.zuplo.app/__zuplo/issuer/.well-known/openid-configuration - JWKS Endpoint:
https://{deploymentName}.zuplo.app/__zuplo/issuer/.well-known/jwks.json
The OIDC configuration endpoint returns a standard OpenID Connect discovery document that includes the JWKS URI for retrieving the public keys used to verify JWTs.
Creating a JWT Authorization Policy
A common pattern is to create a custom policy that automatically adds JWT tokens to outbound requests. This is useful when calling downstream APIs that require authentication.
Here's an example of a custom policy that adds a JWT to the Authorization header of outbound requests:
modules/policies/jwt-auth-upstream.ts
Validating JWTs in Upstream Services
Upstream services can validate the JWTs issued by your Zuplo API by verifying
the signature and claims. The examples below use EdDSA, the plugin's default
signing algorithm. If you configured a different algorithm using the algorithm
option, use that value in the algorithms list instead.
Node.js/Express Example
This example uses the jose library because
the popular jsonwebtoken library doesn't support the EdDSA algorithm.
validate-jwt.mjs
Python/FastAPI Example
EdDSA validation in PyJWT requires the cryptography package. Install PyJWT
with the crypto extra: pip install pyjwt[crypto].
The keys in Zuplo's JWKS don't include a kid, so this example loads the key
directly from the JWKS document rather than using PyJWKClient, which only
matches keys by kid.
validate_jwt.py
Dynamic OIDC Discovery
For more flexible JWT validation, you can dynamically discover the OIDC
configuration based on the issuer claim in the JWT. This example fetches the
issuer's OIDC discovery document to find the JWKS endpoint, then verifies the
token with the same jose library used in the
Node.js example above.
Security Warning
This approach is particularly useful when you have multiple Zuplo APIs with different issuers or when the issuer URL might change (for example, between environments). It's CRITICAL that you validate the issuer claim in the JWT to ensure you are only allowing tokens from trusted issuers.
validate-jwt-dynamic.ts
This approach is particularly useful when:
- You need to validate JWTs from multiple Zuplo APIs with different issuers
- The issuer URL might change (for example, between environments)
- You want to leverage automatic OIDC discovery for configuration updates
Important Validation Steps
When validating JWTs from Zuplo:
- Verify the signature using the public keys from the JWKS endpoint
- Check the issuer matches your Zuplo API's issuer URL
- Validate expiration to ensure the token hasn't expired
- Verify audience if your tokens include audience claims
- Check any custom claims required by your application
The JWT Service Plugin handles key rotation automatically, so always fetch the current public keys from the JWKS endpoint rather than hard coding them.