Token PASETO dapat melindungi claim secara kriptografis tanpa mengetahui apakah pengguna sudah logout. Batas ini lebih penting daripada sekadar membandingkan JWT dengan PASETO: mengganti format token tidak otomatis menghasilkan mekanisme revokasi sesi.

PASETO memberi setiap token version dan purpose yang eksplisit. Pada Version 4, v4.public menandatangani message dengan Ed25519, sedangkan v4.local mengenkripsi dan mengautentikasi message dengan symmetric cryptography. Pilihan tersebut menentukan siapa yang dapat membaca token serta siapa yang dapat membuat atau memverifikasinya. Pilihan itu tidak menentukan apakah token yang sebelumnya valid masih boleh diterima setelah state sesi berubah.

Public dan local menjawab kebutuhan yang berbeda

Token v4.public berguna ketika satu sistem menandatangani claim dan sistem lain memverifikasinya dengan public key. Payload-nya tidak terenkripsi.

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

Verifikasi dapat didistribusikan tanpa ikut menyebarkan signing key. Siapa pun yang memegang token tetap dapat membaca payload, jadi data rahasia tidak seharusnya dimasukkan hanya karena token sudah ditandatangani.

Token v4.local memakai trust model yang berbeda:

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

Payload dienkripsi sekaligus diautentikasi. Sebuah pihak memerlukan symmetric key untuk mendekripsinya. Konsekuensinya ada pada distribusi key: setiap komponen yang dapat mendekripsi token local juga memegang key material yang dapat membuat token valid. Pada token public, verifier cukup menerima public key dan tidak memperoleh kemampuan untuk menerbitkan token.

Dapat dibaca bukan berarti tidak ditandatangani

Confidentiality mudah tercampur dengan integrity. Misalnya access token membawa claim:

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

Pada v4.public, claim tersebut dapat dibaca. Signature mencegah perubahan tanpa terdeteksi ketika verifikasi dilakukan dengan benar; signature tidak menyembunyikan claim. Pada v4.local, claim yang sama terenkripsi.

Encryption dengan demikian ditentukan oleh kebutuhan perlindungan data, bukan sebagai pengganti authorization. Claim terenkripsi seperti "role": "admin" tetap memerlukan authorization policy yang benar di aplikasi penerima.

PASETO mempersempit negosiasi kriptografi

PASETO tidak meminta aplikasi memilih signing algorithm arbitrer dari setiap header token. Version dan purpose menentukan konstruksi protokol. Panduan implementasinya menyebut properti terkait sebagai algorithm lucidity: tipe key dan purpose token harus tetap dipisahkan secara logis.

Pada Version 4:

v4.public
  signing: Ed25519
  verification: Ed25519 public key

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

Pemisahan ini menghilangkan satu kelas pilihan kriptografi dari proses verifikasi token. Namun aplikasi tetap perlu memvalidasi issuer, audience, expiration, subject, dan operasi yang memang diizinkan. Token yang valid secara kriptografis masih dapat tidak valid untuk request tertentu.

Logout terjadi setelah token diterbitkan

Bayangkan access token diterbitkan pukul 10:00 dan berakhir pukul 10:15:

10:00  token diterbitkan
10:05  pengguna logout
10:10  token yang dicuri di-replay
10:15  token kedaluwarsa

Jika API hanya memeriksa kriptografi token dan expiration, token masih dapat lolos pada 10:10. Tidak ada informasi di dalam v4.public maupun v4.local yang memberi tahu verifier bahwa logout terjadi pada 10:05.

Ini adalah sifat self-contained bearer token. Verifier yang hanya memakai isi token hanya mengetahui informasi yang sudah ada ketika token dibuat. Event yang terjadi kemudian tidak dapat mengubah byte token secara retroaktif. Spesifikasi PASETO juga menegaskan bahwa format token tidak mencegah replay dengan sendirinya.

Access token berumur pendek membatasi stale window

Desain praktis membuat access token berumur pendek dan menyimpan state sesi yang dapat diperbarui di server:

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

Saat logout, aplikasi merevoke refresh atau session record. Access token yang sudah diterbitkan tidak langsung hilang, tetapi tidak dapat diperbarui setelah kedaluwarsa.

Batasnya menjadi jelas:

maximum stale authorization window ≈ sisa lifetime access token

Lifetime yang lebih pendek mengurangi exposure setelah logout atau credential theft, tetapi meningkatkan refresh traffic dan membuat clock, availability, serta perilaku refresh lebih penting secara operasional.

Refresh token tidak perlu membawa claim pengguna. Nilai opaque yang dibuat secara cryptographically random dapat menunjuk ke state di server:

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

Jika memungkinkan, menyimpan hash refresh token membatasi dampak ketika session store tidak sengaja terekspos.

Revokasi instan memerlukan state terkini

Jika logout harus langsung membuat access token tidak berlaku, verifier membutuhkan informasi yang dapat berubah setelah token diterbitkan.

Salah satu pola memasukkan session identifier ke token:

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

API memverifikasi PASETO, lalu mengecek apakah session masih aktif:

request
  ├── verify PASETO
  └── lookup sid
         ├── active  → lanjut
         └── revoked → tolak

Revokasi langsung berlaku, tetapi authorization tidak lagi sepenuhnya stateless.

Denylist memakai prinsip yang sama. Token dapat membawa identifier unik seperti jti, lalu identifier yang direvoke disimpan sampai token terkait seharusnya kedaluwarsa. Pola lain menyimpan security epoch untuk user atau session. Password reset, aksi “logout semua perangkat”, atau security event lain menaikkan epoch tersebut; token lama gagal pada pemeriksaan version di server.

Semua desain ini memperkenalkan state karena untuk mengetahui event yang terjadi setelah token diterbitkan, verifier membutuhkan jalur agar event tersebut dapat sampai kepadanya.

Key rotation bukan logout pengguna

Rotasi PASETO key dapat membatalkan token setelah verifier berhenti menerima key lama, tetapi granularitasnya biasanya salah untuk logout satu pengguna.

Jika ribuan pengguna memakai signing key yang sama, merotasi key untuk satu sesi dapat membatalkan ribuan token yang tidak terkait. Key rotation menangani lifecycle cryptographic key. Session revocation menangani lifecycle identitas aplikasi.

Perbedaannya juga membuat incident response lebih jelas:

satu session compromised → revoke session tersebut
semua session user compromised → revoke session user / naikkan epoch
signing key compromised → rotate key dan evaluasi token terdampak

Masing-masing memiliki blast radius yang berbeda.

Pilih purpose token dan kebijakan sesi secara terpisah

Keputusan desain yang berguna bukan sekadar “PASETO menggantikan JWT”. Ada dua pertanyaan yang independen:

Pertanyaan kriptografi:
  Apakah claim cukup ditandatangani dan dapat dibaca,
  atau harus terenkripsi?

Pertanyaan sesi:
  Seberapa cepat token harus berhenti berlaku setelah logout,
  account disablement, perubahan role, atau credential theft?

Gunakan v4.public ketika distributed verification penting dan confidentiality claim bukan persyaratan. Gunakan v4.local ketika payload harus tetap rahasia dan para pihak dapat mengelola symmetric key material dengan aman.

Setelah itu, rancang revocation secara terpisah. Access token berumur pendek ditambah refresh atau session record di server cocok ketika stale window kecil masih dapat diterima. Jika perubahan authorization harus berlaku seketika, tambahkan pemeriksaan session, denylist, epoch, atau state lain yang setara.

PASETO dapat membuat cryptographic envelope lebih sulit disalahgunakan. PASETO tidak dapat membuat verifier stateless mengetahui bahwa state di tempat lain berubah lima menit setelah token diterbitkan.