This feature is available only on the Enterprise Plan of Portkey.
x-portkey-api-key or Authorization: Bearer; the token is validated against JWKS configured on the organisation.
Portkey Cloud validates JWTs on the control plane. Hybrid and air-gapped deployments can optionally enable gateway-local JWT authentication so the AI Gateway validates tokens locally instead of delegating every request to the control plane.
Validate JWT Token (Guardrail)
Optionally validate JWTs inside a config’s hook pipeline using the JWT guardrail plugin. This is separate from gateway-local JWT auth, which replaces API key validation at the gateway.
Configuring JWT Authentication
JWT authentication can be configured under Admin Settings → Organisation → Authentication.
JWKS Configuration
To validate JWTs, you must configure one of the following:- JWKS URL: A URL from which the public keys will be dynamically fetched.
- JWKS JSON: A static JSON containing public keys.
Hard Requirements (Read First)
JWT Header (JOSE Header)
alg: Must beRS256. Symmetric algorithms likeHS256are not accepted.typ: Must beJWT.kid: Required. The value in the JWT header must match akidin your JWKS.
Key Requirements
- Key type: RSA
- Key size: 2048 bits or higher
- Your JWKS must expose only the public key parameters (e.g.,
kty,n,e,use,alg,kid). Do not include private key material.
JWT Requirements
Supported Algorithm
- JWTs must be signed using RS256 (RSA Signature with SHA-256).
Required Claims
Your JWT payload must contain the following claims:expis mandatory. Tokens withoutexpor with expiredexpare rejected. A small amount of clock skew is tolerated.iatand/ornbfare recommended but optional.
On Portkey Cloud,
portkey_oid and portkey_workspace are required. In gateway-local JWT auth, org and workspace can be resolved from deployment configuration when you use a standard IdP token - see Integration modes.Optional Claims
User Identification
Portkey identifies users in the following order of precedence for logging and metrics:email_idsubuid
End-to-End Working Example (Generate → Configure JWKS → Sign → Call)
The following example uses Node.js and thejose library to:
- generate an RSA key pair,
- create a JWKS containing the public key,
- sign a JWT with the private key,
- call Portkey with the JWT.
1) Prerequisites
2) Generate RSA Keys, Create JWKS, and Sign a JWT (NodeJS)
Creategenerate-and-sign-jwt.mjs:
jwks.json: A JWKS containing your public key (with akid).token.jwt: A signed JWT ready to use with Portkey.
3) Add Your Public Key to Portkey (JWKS)
In the Portkey Admin UI:- Navigate to Admin Settings → Organisation → Authentication.
- Choose either:
- JWKS URL: Host
jwks.jsonat a reachable HTTPS URL and paste that URL. - JWKS JSON: Paste the entire contents of your generated
jwks.json.
- JWKS URL: Host
- Save changes.
kid in your JWT header matches a key in the configured JWKS.
4) Call Portkey Using the Signed JWT
Send the JWT in thex-portkey-api-key header.
If you prefer Python for signing, you can generate the RSA key pair using your preferred method, ensure the public key is present in your JWKS with a matching
kid, and use a library like PyJWT to sign with RS256 while setting the header { "alg": "RS256", "typ": "JWT", "kid": "<your-kid>" }.Authentication Process
-
The client sends the JWT in
x-portkey-api-keyorAuthorization: Bearer:Ifx-portkey-api-keyis absent,Authorizationis used. -
The gateway or control plane validates the JWT:
- Verifies the signature using the organisation JWKS.
- Checks token expiry.
- Ensures required claims are present.
- If valid, the request is authenticated and user details are extracted for authorization and logging.
- If invalid, the request is rejected. Common responses include 401 Unauthorized (invalid or expired token), 403 Forbidden (scope or workspace not allowed), 412 (usage limit exceeded), and 429 (rate limit exceeded).
JWT_ENABLED=ON, validation runs locally on the gateway. Otherwise, JWT-shaped tokens are validated by the control plane.
Authorization & Scopes
Once the JWT is validated, the server checks for the required scope. Scopes can be provided in the JWT as either a single string or an array of strings using thescope or scopes claim.
Scopes can also be prefixed with portkey. (e.g., portkey.completions.write).
JWT tokens with appropriate scopes function identically to workspace API keys, providing access to workspace-specific operations. They cannot be used as organization API keys, which have broader administrative permissions across all workspaces.
Example JWT Header
- This matches the signing example (
.setProtectedHeader({ alg: 'RS256', kid: publicJwk.kid, typ: 'JWT' })). - Ensure
kidexactly matches one key in your configured JWKS.
Embedding Default Configs in JWT
You can embed a default config directly in the JWT payload using thedefaults claim. This works the same way as attaching default configs to API keys, but lets you control it per-token - useful when different users or services need different routing rules.
The defaults object supports the following fields:
When a JWT with a
defaults.config_id is used, Portkey validates that the config belongs to the same organization before applying it. If the config is not found or doesn’t belong to the org, the default is ignored.
This follows the same precedence rules as API key default configs - if a user explicitly passes a config ID in their request headers, it will override the JWT default unless config override is disabled at the workspace level.
Example JWT Payload with Defaults
Example JWT Payload
Making API Calls with JWT Authentication
Once you have a valid JWT token, you can use it to authenticate your API calls to Portkey. Below are examples showing how to use JWT authentication with different SDKs.- NodeJS
- Python
- cURL
- OpenAI Python SDK
- OpenAI NodeJS SDK
Install the Portkey SDK with npm
Troubleshooting “Invalid API Key” Errors
- Wrong algorithm: Only
RS256is accepted;HS256or others will fail. - Missing or mismatched
kid: Your JWT header must include akidthat matches a key in the JWKS. - Incorrect header usage: Send the raw JWT in
x-portkey-api-key, or useAuthorization: Bearer <JWT>. Do not prefix the token withBearerinx-portkey-api-key. - Expired or missing
exp: Theexpclaim is required and must be in the future. Allow for small clock skew. - Private vs Public key mix-up: Your JWKS must contain only the public key parameters. The private key is used only for signing; never paste it into the JWKS JSON.
- Wrong org/workspace identifiers:
portkey_oid(ororganisation_id) andportkey_workspace(orworkspace_slug) must correspond to valid identifiers in your Portkey tenant. - Scopes missing for the API you call: E.g., chat completions needs
completions.write. - Unreachable JWKS URL: If using a URL, it must be publicly reachable by Portkey. For static JSON, ensure the pasted JSON is valid and includes
keys: [...].
All Invalid JWT errors are logged in the Audit Logs.
Sample error message:
Gateway-Local JWT Authentication
Gateway-local JWT authentication is available only on hybrid and air-gapped deployments.It requires gateway 2.5.0 or higher (Backend v1.13.0 or higher for air-gapped) with
JWT_ENABLED=ON.JWT_ENABLED is not ON, JWT-shaped tokens are validated by the control plane instead.
How it works
- The client sends a JWT in
x-portkey-api-keyorAuthorization: Bearer. - The gateway determines the organisation and workspace for the request.
- The gateway verifies the token signature against your configured JWKS.
- The gateway applies the same authorization, usage limits, rate limits, and policies as it would for a regular API key.
Integration modes
Choose the mode that matches how much control you have over your JWT issuer.Mode A - You control the JWT issuer
You can add Portkey-specific claims to your tokens (portkey_oid, portkey_workspace, usage_limits, rate_limits, defaults, and others) and use the full JWT feature set described in this guide.
Mode B - Standard IdP token
Use this when tokens come from Okta, Auth0, Entra, Cognito, or another IdP whose token schema you cannot change. Portkey handles org, workspace, and budget configuration on the server side. If your IdP cannot include Portkey scopes in tokens, setJWT_LOCAL_AUTH_DEFAULT_SCOPES on the gateway instead.
Enable gateway-local JWT
Gateway environment variables
Example:
Organisation JWKS
Configure JWKS under Admin Settings → Organisation → Authentication:- JWKS URL (recommended) - your IdP’s public key endpoint, or
- JWKS JSON - a static public key set
Required JWT claims (gateway-local)
Recommended optional claims
Example token payloads
Mode A - full Portkey-aware token:scope / scopes, set JWT_LOCAL_AUTH_DEFAULT_SCOPES on the gateway (e.g. completions.write,mcp.invoke).
In Mode B, the gateway resolves the org from ORGANISATIONS_TO_SYNC and the workspace from your deployment configuration.
Gateway scopes
Scopes can be provided as a space-separated string (scope) or an array (scopes) in the token, or via JWT_LOCAL_AUTH_DEFAULT_SCOPES on the gateway. A portkey. prefix is optional.
Each API route requires a matching scope. For example, chat completions requires
completions.write.
Organisation resolution
The gateway determines which organisation a token belongs to using this priority order:portkey_oidclaim in the tokenorganisation_idclaim in the tokenORGANISATIONS_TO_SYNC- only when exactly one org UUID is configured
ORGANISATIONS_TO_SYNC is set, the resolved org must be in that list.
After the org is determined, the gateway verifies the token signature against that org’s JWKS.
Workspace resolution
Workspace is determined after the token is verified, using token claims first and then deployment settings. From the token:portkey_workspaceworkspace_slug
Contact your Portkey account team to configure deployment-level JWT settings such as user allowlists, user-to-workspace mappings, and workspace allowlists.
Usage limits, rate limits, and policies
JWT-authenticated requests are subject to the same limit and policy checks as API key requests. Limits can come from three places:
Each unique JWT is tracked separately for token-level limits. Workspace limits and policies apply on top of any token-level limits - all must pass before the request proceeds.
Guidance by mode:
- Mode A: Put per-user or per-session budgets in the JWT
usage_limitsclaim. Use workspace limits and policies for shared team budgets. - Mode B: Configure all budgets and rate limits on the workspace or as workspace policies. For per-user splits within a shared workspace, use policies keyed off user metadata. For hard per-user isolation, map each user to a dedicated workspace.
Authentication flow
Troubleshooting gateway-local JWT
Quick setup checklist
Both modes:- Set
JWT_ENABLED=ON,PORTKEY_CLIENT_AUTH, andORGANISATIONS_TO_SYNCon the gateway - Configure JWKS for your org in the Portkey admin UI
- Ensure the gateway cache is enabled (required for hybrid and air-gapped deployments)
- Issue JWTs with required scopes and optionally
portkey_oid,portkey_workspace,usage_limits,rate_limits, anddefaults
- Set
ORGANISATIONS_TO_SYNCto a single org UUID - Configure scopes in your IdP, or set
JWT_LOCAL_AUTH_DEFAULT_SCOPESon the gateway if IdP scope changes are not possible - Set up workspace resolution (user mapping, workspace allowlist, or org default workspace)
- Configure workspace-level usage limits, rate limits, and policies in Portkey
Caching & Token Revocation
Validated JWTs are cached until they expire to reduce validation overhead. On gateway-local auth, org and workspace settings are also cached locally and refreshed during control plane sync. If you rotate signing keys:- Publish the new public key in JWKS with a new
kid. - Start issuing tokens signed by the new private key (with the new
kid). - Old tokens remain valid until their
expis reached.

