JOSE Validation Policy
General Information
Policy Type
policy-jose-validation
Description
JOSE Validation policy validates JOSE (JSON Object Signing and Encryption) tokens including JWT (JSON Web Token), JWE (JSON Web Encryption), and JWS (JSON Web Signature). It can validate signatures, decrypt encrypted tokens, verify claims, and extract client information from tokens.
Endpoints
List Policies
GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/
Add Policy
POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Update Policy
PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Delete Policy
DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
List Policies
Endpoint
GET /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"resultList": [
{
"apiProxy": {
"name": "MyAPI",
"requestPolicyList": [
{
"type": "policy-jose-validation",
"name": "jose-validation-policy",
"description": "Validate JOSE tokens",
"active": true,
"joseTarget": "BODY",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {
"role": {
"value": "admin",
"valueType": "STRING"
}
},
"requiredClaimList": ["sub", "exp"],
"prohibitedClaimList": [],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": true,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "NONE",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
],
"responsePolicyList": [],
"errorPolicyList": []
}
}
],
"resultCount": 1
}
cURL Example
curl -X GET \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAPI/policies/" \
-H "Authorization: Bearer YOUR_TOKEN"
Add Policy
Endpoint
POST /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
| Content-Type | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Request Body
Full JSON Body Example - Basic Validation
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate JOSE tokens from request body",
"active": true,
"joseTarget": "BODY",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {
"role": {
"value": "admin",
"valueType": "STRING"
}
},
"requiredClaimList": ["sub", "exp"],
"prohibitedClaimList": [],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": true,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "NONE",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
}
Full JSON Body Example - From Authorization Header
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate JOSE tokens from Authorization header",
"active": true,
"joseTarget": "AUTHORIZATION_HEADER",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {},
"requiredClaimList": ["sub", "exp", "iat"],
"prohibitedClaimList": [],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": false,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "NONE",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
}
Full JSON Body Example - With Proxy JWK
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate JOSE tokens using proxy JWK",
"active": true,
"joseTarget": "BODY",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {},
"requiredClaimList": ["sub", "exp"],
"prohibitedClaimList": [],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": false,
"validateACLforIssuer": false,
"jwkIdForValidationAndSign": "my-jwk-id",
"decrypt": true,
"decryptByIssuer": false,
"jwkIdForDecryptionAndEncryption": "my-decrypt-jwk-id",
"stripAndDecode": "ALL",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
}
Full JSON Body Example - Partial Decode with Claims Extraction
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate and partially decode JOSE tokens",
"active": true,
"joseTarget": "BODY",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {
"role": {
"value": "admin",
"valueType": "STRING"
},
"permissions": {
"value": "read,write",
"valueType": "STRING_LIST"
}
},
"requiredClaimList": ["sub", "exp", "iat"],
"prohibitedClaimList": ["blacklisted"],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": true,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "PARTIAL",
"jwtClaimsToDecode": "sub,role,permissions",
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
}
Full JSON Body Example - Variable Target
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate JOSE tokens from variable",
"active": true,
"joseTarget": "CHOOSE_FROM_VARIABLE",
"joseTargetVariable": {
"type": "HEADER",
"headerName": "X-JWT-Token"
},
"clientSourcePart": "VARIABLE",
"clientSourceVariable": {
"type": "HEADER",
"headerName": "X-Client-ID"
},
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {},
"requiredClaimList": ["sub", "exp"],
"prohibitedClaimList": [],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": true,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "NONE",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "CHOOSE_FROM_VARIABLE",
"decodedClaimsTargetVariableForDataManipulation": {
"type": "HEADER",
"headerName": "X-Decoded-Claims"
}
}
}
Full JSON Body Example - DPoP Validation
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["test"]
},
"policy": {
"type": "policy-jose-validation",
"active": true,
"joseTarget": "AUTHORIZATION_HEADER",
"validateSign": true,
"validateExpirationTime": true,
"enableDpop": true,
"dpopValidateHtm": true,
"dpopValidateHtu": true,
"dpopValidateCnfBinding": true,
"dpopValidateJti": true,
"dpopMaxProofAge": 60,
"dpopMaxProofAgeUnit": "SECONDS",
"dpopCacheConnectionTimeout": 3,
"dpopCacheErrorHandlingType": "CONTINUE"
}
}
DPoP (RFC 9449) validation is layered on top of the standard JOSE validation and can run alongside signature/claim validation, or on its own (with validateSign disabled). The access token the proof binds to is read from whatever joseTarget points at, so there is no target restriction. Invalid or replayed proofs, and access tokens not bound to the proof key, are rejected with HTTP 401.
Request Body Fields
operationMetadata
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| targetScope | string | Yes | - | Policy scope: ALL or ENDPOINT |
| targetEndpoint | string | No* | - | Endpoint path (required if targetScope=ENDPOINT) |
| targetEndpointHTTPMethod | string | No* | - | HTTP method (required if targetScope=ENDPOINT) |
| targetPipeline | string | Yes | - | Pipeline: REQUEST, RESPONSE, or ERROR |
| deploy | boolean | No | true | Whether to deploy after adding policy |
| deployTargetEnvironmentNameList | array | No | [] | List of environment names to deploy to |
| order | integer | No | null | Policy execution order (starts from 1) |
Enum: targetScope
ALL- Policy applies to all endpointsENDPOINT- Policy applies only to specified endpoint
Enum: targetPipeline
REQUEST- Executes in request pipeline (validates incoming tokens)RESPONSE- Executes in response pipeline (validates outgoing tokens)ERROR- Executes in error pipeline
Enum: targetEndpointHTTPMethod
GET,POST,PUT,DELETE,PATCH,OPTIONS,HEAD
policy
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| type | string | Yes | - | Policy type: policy-jose-validation |
| description | string | No | - | Policy description |
| active | boolean | No | true | Whether policy is active |
| joseTarget | string | Yes | BODY | JOSE target location. See EnumJoseTarget |
| joseTargetVariable | object | No* | null | Variable for JOSE target (required if joseTarget=CHOOSE_FROM_VARIABLE). See VariableDTO |
| clientSourcePart | string | Yes | CLAIMS | Client source part. See EnumJoseUserSourcePart |
| clientSourceVariable | object | No* | null | Variable for client source (required if clientSourcePart=VARIABLE). See VariableDTO |
| clientFieldname | string | No | iss | Client field name for extraction (e.g., "iss" for issuer) |
| acceptedAudienceList | array | No | [] | List of accepted audience values |
| exactMatchClaimMap | object | No | Map of exact match claims. See MapValue | |
| requiredClaimList | array | No | [] | List of required claim names |
| prohibitedClaimList | array | No | [] | List of prohibited claim names |
| validateExpirationTime | boolean | No | true | Whether to validate expiration time |
| validateSign | boolean | No | true | Whether to validate JOSE signature |
| validateByIssuer | boolean | No | true | Validate by issuer (true) or by proxy's JWK (false) |
| validateACLforIssuer | boolean | No | true | Whether to validate ACL for issuer |
| jwkIdForValidationAndSign | string | No* | null | JWK ID for validation and signing (required if validateSign=true and validateByIssuer=false) |
| decrypt | boolean | No | true | Whether to decrypt JOSE |
| decryptByIssuer | boolean | No | true | Decrypt by issuer (true) or by proxy's JWK (false) |
| jwkIdForDecryptionAndEncryption | string | No* | null | JWK ID for decryption and encryption (required if decrypt=true and decryptByIssuer=false) |
| dynamicKeyForValidationAndSign | object | No | - | Dynamic HTTP key fetching configuration for the signing/validation key (see JoseDynamicKeyConfig Object) |
| dynamicKeyForDecryptionAndEncryption | object | No | - | Dynamic HTTP key fetching configuration for the encryption/decryption key (see JoseDynamicKeyConfig Object) |
| stripAndDecode | string | Yes | NONE | Strip and decode mode. See EnumJoseStripAndDecode |
| jwtClaimsToDecode | string | No* | null | JWT claims to decode (required if stripAndDecode=PARTIAL). Comma-separated claim names |
| decodedClaimsTargetForDataManipulation | string | No | BODY | Target for decoded claims data manipulation. See EnumJoseTarget |
| decodedClaimsTargetVariableForDataManipulation | object | No* | null | Variable for decoded claims target (required if decodedClaimsTargetForDataManipulation=CHOOSE_FROM_VARIABLE). See VariableDTO |
| enableDpop | boolean | No | false | Enable DPoP (RFC 9449) sender-constrained proof validation on top of standard JOSE validation |
| dpopProofHeaderName | string | No | DPoP | HTTP header carrying the DPoP proof |
| dpopMaxProofAge | integer | No | 60 | Proof freshness window based on the proof iat claim; clock skew tolerance is added on top |
| dpopMaxProofAgeUnit | string | No | SECONDS | Unit for dpopMaxProofAge. See EnumTimeUnit |
| dpopValidateHtm | boolean | No | true | Validate the proof htm claim against the request HTTP method |
| dpopValidateHtu | boolean | No | true | Validate the proof htu claim against the request URI |
| dpopExpectedHtu | string | No | null | Expected htu value; blank derives it from the request (variable-aware) |
| dpopValidateCnfBinding | boolean | No | true | Validate the access token cnf.jkt binding against the proof key thumbprint. Works against the token read from any joseTarget (BODY, AUTHORIZATION_HEADER, or CHOOSE_FROM_VARIABLE) |
| dpopValidateAth | boolean | No | false | Validate the proof ath claim against the access token hash. Works against the token read from any joseTarget |
| dpopValidateJti | boolean | No | true | Enable replay protection via distributed cache using the proof jti claim |
| dpopJtiCacheTtl | integer | No | null | jti replay cache retention in seconds; blank derives it from max proof age + clock skew |
| dpopCacheConnectionTimeout | integer | No | 3 | DPoP replay cache connection timeout in seconds |
| dpopCacheErrorHandlingType | string | No | CONTINUE | Behavior when the replay cache is unreachable. See EnumCacheErrorHandlingType |
JoseDynamicKeyConfig Object
Configuration for fetching a JOSE key over HTTP. Present twice on the policy: dynamicKeyForValidationAndSign (signing/validation key) and dynamicKeyForDecryptionAndEncryption (encryption/decryption key). Used when keySourceMode is DYNAMIC_HTTP; ignored for an embedded JWK.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| keySourceMode | string | No | - | EMBEDDED for a stored JWK, DYNAMIC_HTTP to fetch over HTTP |
| httpRequest | object | No* | - | Key request definition (required when keySourceMode=DYNAMIC_HTTP) |
| keyExtractionVariable | object | No* | - | Variable that extracts the key from the response (required when keySourceMode=DYNAMIC_HTTP) |
| keyFormat | string | No | - | AUTO_DETECT, PUBLIC_KEY, PRIVATE_KEY, CERTIFICATE or JWK_JSON |
| keyAlgorithm | string | No | NONE | Key algorithm; NONE lets Apinizer auto-detect |
| keyKid | string | No | - | Key id (kid) to select from a JWK Set |
| enableCache | boolean | No | false | Cache the fetched key |
| cacheByVariable | object | No* | - | Variable used to build the key cache entry (required when enableCache=true) |
| keyCacheTtl | integer | No | 3600 | Key cache time-to-live in seconds |
| keyCacheCapacity | integer | No | - | Maximum number of cached key entries |
| keyRespectCacheInvalidationHeaders | boolean | No | true | Honour Cache-Control headers returned by the key endpoint |
| keyCacheStorageType | string | No | DISTRIBUTED | LOCAL or DISTRIBUTED |
| keyCacheConnectionTimeout | integer | No | 3 | Distributed key cache connection timeout in seconds |
| keyCacheErrorHandlingType | string | No | CONTINUE | Action when the cache service is unreachable: CONTINUE or FAIL |
| retryOnKeyError | boolean | No | true | On a cryptographic key error, invalidate the cache and fetch the key once more |
| invalidateCacheOnValidationError | boolean | No | - | Invalidate the cached key when validation fails |
| httpRetrySettings | object | No | - | Retry settings for the key-fetch HTTP call itself (see RetrySettings Object) |
httpRequest fields:
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| endpointUrl | string | No* | - | Full endpoint URL (endpointUrl or baseUrl is required) |
| baseUrl | string | No* | - | Base URL, used when endpointUrl is relative |
| httpMethod | string | No | - | HTTP method of the key request |
| headerList | array | No | [] | Request headers as { "name": "...", "value": "..." } |
| parameterList | array | No | [] | Query parameters as { "name": "...", "value": "..." } |
| bodyType | string | No | - | NONE, RAW, FORM_DATA, URL_ENCODED or BINARY |
| requestBody | string | No | - | Raw request body (used when bodyType=RAW) |
| formDataList | array | No | [] | Form-data fields (key, value, fieldType, fileName, contentType) |
| urlEncodedList | array | No | [] | x-www-form-urlencoded fields, same shape as formDataList |
| timeout | integer | No | - | Request timeout in seconds |
RetrySettings Object (httpRetrySettings):
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| enabled | boolean | No | false | Enable retry for the key request |
| retryCount | integer | No | 0 | Additional attempts after the first one |
| retryDelayType | string | No | NO_DELAY | NO_DELAY, FIXED or EXPONENTIAL |
| retryFixedDelayMs | integer | No | 500 | Fixed wait before each retry |
| retryInitialDelayMs | integer | No | 500 | Wait before the first retry (EXPONENTIAL) |
| retryMaxDelayMs | integer | No | 10000 | Upper bound for the growing wait |
| retryBackoffMultiplier | number | No | 2.0 | Growth factor per step, must be greater than 1 |
| retryOnStatusCodeList | array | No | [502, 503, 504] | HTTP status codes that trigger a retry |
| retryNonIdempotent | boolean | No | false | Allow retry for POST/PATCH on server responses |
retryOnKeyError and httpRetrySettings are different layers. retryOnKeyError clears the cached key and fetches it once more when the key itself is cryptographically unusable; httpRetrySettings retries the key request when it fails at the network level. Both can be enabled together — each fetch stays within its own retry limit.
Certificate and mTLS settings of the key request are not carried over the APIops API. They hold installation-specific secret material or ID references, so they are configured on the target installation; when an existing policy is updated, its current values are preserved.
Example — fetching the signing key over HTTP with cache and retry:
{
"name": "jose-dynamic-key-example",
"sign": true,
"signByIssuer": false,
"jwkIdForValidationAndSign": null,
"dynamicKeyForValidationAndSign": {
"keySourceMode": "DYNAMIC_HTTP",
"httpRequest": {
"endpointUrl": "https://idp.example.com/.well-known/jwks.json",
"httpMethod": "GET",
"headerList": [
{ "name": "Accept", "value": "application/json" }
],
"parameterList": [],
"bodyType": "NONE",
"timeout": 10
},
"keyExtractionVariable": {
"type": "BODY",
"bodyExpression": "$.keys[0]"
},
"keyFormat": "JWK_JSON",
"keyAlgorithm": "NONE",
"keyKid": "signing-key-1",
"enableCache": true,
"cacheByVariable": {
"type": "CONTEXT_VALUE",
"contextValue": "API_PROXY_NAME"
},
"keyCacheTtl": 3600,
"keyCacheCapacity": 100,
"keyRespectCacheInvalidationHeaders": true,
"keyCacheStorageType": "DISTRIBUTED",
"keyCacheConnectionTimeout": 3,
"keyCacheErrorHandlingType": "CONTINUE",
"retryOnKeyError": true,
"httpRetrySettings": {
"enabled": true,
"retryCount": 2,
"retryDelayType": "EXPONENTIAL",
"retryInitialDelayMs": 500,
"retryMaxDelayMs": 10000,
"retryBackoffMultiplier": 2.0,
"retryOnStatusCodeList": [502, 503, 504],
"retryNonIdempotent": false
}
}
}
In this example the key is fetched from a JWKS endpoint and cached for an hour. If the endpoint cannot be reached, the request is retried up to two more times with an exponentially growing wait. If the fetched key later turns out to be cryptographically unusable, retryOnKeyError clears the cache and fetches it once more.
EnumJoseTarget
BODY- JOSE token is in request/response bodyAUTHORIZATION_HEADER- JOSE token is in Authorization headerCHOOSE_FROM_VARIABLE- JOSE token location is specified by variable (requiresjoseTargetVariable)
EnumJoseUserSourcePart
HEADER- Extract client information from JOSE headerCLAIMS- Extract client information from JOSE claims (default)VARIABLE- Extract client information from variable (requiresclientSourceVariable)
EnumJoseStripAndDecode
NONE- Do not strip or decode (default)ALL- Strip and decode all claimsPARTIAL- Strip and decode only specified claims (requiresjwtClaimsToDecode)
EnumTimeUnit
MILLI_SECONDS,SECONDS,MINUTES,HOURS,DAYS
EnumCacheErrorHandlingType
CONTINUE- When the DPoP replay cache is unreachable, allow the request (replay protection is skipped for that request)FAIL- When the DPoP replay cache is unreachable, reject the request
EnumJoseTarget (for decoded claims)
BODY- Place decoded claims in request/response bodyAUTHORIZATION_HEADER- Place decoded claims in Authorization headerCHOOSE_FROM_VARIABLE- Place decoded claims in variable (requiresdecodedClaimsTargetVariableForDataManipulation)
Note
- If
joseTarget: CHOOSE_FROM_VARIABLE,joseTargetVariableis required. - If
clientSourcePart: VARIABLE,clientSourceVariableis required. - If
validateSign: trueandvalidateByIssuer: false,jwkIdForValidationAndSignis required. - If
decrypt: trueanddecryptByIssuer: false,jwkIdForDecryptionAndEncryptionis required. - If
stripAndDecode: PARTIAL,jwtClaimsToDecodeis required. - If
decodedClaimsTargetForDataManipulation: CHOOSE_FROM_VARIABLE,decodedClaimsTargetVariableForDataManipulationis required.
VariableDTO
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| id | string | No | - | Variable ID (if referencing existing variable) |
| projectId | string | No | - | Project ID (if referencing existing variable) |
| name | string | No* | - | Variable name (required if id not provided) |
| description | string | No | - | Variable description |
| type | string | Yes | - | Variable type: HEADER, PARAMETER, BODY, CONTEXT_VALUES, CUSTOM |
| headerName | string | No* | - | Header name (required if type=HEADER) |
| paramType | string | No* | - | Parameter type: QUERY, PATH, FORM (required if type=PARAMETER) |
| paramName | string | No* | - | Parameter name (required if type=PARAMETER) |
| paramPath | string | No | - | Parameter path |
| formName | string | No | - | Form name (for form parameters) |
| xpathValue | string | No* | - | XPath value (required if type=BODY and content is XML) |
| jsonPathValue | string | No* | - | JSONPath value (required if type=BODY and content is JSON) |
| bodyJsonPath | string | No* | - | JSONPath value (alternative to jsonPathValue) |
| messageContentType | string | No* | - | Message content type: JSON, XML, FORM (required if type=BODY) |
| contextValue | string | No* | - | Context value (required if type=CONTEXT_VALUES) |
| zoneId | string | No | - | Zone ID (for date context values) |
| initWithScript | boolean | No | false | Initialize with script |
| scriptLanguage | string | No | - | Script language: GROOVY, JAVASCRIPT (required if initWithScript=true) |
| scriptBody | string | No | - | Script body (required if initWithScript=true) |
EnumVariableType
HEADER- HTTP headerPARAMETER- Query/path/form parameterBODY- Request/response bodyCONTEXT_VALUES- Context values (e.g., current time, IP address)CUSTOM- Custom variable (script-based)
EnumVariableParameterType
QUERY- Query parameterPATH- Path parameterFORM- Form parameter
EnumMessageContentType
JSON- JSON contentXML- XML contentFORM- Form content
EnumVariableContextValue
CURRENT_TIME- Current timestampCURRENT_DATE- Current dateCLIENT_IP- Client IP addressCLIENT_PORT- Client portSERVER_IP- Server IP addressSERVER_PORT- Server portREQUEST_METHOD- HTTP request methodREQUEST_URI- Request URIREQUEST_PATH- Request pathREQUEST_QUERY_STRING- Query stringREQUEST_PROTOCOL- Request protocolREQUEST_HOST- Request hostREQUEST_SCHEME- Request schemeRESPONSE_STATUS_CODE- Response status codeRESPONSE_STATUS_TEXT- Response status textAPI_PROXY_NAME- API Proxy nameAPI_PROXY_ID- API Proxy IDENDPOINT_NAME- Endpoint nameENDPOINT_ID- Endpoint IDENVIRONMENT_NAME- Environment nameENVIRONMENT_ID- Environment IDPROJECT_NAME- Project namePROJECT_ID- Project IDUSER_NAME- User nameUSER_ID- User IDORGANIZATION_NAME- Organization nameORGANIZATION_ID- Organization IDZONE_ID- Zone IDTIMEZONE_ID- Timezone ID
EnumScriptType
GROOVY- Groovy scriptJAVASCRIPT- JavaScript script
MapValue
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| value | string | Yes | - | Claim value |
| valueType | string | No | STRING | Value type. See MapValueType |
MapValueType
STRING- String valueBOOLEAN- Boolean valueINTEGER- Integer valueLONG- Long valueDOUBLE- Double valueFLOAT- Float valueSTRING_LIST- String list (comma-separated)URI- URI value
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}
cURL Example
curl -X POST \
"https://demo.apinizer.com/apiops/projects/MyProject/apiProxies/MyAPI/policies/jose-validation-policy/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Validate JOSE tokens from request body",
"active": true,
"joseTarget": "BODY",
"clientSourcePart": "CLAIMS",
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi"],
"exactMatchClaimMap": {
"role": {
"value": "admin",
"valueType": "STRING"
}
},
"requiredClaimList": ["sub", "exp"],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"decrypt": true,
"decryptByIssuer": true,
"stripAndDecode": "NONE"
}
}'
Update Policy
Endpoint
PUT /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
| Content-Type | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Request Body
Full JSON Body Example
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": true,
"deployTargetEnvironmentNameList": ["production"],
"order": 1
},
"policy": {
"type": "policy-jose-validation",
"description": "Updated: Enhanced JOSE token validation with additional claims",
"active": true,
"joseTarget": "BODY",
"joseTargetVariable": null,
"clientSourcePart": "CLAIMS",
"clientSourceVariable": null,
"clientFieldname": "iss",
"acceptedAudienceList": ["api://myapi", "api://partners"],
"exactMatchClaimMap": {
"role": {
"value": "admin",
"valueType": "STRING"
},
"department": {
"value": "engineering",
"valueType": "STRING"
}
},
"requiredClaimList": ["sub", "exp", "iat", "jti"],
"prohibitedClaimList": ["debug_mode"],
"validateExpirationTime": true,
"validateSign": true,
"validateByIssuer": true,
"validateACLforIssuer": true,
"jwkIdForValidationAndSign": null,
"decrypt": true,
"decryptByIssuer": true,
"jwkIdForDecryptionAndEncryption": null,
"stripAndDecode": "NONE",
"jwtClaimsToDecode": null,
"decodedClaimsTargetForDataManipulation": "BODY",
"decodedClaimsTargetVariableForDataManipulation": null
}
}
Note: Request body structure is the same as Add Policy. All fields should be provided for update.
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": [
{
"environmentName": "production",
"success": true,
"message": "Deployment successful"
}
]
}
}
Delete Policy
Endpoint
DELETE /apiops/projects/{projectName}/apiProxies/{apiProxyName}/policies/{policyName}/
Request
Headers
| Header | Value |
|---|---|
| Authorization | Bearer {token} |
| Content-Type | application/json |
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| projectName | string | Yes | Project name |
| apiProxyName | string | Yes | API Proxy name |
| policyName | string | Yes | Policy name |
Request Body
Full JSON Body Example
{
"operationMetadata": {
"targetScope": "ALL",
"targetPipeline": "REQUEST",
"deploy": false
}
}
Response
Success Response (200 OK)
{
"status": "SUCCESS",
"deploymentResult": {
"success": true,
"deploymentResults": []
}
}
Notes and Warnings
-
JOSE Target:
BODY- Token is in request/response body (for POST/PUT requests)AUTHORIZATION_HEADER- Token is in Authorization header (standard Bearer token)CHOOSE_FROM_VARIABLE- Token location is dynamic (specified by variable)
-
Client Source Part:
CLAIMS- Extract client info from JWT claims (e.g., "iss" claim)HEADER- Extract client info from JOSE headerVARIABLE- Extract client info from a variable
-
Validation:
- Signature validation ensures token integrity and authenticity
- Expiration validation ensures token is not expired
- ACL validation ensures issuer is authorized
-
Decryption:
- JWE tokens must be decrypted before validation
- Decryption key can come from issuer credentials or proxy JWK
-
Strip and Decode:
NONE- Keep token as-is (default)ALL- Decode all claims and place in targetPARTIAL- Decode only specified claims
-
Claims Validation:
acceptedAudienceList- Validates "aud" claimexactMatchClaimMap- Validates exact claim valuesrequiredClaimList- Ensures required claims are presentprohibitedClaimList- Ensures prohibited claims are absent
-
JWK Management:
- When
validateByIssuer: true, uses issuer's JWK from credentials - When
validateByIssuer: false, uses proxy's JWK (requiresjwkIdForValidationAndSign) - Same logic applies for decryption (
decryptByIssuer)
- When
-
Performance: JOSE validation adds cryptographic processing overhead. Use for necessary security only.
-
Pipeline:
REQUESTpipeline validates incoming tokensRESPONSEpipeline validates outgoing tokens
-
Error Handling: Invalid token, expired token, or validation failure causes policy to fail
-
Deployment: Policy changes require deployment to take effect. Set
deploy: trueor deploy manually.
Related Documentation
- List Policies - List all policies
- Add Policy - General policy addition guide
- Update Policy - General policy update guide
- Delete Policy - General policy deletion guide
- JOSE Implementation Policy - Generate JOSE tokens