The Problem with JWT

JSON Web Tokens (JWT) are the most widely used token format on the web. They are also one of the most misused. The JWT specification (RFC 7519) is flexible by design — it supports multiple algorithms, multiple key types, and multiple serialization formats. This flexibility has produced a long history of security vulnerabilities, many of which are structural rather than implementation bugs.

For a typical web application session token, these issues are manageable with careful implementation. But for AI agent authorization proofs — tokens that serve as cryptographic evidence that a specific action was authorized by a specific owner at a specific time — the stakes are higher. A forged or manipulated proof token could authorize an agent to spend money, access sensitive data, or perform irreversible actions. The token format needs to be secure by default, not secure if configured correctly.

JWT's Structural Vulnerabilities

The security issues with JWT are well-documented and have been exploited repeatedly in production systems. The most critical are structural — they exist because of how the specification was designed, not because of implementation errors.

The alg Header Attack

JWT includes the signing algorithm in the token header. The verifier reads this header to determine how to verify the signature. This means an attacker can change the algorithm to one the verifier does not expect. The most famous variant: if a server uses RSA to sign tokens but the verifier also accepts HMAC, an attacker can take the server's RSA public key (which is public), use it as an HMAC secret to sign a forged token, and set alg: HS256. The verifier uses the "public key" as the HMAC secret, the signature validates, and the forged token is accepted.

The none Algorithm

The JWT specification includes an alg: none option that produces unsigned tokens. This was intended for contexts where the token integrity is guaranteed by other means (like TLS). In practice, many JWT libraries accepted none tokens by default, allowing attackers to strip the signature entirely and present an unsigned token that the verifier accepted as valid.

Key Confusion Attacks

JWT's support for multiple key types (symmetric and asymmetric) within the same verification flow creates confusion vulnerabilities. If a system is configured for asymmetric signing (RS256) but the library also supports symmetric verification, an attacker can exploit the overlap. These attacks are subtle and difficult to detect through code review alone.

Weak Default Configurations

Many JWT libraries ship with permissive defaults: accepting multiple algorithms, not validating expiration claims, allowing unsigned tokens in development mode. Each permissive default is a potential vulnerability in production. Securing JWT requires explicitly disabling features — a negative security model where forgetting a configuration option creates an exploit.

How PASETO Solves These Problems

PASETO (Platform-Agnostic Security Tokens) was designed explicitly to fix JWT's structural issues. Created by Scott Arciszewski in 2018, PASETO takes a different approach: instead of being flexible, it is opinionated. Instead of letting the developer choose (and potentially mischoose) algorithms, PASETO prescribes exactly one algorithm per version and purpose.

No Algorithm Negotiation

PASETO tokens do not contain an algorithm header. The version and purpose are encoded in the token prefix (e.g., v4.public), and each prefix maps to exactly one algorithm. There is no mechanism for an attacker to change the algorithm because the algorithm is not specified in the token — it is determined by the protocol version. The alg header attack is structurally impossible.

No none Option

PASETO does not have an unsigned token mode. Every token is either encrypted (local) or signed (public). There is no way to produce a valid PASETO token without a key. This eliminates an entire class of vulnerabilities by simply not offering the dangerous option.

Strict Purpose Separation

PASETO separates symmetric encryption (local) from asymmetric signing (public) at the protocol level. A v4.local token can only be verified with symmetric decryption. A v4.public token can only be verified with asymmetric signature verification. The key types cannot be confused because they use different token prefixes and different verification code paths.

Modern Cryptography

PASETO v4 uses Ed25519 for public tokens and XChaCha20-Poly1305 for local tokens. These are modern, well-analyzed primitives with strong security margins. There is no option to use SHA-1, RSA with PKCS#1 v1.5 padding, or any of the legacy algorithms that JWT supports and that have known weaknesses.

Why v4.public with Ed25519 for Agent Proofs

OpenLeash uses PASETO v4.public tokens for authorization proofs. This choice is driven by the specific requirements of AI agent authorization:

  • Offline verification. Counterparties (the services receiving agent requests) need to verify proof tokens without calling back to the authorization server. Public-key signatures enable this — anyone with the public key can verify, but only the key holder can sign.
  • Non-repudiation. A signed proof token is evidence that the owner's key authorized the action. Unlike symmetric tokens (where anyone who can verify can also forge), asymmetric tokens provide non-repudiation: the verifier cannot create fake proofs.
  • Performance. Ed25519 signatures are fast — roughly 50,000 signatures per second on modest hardware. Verification is even faster. For an authorization sidecar that evaluates every agent action, signature performance matters.
  • Small keys and signatures. Ed25519 public keys are 32 bytes. Signatures are 64 bytes. This keeps proof tokens compact, which matters when tokens are included in HTTP headers or passed between services.

What a Proof Token Looks Like

An OpenLeash proof token is a standard PASETO v4.public token. The payload contains the authorization decision, the action that was evaluated, constraints that were applied, and metadata for auditing:

PASETO v4.public proof token payload
{
"sub": "agent_01HQ3...", // agent ID
"iss": "openleash", // issuer
"iat": "2026-04-10T12:00:00Z", // issued at
"exp": "2026-04-10T12:05:00Z", // expires
"action": "payment.send", // authorized action
"decision": "ALLOW", // policy decision
"constraints": {
"max_amount": 50, // enforced limit
"currency": "USD"
},
"policy_ids": ["pol_spending_limit"]
}

The token is signed with the owner's Ed25519 private key. A counterparty receiving this token can verify the signature using the public key (available at GET /v1/public-keys) and confirm that the agent was authorized to send a payment of up to $50 USD. No trust in the agent itself is required — the trust is in the cryptographic signature.

Side-by-Side Comparison

Feature JWT PASETO v4
Algorithm in token Yes (alg header) No (fixed per version)
Unsigned tokens Yes (alg: none) Not possible
Key confusion risk Yes (sym/asym mixing) No (strict separation)
Signing algorithm RS256, ES256, HS256, etc. Ed25519 only (public)
Encryption JWE (complex, many options) XChaCha20-Poly1305 (local)
Security model Opt-in (disable unsafe) Secure by default

When JWT Is Still Appropriate

JWT is not universally bad. For web application session tokens in a controlled environment where you own both the issuer and the verifier, JWT with a pinned algorithm (e.g., ES256) and strict validation works fine. The ecosystem is mature, every language has libraries, and the interoperability is excellent.

The case for PASETO is strongest when tokens cross trust boundaries — when a token issued by one party is verified by a different party, when tokens serve as evidence rather than session state, or when the cost of a forged token is high. AI agent proof tokens meet all three criteria. The token issuer (OpenLeash) is different from the verifier (the counterparty). The token is evidence of authorization. And a forged token could authorize unauthorized spending, data access, or actions.

Further Reading

Learn more about how OpenLeash uses PASETO tokens in the PASETO proof tokens concept page. For a hands-on walkthrough, see our getting started guide. To understand the broader context of why agents need authorization, read why AI agents need authorization in 2026. For the full specification, visit the PASETO website.