A PASETO token can protect claims cryptographically without knowing whether the user has logged out. That boundary matters more than the usual JWT-versus-PASETO comparison: changing the token format does not create session revocation.

PASETO gives each token an explicit version and purpose. With Version 4, v4.public signs a message with Ed25519, while v4.local encrypts and authenticates a message with symmetric cryptography. Those choices determine who can read a token and who can create or verify it. They do not determine whether a previously valid token should still be accepted after a session changes.

Public and local answer different questions

A v4.public token is useful when one system signs claims and other systems verify them with a public key. The payload is not encrypted.

issuer
  │ private key
v4.public token
  ├── service A ── public key ── verify
  └── service B ── public key ── verify

Verification can be distributed without distributing the signing key. Anyone holding the token can still read its payload, so confidential data does not belong there merely because the token is signed.

A v4.local token uses a different trust model:

application A ── shared secret ── application B
       │                              │
       └──── encrypt / decrypt ───────┘

Its payload is encrypted and authenticated. A party needs the symmetric key to decrypt it. The trade-off is key distribution: every component that can decrypt a local token also holds key material capable of creating valid tokens. With public tokens, a verifier can receive only the public key and cannot mint tokens.

Readable does not mean unsigned

It is easy to confuse confidentiality with integrity. Consider an access token carrying:

{
  "sub": "user_42",
  "aud": "billing-api",
  "exp": "2026-09-19T03:15:00Z",
  "role": "editor"
}

With v4.public, those claims are readable. The signature prevents undetected modification when verification is correct; it does not hide the claims. With v4.local, the same claims are encrypted.

Encryption is therefore driven by data-exposure requirements, not by authorization. An encrypted "role": "admin" claim still requires the receiving application to apply the correct authorization policy.

PASETO narrows cryptographic negotiation

PASETO does not ask applications to select an arbitrary signing algorithm from each token header. The version and purpose identify the protocol construction. Its implementation guide calls the related property algorithm lucidity: key types and token purposes should remain logically separated.

For Version 4:

v4.public
  signing: Ed25519
  verification: Ed25519 public key

v4.local
  encryption: XChaCha20
  authentication: keyed BLAKE2b
  key: 256-bit symmetric key

This removes a class of cryptographic choices from token verification. It does not remove application-level validation of issuer, audience, expiration, subject, or intended operation. A cryptographically valid token can still be invalid for a particular request.

Logout happens after the token was issued

Suppose an access token is issued at 10:00 and expires at 10:15:

10:00  token issued
10:05  user logs out
10:10  stolen token is replayed
10:15  token expires

If the API checks only the token’s cryptography and expiration, the token can still pass at 10:10. Nothing inside v4.public or v4.local tells the verifier that logout happened at 10:05.

This is a property of self-contained bearer tokens. A verifier working from the token alone only knows information encoded when the token was created. A later event cannot retroactively change those bytes. PASETO’s specification likewise notes that the format does not prevent replay by itself.

Short-lived access tokens bound the stale window

A practical design keeps access tokens short-lived and renewable session state on the server:

login
  ├── PASETO access token ── lifetime: 5–15 minutes
  └── opaque refresh token ── server-side session record

On logout, the application revokes the refresh or session record. The existing access token is not erased, but it cannot be renewed after expiry.

The resulting bound is simple:

maximum stale authorization window ≈ remaining access-token lifetime

A shorter lifetime reduces exposure after logout or credential theft, but increases refresh traffic and makes clock, availability, and refresh behavior more important operationally.

The refresh token does not need to contain user claims. A cryptographically random opaque value can point to server-side state:

rt_f4a8...random...
session store
{
  session_id,
  user_id,
  expires_at,
  revoked_at
}

Where practical, storing a hash of that refresh token limits the damage from accidental disclosure of the session store.

Immediate revocation requires current state

If logout must invalidate an access token immediately, the verifier needs information that can change after issuance.

One pattern puts a session identifier in the token:

{
  "sub": "user_42",
  "sid": "session_8c91",
  "exp": "2026-09-19T03:15:00Z"
}

The API verifies the PASETO and then checks whether the session is active:

request
  ├── verify PASETO
  └── lookup sid
         ├── active  → continue
         └── revoked → reject

Revocation becomes immediate, but authorization is no longer fully stateless.

A denylist follows the same principle. A token can carry a unique jti, and revoked identifiers remain in shared storage until the corresponding tokens would naturally expire. Another pattern stores a security epoch for the user or session. Password reset, “log out all devices,” or another security event increments that epoch; older tokens fail the server-side version check.

All of these designs introduce state because immediate knowledge of a later event requires a channel through which that event reaches the verifier.

Key rotation is not user logout

Rotating a PASETO key can invalidate tokens once verifiers stop accepting the old key, but that is usually the wrong granularity for one user’s logout.

If thousands of users share one signing key, rotating it for one session can invalidate thousands of unrelated tokens. Key rotation handles cryptographic key lifecycle. Session revocation handles application identity lifecycle.

The distinction also clarifies incident response:

one session compromised → revoke that session
all user sessions compromised → revoke user sessions / bump epoch
signing key compromised → rotate key and reassess affected tokens

Each event has a different blast radius.

Choose token purpose and session policy separately

The useful design decision is not simply “PASETO instead of JWT.” There are two independent questions:

Cryptographic question:
  Should claims be signed and readable, or encrypted?

Session question:
  How quickly must a token stop working after logout,
  account disablement, role changes, or credential theft?

Use v4.public when distributed verification matters and claim confidentiality is not required. Use v4.local when the payload must remain confidential and the parties can safely share symmetric key material.

Then design revocation independently. Short-lived access tokens plus a server-side refresh or session record work when a small stale window is acceptable. If authorization changes must take effect immediately, add a session, denylist, epoch, or equivalent state check.

PASETO can make the cryptographic envelope harder to misuse. It cannot make a stateless verifier know that state changed somewhere else five minutes after the token was issued.