--------------------------------------------------------------------------
 resource server profiles: stub,roles,nottlcache
--------------------------------------------------------------------------
Scenario: a signing key is compromised. The issuer publishes a replacement and
removes the compromised key from the JWK Set immediately. Tokens it signed are
already out there with an hour left to run.

1. A token signed with stub-key-1, one hour to live: GET /api/me -> 200
   jwks fetches: 0

2. Issuer rotates to stub-key-2 and retires stub-key-1.
{
    "message": "ok",
    "activeKid": "stub-key-2",
    "publishedKids": [
        "stub-key-2"
    ],
    "jwksFetches": 0
}

   Anyone fetching /jwks.json from this moment sees only stub-key-2.

3. From here the ONLY traffic is the leaked token. Nothing carries an unknown kid,
   so nothing forces a refresh. Whether the token keeps working is decided purely
   by whether the cached JWK Set expires.

   elapsed    leaked   jwksFetches
   t+0s       200      0
   t+30s      200      0
   t+60s      200      0
   t+90s      200      0
   t+120s     200      0
   t+150s     200      0
   t+180s     200      0
   t+210s     200      0
   t+240s     200      0
   t+270s     200      0
   t+300s     200      0
   t+330s     200      0
   t+360s     200      0
   t+390s     200      0
   t+420s     200      0
   t+450s     200      0

A row that flips to 401 is the cache expiring and the retired key going away.
A column of 200s is a resource server that has not noticed, and will not, until
something happens to bring it a token it cannot verify.
