The Passport Made of Three Parts
Mudrankar designed a new kind of travel passport that could be verified by any border guard without sending a message to the capital. The passport had three parts, separated by dots. The first described how the seal was made. The second held the traveller's claims: name, permitted kingdoms, issuer, and expiry. The third was the seal itself — a mathematical signature made by pressing the first two parts through the seal-maker's private signet ring. Any guard who knew the seal-maker's public seal could press the first two parts through it and compare the result to the third. If they matched, the passport was genuine. If one letter in the claims had been altered, the comparison would fail. The passport was self-verifying.
“A JWT is header.payload.signature — the signature binds the first two parts; altering any claim breaks the signature.”
The Forger and the Blank Seal
Mithyaka had obtained a legitimate passport from a minor clerk. She wanted to change the claim "permitted kingdoms: eastern-market" to "permitted kingdoms: royal-treasury." She scratched out the original claim and tried to affix a new seal. But without the seal-maker's private signet ring, her new seal did not match the public seal. Every guard rejected it. Then Mithyaka heard of a loophole: an old border post still accepted passports that carried the instruction "no-seal-required" in the header's seal-type field. She forged a passport with seal-type: none. Some old guards accepted it. The fix: guards must never accept seal-type: none. The algorithm used must be checked against a whitelist of approved algorithms — the passport holder must not be able to nominate their own.
“Always validate the algorithm header against a server-side allowlist. Never allow "alg: none" to pass through.”
The Passport That Lived Forever
A merchant lost his passport at a river crossing. Six months later, the same passport was used at the northern border. It was still valid. Mudrankar had never put an expiry date in the "exp" claim — the passport had no end of life. Whoever found it could use it indefinitely. Mudrankar also had no way to revoke a specific passport before its expiry; the verification happened without contacting the capital, so a stolen passport could not be cancelled until it expired. The fix was a short lifespan on the main passport — one hour — with a separate, long-lived refresh token stored only in a secure, same-site cookie. The refresh token could be revoked. The main passport expired quickly enough that theft was limited.
“Set "exp" on every token. Use short access tokens with revocable refresh tokens, not long-lived access tokens.”
The Symmetric Key Shared With Every Province
Early in the system's life, Mudrankar used a symmetric signet — the same key both sealed and verified passports. To let border guards verify passports, he shared the signet with every border post. But border posts received many travellers. One post was compromised. The attacker now had the symmetric key. He could issue his own perfectly valid passports for anyone. With an asymmetric signet, Mudrankar's private key stayed only in the capital — only Mudrankar could seal new passports. Every border post had only the public seal, which could verify but not create. A border post compromise exposed the ability to verify, not the ability to forge.
“Prefer RS256 (asymmetric) over HS256 (symmetric) when multiple services verify tokens — distribute only the public key.”
What the Passport Should Never Carry
A young official heard about the self-verifying passport and had an idea: why not put everything inside it — the traveller's personal history, family records, tax status, and full biography? Verification would then need no other lookup. Mudrankar declined. The passport was carried by the traveller, visible to every border guard. Large passports were inconvenient. Sensitive data in a passport was at risk whenever the passport was inspected. The passport should carry only what was needed for access decisions: subject identifier, permissions, issuer, expiry. Anything else should be fetched from secure records using the identifier. The passport was a key. It was not the treasury.
“Keep JWT payloads small. Store sensitive data server-side; put only access-decision claims in the token.”
🪔 Deepak — the lamp of meaning · what this fable means in code
A JWT (JSON Web Token) is a base64url-encoded header.payload.signature. The header specifies the signing algorithm (use RS256 or ES256; never HS256 in distributed systems; never "alg: none"). The payload carries claims: "iss" (issuer), "sub" (subject), "aud" (audience), "exp" (expiry), "iat" (issued at). The signature is computed over header + payload using the server's private key. Verification uses only the public key. Always validate: algorithm allowlist, issuer, audience, and expiry. Set short "exp" values (15–60 minutes for access tokens). Use refresh tokens stored in HttpOnly, Secure, SameSite=Strict cookies — not localStorage. Never store sensitive PII in the payload. Implement token revocation for refresh tokens via a database check on refresh.

