Safeguard
Identity Security

PASETO tokens

PASETO tokens explained: what is PASETO, how PASETO vs JWT differs, and why platform-agnostic security tokens with versioned crypto are safer by design.

Aman Khan
AppSec Engineer
7 min read

PASETO (Platform-Agnostic Security Tokens) is a specification for cryptographically secure, stateless tokens designed as a purpose-built alternative to JSON Web Tokens (JWT). Created in 2018 by security researcher Scott Arciszewski of Paragon Initiative Enterprises, PASETO was built specifically to answer the question of what is PASETO's advantage over JWT: it removes the algorithm-negotiation flexibility that has caused years of real-world JWT vulnerabilities. Instead of letting a token specify which cryptographic algorithm should verify it — the root cause of "alg:none" and algorithm-confusion attacks — PASETO bakes the algorithm into a versioned protocol. Each token type (local for symmetric encryption, public for asymmetric signing) uses one fixed, modern cipher suite per version. The result is a secure token format that developers can implement without needing deep cryptographic expertise to avoid footguns. For engineering teams issuing session tokens, API credentials, or service-to-service auth claims, PASETO offers a drop-in, safer-by-default replacement for JWT-based identity systems.

What Is PASETO?

PASETO is a token format that pairs a fixed cryptographic recipe with a simple, versioned structure, rather than letting the token itself declare which algorithm to use. A PASETO token looks like v4.public.eyJz...signature, where the version (v1v4) and purpose (local or public) are encoded directly in the token header as plain, non-negotiable strings. This is the core design philosophy: because the parsing library — not the token — decides which algorithm applies to a given version and purpose, there is no way for an attacker to trick a server into accepting a token signed with a weaker or different algorithm than intended. JWT, by contrast, encodes the algorithm (alg) as a field inside the token header, which a verifier must read and trust before it even validates the signature. That single design decision is why PASETO exists at all: it takes an entire class of vulnerabilities off the table by construction rather than relying on developers to configure JWT libraries correctly every time.

How Does PASETO Differ from JWT?

PASETO differs from JWT primarily in what it refuses to let you configure. The PASETO vs JWT distinction comes down to flexibility versus safety: JWT supports a long menu of algorithms (HS256, RS256, ES256, PS256, and the notorious "none"), and a verifier must correctly restrict which algorithms it will accept — a step many implementations have historically gotten wrong. This produced well-documented incidents, such as libraries that accepted alg:none tokens as valid (effectively unsigned) or that could be tricked into verifying an HMAC-signed token using a public RSA key as the HMAC secret, a class of bug reported across multiple JWT libraries between 2015 and 2019. PASETO eliminates this attack surface by hard-coding one algorithm per version and purpose combination. A v4.public token is always Ed25519; there is no field to manipulate, no algorithm list to misconfigure, and no way to downgrade a signature check. The tradeoff is that PASETO is deliberately less flexible than JWT — you cannot mix and match ciphers — but for most authentication and authorization use cases, that inflexibility is precisely the point.

What Are the PASETO Token Versions?

PASETO currently defines four token versions, though only two are recommended for new systems. Version 1 used AES-256-CTR with HMAC-SHA384 for local tokens and RSASSA-PSS for public tokens, targeting environments restricted to NIST-approved, FIPS-compatible primitives. Version 2 replaced those with modern, misuse-resistant primitives: XChaCha20-Poly1305 for authenticated encryption and Ed25519 for signatures, both drawn from libsodium. Versions 1 and 2 are now considered legacy. Version 3 and Version 4 are the current, actively maintained PASETO token versions: v3 mirrors v1's NIST-compliant algorithm choices (AES-256-CTR, HMAC-SHA384, ECDSA with P-384) for organizations under compliance mandates requiring FIPS 140-2/140-3 validated cryptography, while v4 mirrors v2's Sodium-based primitives (XChaCha20-Poly1305, Ed25519, BLAKE2b) and is the recommended default for greenfield projects. A team building a new internal API in 2026 would almost always choose v4 unless a compliance requirement — say, a government contract mandating FIPS-validated modules — forces them onto v3. This versioning discipline is itself a security feature: rather than JWT's approach of adding new algorithms indefinitely, PASETO periodically retires and replaces entire version families as cryptographic best practice evolves.

Why Is PASETO Considered a More Secure Token Format?

PASETO is considered a more secure token format because it enforces authenticated encryption and eliminates ambiguity in how a token's authenticity is checked. Every local PASETO token is encrypted and authenticated as a single operation (AEAD), meaning the payload is confidential by default and any tampering — even a single flipped bit — causes decryption to fail outright rather than silently succeeding with corrupted data. JWT's equivalent, JWE, is rarely used in practice; most JWT deployments use plaintext-encoded JWS tokens where claims are base64-encoded but fully readable by anyone who intercepts them, and separate signature verification steps that have historically been skipped or misimplemented (for example, verifying only that a signature exists, not that it matches the expected key). PASETO also binds tokens to their intended context: the specification supports a mandatory "footer" for storing key IDs and optional "implicit assertions" (introduced in v3/v4) that bind a token to out-of-band context, such as a specific device fingerprint or client ID, without that context being visible inside the encrypted payload. A concrete example: a payments API can issue a v4.local token whose implicit assertion includes the merchant account ID; even if the token is somehow exfiltrated, replaying it against a different merchant context fails verification, because the assertion is checked cryptographically rather than trusted at read time.

How Does PASETO Work as a Platform-Agnostic Security Token?

PASETO works as a platform-agnostic security token because its specification, not any single library's implementation, defines exact byte-for-byte behavior for every version and purpose. The name itself — Platform-Agnostic Security Tokens — reflects this goal: a v4.public token generated by a Go service using paseto-go must be verifiable byte-for-byte by a PHP service using paragonie/paseto, a Rust service using rusty_paseto, or a Node.js service using paseto-js, because the spec pins the exact encoding, canonicalization, and cryptographic primitives rather than leaving them as implementation choices. This matters in real deployments where authentication tokens cross language boundaries — for instance, a mobile app's Swift client validating a token that was issued by a Python-based auth service, then passed through a Java-based API gateway before reaching a Go microservice. With JWT, subtle differences in how libraries handle key formats, algorithm allow-lists, or claim validation have caused interoperability bugs and security gaps across exactly these kinds of polyglot pipelines. PASETO's tighter specification reduces that surface area, making it a practical choice for organizations running heterogeneous service architectures where identity tokens must move reliably between independently maintained codebases.

How Safeguard Helps

Adopting a safer token format is only half the battle — the harder problem is knowing where every token-issuing and token-verifying service in your software supply chain actually lives, which libraries and versions they depend on, and whether any of them are still using deprecated algorithms or misconfigured verification logic. Safeguard gives security and platform teams visibility into exactly this: it inventories the cryptographic libraries and dependencies (PASETO, JWT, or otherwise) present across your codebase and build pipeline, flags outdated or vulnerable versions of token libraries before they ship, and helps enforce policy so that a service can't silently regress from a v4 PASETO implementation back to a legacy, weaker configuration. For teams migrating from JWT to PASETO, or standardizing on PASETO token versions across a polyglot service mesh, Safeguard's software composition analysis surfaces every transitive dependency that touches authentication, so that a token format decision made at the architecture level is actually reflected — and stays reflected — in every service that issues or verifies identity tokens across the supply chain.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.