Skip to main content
An API trigger’s key answers “is this call allowed to fire?” It says nothing about who made it. If you expose a workflow to a web app, a partner, or your own backend, you often need to know the actual end user — and you need that identity to be something the caller cannot forge. Verified Inputs lets a caller attach a JWT from an identity provider you’ve registered. Pinkfish verifies the signature, then hands the validated claims to your workflow as a _verified input.
Verified Inputs establishes who is calling. It does not change whose connections run — the workflow still executes with the trigger owner’s connections. See Tool Sharing and Identity.

How a call is authenticated

Two independent things travel on the request:
WhatHeaderAnswers
API keyX-API-KEY (or embedded in the webhook URL)Is this call allowed to fire this trigger?
JWTAuthorization: Bearer <jwt>Who is the end user making it?
The API key remains required. The JWT is additional. By default, verification is opportunistic: if a Bearer token is present and its issuer matches one of your registered providers, Pinkfish verifies it and injects the claims. If no token is present, the run proceeds without _verified. You can make it mandatory — see Requiring verification.

Registering a trusted identity provider

Go to Settings → Triggers and add a provider. Providers are scoped to your organization and can only be managed by an org admin.
FieldNotes
NameYour label for the provider.
IssuerMust exactly equal the iss claim in the tokens you mint.
AudienceSet by Pinkfish, not by you — always org:<your-org-id>. Mint your tokens with this aud.
JWKS URL or PEMExactly one. A JWKS URL is strongly preferred, since it supports key rotation. Must be HTTPS.
Subject claimWhich claim identifies the user. Defaults to sub.
Allowed algorithmsAsymmetric only. HS* and none are always rejected.
Max token ageHow old an iat may be. Defaults to 300 seconds.
Statusactive or disabled.
The audience is pinned to your organization on purpose. Because Pinkfish forces aud to org:<your-org-id>, a token minted for one organization cannot be replayed against another organization’s trigger. Your token issuer must set that exact aud value or verification fails with audience_mismatch.
Use the Test action on a provider to paste a sample JWT and see the resolved subject and claims before you wire anything up.

What the workflow receives

When verification succeeds, Pinkfish adds a top-level _verified key to the workflow’s inputs. Its value is the entire validated claim set — every claim the token carried, verbatim:
{
  "customerId": "acme-42",
  "_verified": {
    "iss": "https://auth.example.com/",
    "aud": "org:org_abc123",
    "sub": "user_9f2c",
    "email": "dana@example.com",
    "exp": 1782000000,
    "iat": 1781999700,
    "role": "admin"
  }
}
Branch on it like any other input — for example, use _verified.sub as the record owner rather than trusting a caller-supplied userId.
_verified cannot be spoofed. Pinkfish strips any caller-supplied _verified key from the inputs of every run-creation path — API, schedule, email, manual, and bulk — before it re-adds a genuinely verified one. A workflow default cannot reintroduce it either. If the key was present, the attempt is logged.So inside a workflow, the presence of _verified always means a real token verified against one of your registered providers.
Each run also records three immutable audit fields, surfaced as a “Verified caller” badge in the run details: whether a JWT was presented, the verified subject, and which provider validated it.

Requiring verification

Opportunistic verification means an unauthenticated caller still runs the workflow — just without _verified. To reject those calls outright, turn on requireVerifiedRequest for the trigger. The request is then refused before any run is created. Turn on Require verified request“Reject API requests that lack a verified Trusted-IdP identity (JWT). Off by default.” You’ll find it:
  • On a workflow API trigger, in the trigger editor alongside the API key fields.
  • On an agent API channel, in the agent editor’s Channels section.
It can also be set through the API — it’s a requireVerifiedRequest field on the trigger, and agent API channels have a dedicated endpoint (PUT /api/useragents/{userAgentId}/channels/api/require-verified-request).
If you rely on verified identity for authorization, you must turn this on. It is off by default, and while it is off a caller who simply omits the Authorization header gets a successful run with no _verified key at all — so a workflow that reads _verified.sub would see nothing rather than an error.

Failure responses

A token whose issuer matches a registered provider but which fails verification is always rejected with 401, whether or not verification is required. A missing token is rejected only when requireVerifiedRequest is on. Responses follow the OAuth bearer-token convention:
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer error="expired"
Content-Type: application/json

{ "error": "expired", "error_description": "JWT has expired" }
errorMeaning
verification_requiredThe trigger requires a verified request and none was presented.
unknown_issuerNo registered provider matches the token’s iss.
signature_invalidSignature does not verify against the provider’s keys.
audience_mismatchaud is not org:<your-org-id>.
expiredThe token’s exp has passed.
token_too_oldThe token’s iat exceeds the provider’s max token age.
algorithm_not_allowedThe signing algorithm is not in the provider’s allowed list.
invalid_tokenThe token is malformed.
A Bearer token whose iss matches no registered provider is ignored rather than rejected, so an unrelated Authorization header won’t break a trigger — unless requireVerifiedRequest is on, in which case it counts as “no verified identity presented.”

Where it applies

SurfaceVerified Inputs
Workflow API triggersYes — verify, inject _verified, optional enforcement.
Agent API channelsYes — the verified claims travel as metadata rather than workflow inputs.
Webhook triggersNo. Webhook deliveries authenticate by HMAC signature from the sending provider, so the JWT path is skipped and the payload is left untouched.
Schedule, email, app-event triggersNo JWT is verified. Any caller-supplied _verified is still stripped.

Relationship to A2A end-user connections

Both features verify a caller’s JWT against the same trusted-provider registry, but they do different things with the result.
  • Verified Inputs treats the identity as data. The run still executes with the trigger owner’s connections.
  • A2A end-user connections treat the identity as an execution principal. Each external caller resolves connections against their own account, and the call is rejected if no verified identity is presented.
Reach for Verified Inputs when you want the workflow to know who asked. Reach for A2A end-user connections when each caller must act as themselves against the third-party app.