Class: Clowk::Jwks
- Inherits:
-
Object
- Object
- Clowk::Jwks
- Defined in:
- lib/clowk/jwks.rb
Overview
Fetches and caches Clowk's public key set.
Keys are cached process-wide because verifying a token must not cost an
HTTP round trip. A kid the cache has never seen forces one refetch — that
is what makes key rotation invisible to consumers instead of an outage.
Constant Summary collapse
- CACHE_TTL =
600- WELL_KNOWN_PATH =
"/.well-known/jwks.json"- REFETCH_COOLDOWN =
Rotation should resolve in one refetch. Anything beyond that is a misconfigured issuer or a forged
kid, and hammering the auth server on every unverifiable token turns a bad token into an outage. 10
Class Method Summary collapse
- .clear_cache! ⇒ Object
- .default_url ⇒ Object
- .key_for(kid, jwks_url: Clowk.config.jwks_url) ⇒ Object
Class Method Details
.clear_cache! ⇒ Object
26 27 28 29 30 31 |
# File 'lib/clowk/jwks.rb', line 26 def clear_cache! @cache_mutex.synchronize do @cache = {} @last_refetch_at = {} end end |
.default_url ⇒ Object
50 51 52 53 54 55 56 |
# File 'lib/clowk/jwks.rb', line 50 def default_url base = Clowk.config.subdomain_url || Clowk::Subdomain.resolve_url! "#{base.to_s.chomp("/")}#{WELL_KNOWN_PATH}" rescue ConfigurationError raise ConfigurationError, "set jwks_url, subdomain_url or publishable_key to verify RS256 tokens" end |
.key_for(kid, jwks_url: Clowk.config.jwks_url) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/clowk/jwks.rb', line 33 def key_for(kid, jwks_url: Clowk.config.jwks_url) url = jwks_url || default_url key = lookup(url, kid) return key if key # Cold or expired cache: this is the ordinary first fetch, not a # rotation, so it must not spend the miss budget. Data is fresh # afterwards, so a miss here means the kid is genuinely unknown. return fetch_and_lookup(url, kid) unless warm?(url) # Warm cache and an unknown kid: the set may have rotated under us. return nil unless claim_refetch_slot!(url) fetch_and_lookup(url, kid) end |