Back to blog
July 12, 2026

PASETO Explained: How It Actually Works Under the Hood

An in-depth guide explaining how PASETO (Platform-Agnostic Security Tokens) works. Dive into version-locked cryptography, symmetric local encryption, asymmetric public signatures, and visual flowcharts.

PASETO Explained: How It Actually Works Under the Hood

Stateless authentication tokens are the backbone of modern web architecture. However, the industry-standard JSON Web Token (JWT) specification contains historical design oversights that put the burden of cryptographic security on the developer.

PASETO (Platform-Agnostic Security Tokens) was created as a secure-by-default alternative. Rather than letting the token dictate its own cryptographic verification rules, PASETO enforces strict, versioned standards that prevent configuration errors at the protocol level.

In this guide, we will unpack exactly how PASETO works, how it structures its data, and how the underlying symmetric and asymmetric flows operate.


The Core Problem with JWT: Algorithm Agility

To understand how PASETO works, we must understand what it fixes. The JWT standard uses algorithm agility, meaning the token header explicitly defines which cryptographic algorithm was used to sign or encrypt it:

{
  "alg": "HS256",
  "typ": "JWT"
}

If a server receives this token, its library parses the alg field and uses it to verify the signature. This design is highly flexible but fundamentally insecure:

  • Algorithm Confusion: Attackers can sign an asymmetric token (like RS256) using a symmetric algorithm (HS256) with the public key, tricking the server into validating the signature against its own public key.
  • Downgrade Attacks: Attackers can modify the header to "alg": "none", which insecure libraries might accept as valid without checking the signature.

PASETO eliminates algorithm agility entirely. There is no alg header. The version of the protocol defines the cryptography.


PASETO Version-Locked Cryptosuites

Every PASETO token declares its protocol version at the very beginning of the token string. As of 2026, Version 4 (v4) is the recommended standard.

Each version locks down a strict cryptographic suite:

Token HeaderCryptographic SuitePurpose
v4.localXChaCha20-Poly1305 (AEAD) + BLAKE2bSymmetric Authenticated Encryption
v4.publicEd25519 (EdDSA) + SHA-512Asymmetric Digital Signatures

You do not choose the hash size or signature curves; the version dictates them. If a vulnerability is found in Ed25519 in the future, the PASETO authors will release a new version (e.g., v5) with a new cryptosuite, and developers will migrate versions rather than changing raw algorithm strings.


The Structure of a PASETO Token

A PASETO token is a compact, URL-safe string containing up to four dot-separated parts:

$$\text \ . \ \text \ . \ \text \ . \ \text$$

v4.public.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZXhwIjoiMTgzMTg5OTAyMiJ9.b3B0aW9uYWwtZm9vdGVy
  1. Version (v4): The protocol version.
  2. Purpose (public or local): Defines whether the payload is signed plaintext (public) or encrypted (local).
  3. Payload: The Base64URL-encoded JSON claims (for public) or the raw ciphertext (for local).
  4. Footer (Optional): Base64URL-encoded unencrypted JSON metadata (like a Key ID kid for key rotation).

Detailed Cryptographic Workflows

Let's examine how both token purposes function.

1. Symmetric Flow (v4.local)

v4.local tokens prioritize confidentiality and authenticity. The client cannot read the claims. Only the party possessing the shared secret key can encrypt or decrypt the payload.

graph TD
    subgraph Token Encryption
        A[Payload Claims] --> B[Generate Random Nonce]
        B --> C[BLAKE2b Key Derivation]
        C --> D[XChaCha20-Poly1305 Encrypt]
        D --> E[Attach Version & Purpose Headers]
        E --> F[Base64URL Encoding]
        F --> G(v4.local.encryptedPayload)
    end

To verify and decrypt:

  1. The server splits the token by its periods to isolate the version, purpose, payload, and optional footer.
  2. It derives the encryption key using the shared secret and the nonce embedded in the payload segment.
  3. The server runs XChaCha20-Poly1305 decryption. If the token was tampered with in transit, the authentication tag validation fails, and the token is rejected.

2. Asymmetric Flow (v4.public)

v4.public tokens prioritize authenticity and non-repudiation. The payload remains visible (Base64URL-encoded JSON) but is digitally signed using a private key. Any service with the public key can verify that it was issued by the trusted identity provider.

graph TD
    subgraph Token Signing
        A[Payload Claims] --> B[Combine Header + Payload + Footer]
        B --> C[Ed25519 Sign with Private Key]
        C --> D[Append Signature to Payload]
        D --> E[Base64URL Encoding]
        E --> F(v4.public.payload.signature)
    end

To verify:

  1. The server decodes the signature and payload segments.
  2. It reconstructs the pre-signing structure (header, payload, and footer combined).
  3. The server uses the Ed25519 public key to verify the signature. If the signature matches, the server decodes the payload JSON to read the user claims.

Safe Offline PASETO Inspection

When developing and debugging PASETO authentication, it is highly useful to parse raw tokens to verify claim values and headers.

However, pasting production-grade tokens into third-party online decoders is a major security risk, as your user claims and metadata are sent over the network to a remote server.

FmtDev provides a secure, 100% Client-Side PASETO Decoder. Because it runs locally in your browser, no token data is ever transmitted, preserving absolute confidentiality.

Interactive Example
Local Execution
v4.public.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiZXhwIjoiMjAyNi0wNy0wNlQyMDoxNjowM1oifV83U21hcnRPZmZsaW5lRGVjb2Rlcg

Clicking will load this data into the tool locally.


Conclusion

PASETO replaces the dangerous flexibility of JWT with structured, version-locked cryptosuites. By removing algorithm negotiation, it neutralizes algorithm confusion attacks out of the box, offering a secure-by-default environment for modern web developers.

For a step-by-step implementation guide in Node.js, read our detailed developer guide on Implementing PASETO v4 in Node.js.

Herramienta Asociada

¿Listo para usar la herramienta Our Secure Tool? Todo el procesamiento es local.

Abrir Our Secure Tool