JWT authentication in a Request-Response Ultra pipeline

Use the JWT Validate Snap at the start of a low-latency (request-response) Ultra Task pipeline to authenticate the token that a caller presents to the Ultra Task URL, before the pipeline processes the request.

This example builds a low-latency (request-response) Ultra Task pipeline that authenticates each caller with a JSON Web Token (JWT) instead of the task's built-in Bearer Token: the JWT Validate Snap validates the token the caller presents before the pipeline processes the request. Ultra Tasks support this JWT-based access control natively — instead of a single Bearer Token, the caller presents a JWT that the pipeline validates, which enables fine-grained access control (for example, allowing only tokens issued for a specific audience) and supports multiple tokens per task. This example shows how to authenticate the incoming token in a low-latency (request-response) Ultra Task.

Note: Ultra Tasks pass the incoming Authorization header to the pipeline, so the caller can present the JWT in that header. This pattern is specific to Ultra Tasks.

How the token reaches the pipeline

In a low-latency Ultra Task with a document input view, the FeedMaster places the incoming HTTP request headers in the root of the input document (header keys are lowercased) and the request body in the content field. If the caller sends the JWT in the Authorization header, the pipeline reads it from $authorization. For the input and output view requirements, refer to Pipeline requirements for Ultra Tasks.

When you create the low-latency Ultra Task, clear the Bearer Token field. SnapLogic auto-generates a token in this field, so you must delete the generated value to leave it empty. On an Ultra Task with no bearer token, the platform does not perform its own token check and passes each request to the pipeline — so authentication is not skipped, it is handled inside the pipeline by the JWT Validate Snap. Because the Snap is then the only authentication gate, design the pipeline so it validates the token before any other processing and returns an error status for any request whose token fails validation.

Important: Clearing the Bearer Token removes the platform's built-in authentication for this task. Make sure the pipeline validates every request, as described in the following steps, so the endpoint is not left open. Build and test the validation logic in the pipeline first, and create the Ultra Task with the cleared Bearer Token only after you confirm the pipeline rejects invalid, expired, and wrong-audience tokens.
  1. Insert the JWT Validate Snap between the pipeline's input view and the Snap that builds the response (a Mapper Snap in this example), so it is the first Snap that processes each request.

    A minimal low-latency Ultra Task pipeline has its input view connected directly to a response-building Snap (see the example pipelines in Low-latency Ultra Tasks). Drag a JWT Validate Snap onto the canvas between them, then reconnect the views: link the pipeline's input view to the new Snap's input view, and the new Snap's output view to the downstream Snap's input view — replacing the link that previously went directly from the pipeline's input.

    The JWT Validate Snap uses a single document input view and a single document output view by default, so no view configuration is needed beyond this rewiring. Because it is now first in the pipeline, its input view receives the same request document the pipeline itself receives (headers at the root, body in $content). Once validation succeeds, its output document contains the decoded JWT claims at the root, plus the original request nested under $original — including the request body in $original.content and the original headers (for example, $original.authorization). The Mapper Snap builds the response using both, as described in the following steps.

  2. Configure the JWT Validate Snap to read the token from the request.

    Click the expression toggle (=) next to the Access token field to put it in expression mode before you enter the expression below. The toggle looks like a small, easy-to-miss button next to the field, but it changes how the field behaves: in string (literal) mode, the Snap uses whatever text you type as the token itself instead of evaluating it, so the expression in this step is sent as a literal string and validation always fails, with no indication that the toggle is the cause.

    With the field in expression mode, set Access token to an expression that resolves to the bare token string. The Snap does not strip a Bearer prefix, so if the caller sends Authorization: Bearer <token>, remove the prefix in the expression. Referencing $authorization directly when the header is absent throws an evaluation error rather than resolving to an empty value, so check for the key first and match the prefix case-insensitively — for example, $.hasOwnProperty('authorization') ? $authorization.replace(/^Bearer\s+/i, "") : "". A request with no Authorization header then resolves to an empty string, which fails validation cleanly.

  3. Associate the Snap with a JWT Account that holds the key used to verify the token signature.

    On the Account tab of the Snap, set Account Reference to a configured JWT Account. This is required regardless of how the Access token field is configured. Without it, the pipeline fails to prepare. The error appears in the task's execution details, not in the response sent to the caller:

    Note: Account is required, please set in Account tab

    Because the pipeline never successfully prepares, callers see a sequence of errors instead of a clean rejection: an immediate 406 ("Ultra Task Queue not found"), then a 504 timeout after about 35 seconds, and finally 400 ("Cannot execute disabled task") once the task's Maximum Failures setting (default 10) disables it.

  4. Restrict access by validating claims.

    Configure the expected claims (for example, the audience) so the Snap allows only tokens that contain the required values. A token issued for a different audience fails validation. This is the same validation pattern shown in JWT Validate - Advanced Use Case. When validation succeeds, the Snap writes the decoded JWT claims to its output document, which downstream Snaps can use for further filtering.

    The Snap checks the token's signature, expiration, and configured audience, but not the issuer (iss) claim — a correctly signed, unexpired token with the right audience validates regardless of its issuer. The signing key and the configured audience are the actual access boundary; do not rely on iss to restrict which callers a token is valid for.

  5. Process the request and return the response.

    After validation, the downstream Mapper Snap (or additional Snaps you add after it) performs the request's work, using the original request body and headers under $original, as described above, and, if useful, the validated claims — for example, mapping $sub into the response to identify the authenticated caller. Because a request-response Ultra pipeline must produce exactly one output document per input request, map the response body to the $content field, any custom response headers to the root $, and the HTTP status code to the $status field of the output document.

    Return an error status for requests whose token fails validation: connect the JWT Validate Snap's error view to a Snap that maps a rejection response (for example, $status set to 401), and leave that Snap's own output view unconnected so it becomes a second output view for the pipeline, separate from the Mapper Snap's output view used by the success path. A low-latency Ultra pipeline supports one or more output views (refer to Pipeline requirements for Ultra Tasks), and because a given request only ever reaches one of the two views — success or rejection — the pipeline still returns exactly one output document per request. Without this second output view, a failed validation does not fail cleanly: the caller receives HTTP 200 with the Snap's own error document — including a stack trace, the failure reason and resolution, Snap build details, and an echo of the request down to the server and client IP addresses — instead of a rejection. The rejection output view is required both to return 401 for a failed validation and to avoid exposing these internal error details to the caller.

The Ultra Task authenticates each caller by validating the JWT presented in the request before processing it. Only requests with a valid token that satisfies the configured claims receive a successful response.

Generate a test token and call the task

To exercise the pipeline, sign a test token with the same key the JWT Validate Snap's Account uses, then send it to the task's HTTP endpoint.

The JWT Validate Snap and the JWT Generate Snap use the same JWT Account type, so the simplest way to generate a token that validates is to reuse that same Account (or one with the same key) in a JWT Generate Snap:

  1. In the Account, set Secret type to Secret Key with a plain string secret — simpler for testing than a KeyStore file.
  2. In a throwaway pipeline, add a JWT Generate Snap using that Account. Set Audience to the same value configured on the JWT Validate Snap. Leave the epoch fields blank to use the current time and the Account's Token TTL.
  3. Run the Snap and copy the token string from its output document.

Then call the task as described in Invoke Ultra Tasks, passing the token in the Authorization header:

curl -k -H 'Authorization: Bearer <token>' \
  https://<feedmaster>/api/1/rest/feed-master/queue/<org>/<project_space>/<project>/<task_name>

Because you cleared the Ultra Task's own Bearer Token field, the FeedMaster does not check this header itself — it passes the request straight through. The header still arrives at the pipeline, lowercased at the root of the input document as $authorization, which is what the expression in the token-reading step strips the Bearer prefix from before handing it to JWT Validate .

Option: also validate the token at the API gateway

In-pipeline validation with the JWT Validate Snap keeps authentication self-contained in the pipeline and requires no additional products, which suits a self-managed Groundplex where you control the pipeline design. If you use API Management, you can add the JWT Validator rule at the gateway as well. The two operate at different layers and can work together: the gateway rule rejects unauthorized requests before the pipeline runs and can extract claims into request headers, while the in-pipeline Snap validates the token within the pipeline itself. The gateway does not forward the original token to the pipeline by default.

To let the in-pipeline Snap validate the same token, add a Headers to add entry to the JWT Validator rule that maps a header (for example, Authorization) to the extracted token, $token. Without that configuration, $authorization is empty in the pipeline and the expression from the preceding steps has no token to validate. Gateway validation also centralizes authentication across APIs and integrates with the Developer Portal Try it out feature. You can use either layer on its own or both together for defense in depth.