# JWT

Sign, verify and decode JSON Web Tokens.

## Do things in JWT

Add a **JWT** step and choose what it does. Choose a row to see its fields.

- [Sign (create token)](https://docs.gorunner.io/apps/jwt#fields-f-sign): Create a signed JWT from a payload of claims.
- [Verify token](https://docs.gorunner.io/apps/jwt#fields-f-verify): Verify a JWT's signature (and expiry) and return its claims.
- [Decode (no verify)](https://docs.gorunner.io/apps/jwt#fields-f-decode): Decode a JWT's header and payload without verifying the signature.

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

**What changed in version 2?**

New steps use version 2.0.0. A step made before keeps 1.0.0 and works as it always has. The step’s panel shows its version at the top right. On an older step it reads **v1.0.0 · 2.0.0 available**: press it to choose the version.

In 2.0.0: **Verify** fails the step when a token doesn’t verify, and says why. To get a result instead, turn on **Return the result instead of failing**. Version 1.0.0 passes the step and returns `valid: false`.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, JWT is `pieceId: "jwt"` with the actions `sign`, `verify`, `decode`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

What each action does outside the run: `sign` pure, `verify` pure, `decode` pure. See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### JWT › Sign (create token)

Create a signed JWT from a payload of claims.

- **Payload (claims) · Optional**: JSON object of claims to embed in the token (such as {"userId": 42, "role": "admin"}).
- **Algorithm · Required**: Signing method for the token. Use HS256 with a shared secret, or an RS/PS/ES option with a key pair. Options: HS256 (HMAC-SHA256), HS384 (HMAC-SHA384), HS512 (HMAC-SHA512), RS256 (RSA-SHA256), RS384 (RSA-SHA384), RS512 (RSA-SHA512), PS256 (RSA-PSS-SHA256), PS384 (RSA-PSS-SHA384), PS512 (RSA-PSS-SHA512), ES256 (ECDSA-SHA256), ES384 (ECDSA-SHA384), ES512 (ECDSA-SHA512). Default: HS256 (HMAC-SHA256).
- **Secret · Optional**: Shared secret for HMAC algorithms (HS256/384/512). Shows when **Algorithm** is **HS256 (HMAC-SHA256)**, **HS384 (HMAC-SHA384)** or **HS512 (HMAC-SHA512)**.
- **Private Key (PEM) · Optional**: Private key in PEM format: RSA (PKCS#1/PKCS#8) for RS/PS, or EC for ES algorithms. Shows when **Algorithm** is **RS256 (RSA-SHA256)**, **RS384 (RSA-SHA384)**, **RS512 (RSA-SHA512)**, **PS256 (RSA-PSS-SHA256)**, **PS384 (RSA-PSS-SHA384)**, **PS512 (RSA-PSS-SHA512)**, **ES256 (ECDSA-SHA256)**, **ES384 (ECDSA-SHA384)** or **ES512 (ECDSA-SHA512)**.
- **Expires In (seconds) · Optional**: Optional. Adds an `exp` claim this many seconds from now, replacing any exp in the payload. Leave at 0 to add none: the token then never expires unless the payload carries its own exp. Default: 0.
- **Issuer (iss) · Optional**: Optional. Who created this token, such as your app or company name like "my-app".
- **Subject (sub) · Optional**: Optional. Who or what the token is about, such as a user ID like "user-42".
- **Audience (aud) · Optional**: Optional. Who the token is intended for, such as "mobile-app" or a website address.
- **JWT ID (jti) · Optional**: Unique token identifier.
- **Not Before (seconds from now) · Optional**: Adds an `nbf` claim; the token is invalid before now + this many seconds. Default: 0.
- **Key ID (kid header) · Optional**: Sets the `kid` JOSE header (which key to verify with).

### JWT › Verify token

Verify a JWT's signature (and expiry) and return its claims. The step fails when the token does not verify, unless Return the result instead of failing is on.

- **Token · Required**: The JWT to verify.
- **Algorithm · Required**: Signing method for the token. Use HS256 with a shared secret, or an RS/PS/ES option with a key pair. Options: HS256 (HMAC-SHA256), HS384 (HMAC-SHA384), HS512 (HMAC-SHA512), RS256 (RSA-SHA256), RS384 (RSA-SHA384), RS512 (RSA-SHA512), PS256 (RSA-PSS-SHA256), PS384 (RSA-PSS-SHA384), PS512 (RSA-PSS-SHA512), ES256 (ECDSA-SHA256), ES384 (ECDSA-SHA384), ES512 (ECDSA-SHA512). Default: HS256 (HMAC-SHA256).
- **Secret · Optional**: Shared secret for HMAC algorithms (HS256/384/512). Shows when **Algorithm** is **HS256 (HMAC-SHA256)**, **HS384 (HMAC-SHA384)** or **HS512 (HMAC-SHA512)**.
- **Public Key (PEM) · Optional**: Public key in PEM format: RSA for RS/PS, or EC for ES algorithms. Shows when **Algorithm** is **RS256 (RSA-SHA256)**, **RS384 (RSA-SHA384)**, **RS512 (RSA-SHA512)**, **PS256 (RSA-PSS-SHA256)**, **PS384 (RSA-PSS-SHA384)**, **PS512 (RSA-PSS-SHA512)**, **ES256 (ECDSA-SHA256)**, **ES384 (ECDSA-SHA384)** or **ES512 (ECDSA-SHA512)**.
- **Clock Tolerance (seconds) · Optional**: Leeway when validating `exp` / `nbf` to tolerate clock skew. Default: 0.
- **Ignore Expiration · Optional**: Accept the token even if its `exp` claim has passed. Off by default.
- **Expected Audience (aud) · Optional**: Optional. Reject the token unless its `aud` claim matches. This is what stops a token minted for another service from being accepted here. Leave blank to skip the check.
- **Expected Issuer (iss) · Optional**: Optional. Reject the token unless its `iss` claim matches, such as "my-app". Leave blank to skip the check.
- **Expected Subject (sub) · Optional**: Optional. Reject the token unless its `sub` claim matches, such as "user-42". Leave blank to skip the check.
- **Return the result instead of failing · Optional**: Off: a token that does not verify fails the step, so no later step acts on an unverified token. On: the step succeeds with valid: false and the reason in error, for a flow that branches on valid itself. Off by default.

### JWT › Decode (no verify)

Decode a JWT's header and payload without verifying the signature.

- **Token · Required**: The JWT to decode.

Source: https://docs.gorunner.io/apps/jwt
