← All posts

Elke tokenvalidering het ons oorsprong getref. Nou woon die JWKS op die rand.

Authagonal·July 20, 2026
authoidcjwkscdncloudflarecachingkey-rotation

Om een van ons JWTs te valideer, haal 'n diens twee publieke dokumente by die uitreiker: die discovery-dokument by /.well-known/openid-configuration, en die JWKS waarna dit wys — die stel publieke sleutels waarmee die tokens onderteken is. Dit is die mees-aangevraagde en mins-geheime dinge wat ons bedien. Dit is publieke sleutels, wat per definisie publiek is, en metadata wat net verander wanneer ons roteer. En tot onlangs het elkeen van daardie hale die hele pad terug na ons oorsprong gekom. Omdat ons multi-tenant is, was dit erger as wat daardie sin laat klink.

Die oorsprong het werk gedoen waarvoor daar geen rede was nie

Elke tenant is sy eie uitreiker, met sy eie .well-known-dokument en sy eie JWKS. En elke steunende party, elke hulpbronbediener, elke SDK wat 'n token valideer, trek daardie dokumente — met 'n koue begin, wanneer sy eie kort kas verval, een keer per diensinstansie. Vermenigvuldig uitreikers per tenant met valideerders per diens met kasmissers en jy kry 'n brandslang van versoeke, alles wat by die toepassing eindig, alles vir dokumente wat greep-vir-greep identies is vir elke oproeper en net verander wanneer ons 'n sleutel roteer.

Dit is die handboekprofiel van iets wat gekas behoort te word: publiek, identies, selde veranderend. In plaas daarvan het die toepassing publieke sleutels dinamies weergegee, op die warm pad van almal anders se tokenvalidering. Die sleutels het niks daar verloor om per versoek bereken te word nie.

Om hulle op die rand te plaas

Die verandering self is klein: stel eerlike Cache-Control-koptekste op die discovery- en JWKS-antwoorde sodat Cloudflare hulle op die rand kas. Nou tref 'n valideerder die naaste Cloudflare-teenwoordigheidspunt, en die oorsprong bedien elke dokument ongeveer een keer per PoP per TTL in plaas van een keer per validering. Discovery is triviaal kasbaar — dit verander byna nooit. Die JWKS is die een waaroor jy hard moet dink, want die JWKS is die een dokument wie se hele taak dit is om te verander presies wanneer jy 'n sleutel roteer, en om iets te kas wat vars moet wees op die een oomblik wanneer dit verander, is waar mense hulself seermaak.

Hoe 'n gekaste JWKS jou byt

Sleutelrotasie plus 'n gekaste sleutelstel is 'n slagyster, en dit misluk in die slegste moontlike rigting. Roteer na 'n nuwe ondertekeningsleutel, begin tokens daarmee uitreik, en 'n valideerder wat die JWKS gehaal het voordat die nuwe sleutel verskyn het, hou 'n verouderde kopie vas. 'n Token kom aan wat die nuwe sleutel se id dra; die valideerder soek dit op, kry dit nie, en verwerp die token. Die token is volkome geldig. Die handtekening is eg. Die gebruiker het niks verkeerd gedoen nie. Jou eie randkas het pas 'n 401 aan 'n wettige aanmelding teruggestuur.

Let op in watter rigting dit misluk. 'n Verouderde privaat sleutel is 'n nie-gebeurtenis — jy het bloot nog nie die nuwe een begin gebruik nie. 'n Verouderde publieke sleutelstel is 'n selftoegediende onderbreking, en jy het die kas wat dit veroorsaak het doelbewus ingevoer, om oorsprongverkeer te bespaar. Die veiligheid van die hele skema staan of val op rotasie.

Die rotasie-veilige patroon

Die veiligheid lê heeltemal in die volgorde, en die volgorde is die teenoorgestelde van 'n atomiese omruil. Drie reëls:

  • Publiseer voordat jy onderteken. Die nuwe sleutel gaan eers in die JWKS in, en jy onderteken nie 'n enkele token daarmee nie totdat daardie JWKS — nuwe sleutel-id en al — vir ten minste een volle kas-TTL op die rand lewend was. Teen die tyd dat enige token wat die nuwe sleutel dra 'n valideerder kan bereik, bevat die valideerder se gekaste sleutelstel reeds die sleutel.
  • Trek terug ná verval, nie by rotasie nie. Die ou sleutel bly in die JWKS gepubliseer totdat die laaste token wat dit ooit onderteken het, verval het. Oud en nuut bestaan saam vir die hele oorvleueling. Trek die ou sleutel die oomblik wat jy roteer, en jy strand elke token wat dit onderteken het wat nog geldig is.
  • TTL korter as die oorvleueling. Die randkas se max-age, plus 'n marge vir klokskeefheid, moet korter wees as die sleutel-oorvleuelingsvenster. Die kas mag verouderd wees; dit mag nooit langer verouderd wees as die venster waarin albei sleutels goed is nie. Daardie enkele ongelykheid is wat 'n aggressief-gekaste JWKS veilig maak.

Saamgestel word rotasie 'n crossfade met 'n vaste volgorde: voeg die nuwe sleutel by, wag 'n TTL sodat die rand en elke valideerder dit sien, begin daarmee onderteken, wag dat die ou tokens uitsterf, en laat dan die ou sleutel val. Elke stap is veilig teen 'n kas wat 'n TTL agter is, want die TTL is gekies om kleiner te wees as elke venster waarmee 'n kas agter kan wees.

Die les, gedistilleer

Kas is gewoonlik 'n latensie-besluit. Om publieke sleutels te kas is 'n korrektheidsbesluit, want die ding wat jy kas is die ding wat besluit watter tokens eg is. Jy kan dit beslis op die rand plaas — jy behoort, want dit is publiek en dit is warm — maar net sodra rotasie as 'n geordende oorvleueling in plaas van 'n omruil uitgedruk word, en net sodra die kas-TTL bewysbaar korter is as daardie oorvleueling. Kry dit reg en die besigste, mees kasbare dokumente in jou auth-stelsel raak nie meer aan jou oorsprong nie, en niemand merk ooit die verskil nie — wat presies die punt is.