Automatic token revocation versus manual expiration checks for least‑privilege auth in Quarkus
0 reputation · 24 Sept 2021, 18:43 UTC
0 reputation · 24 Sept 2021, 18:43 UTC
The goal is to enforce least‑privilege authentication by denying requests that present expired credentials in a Quarkus service. Two documented paths exist: enabling the OIDC revocation check (quarkus.oidc.revocation.enabled) which contacts Keycloak’s token revocation endpoint, or relying on the stateless quarkus‑jwt extension to inspect the exp claim locally and reject the token without external calls.
Constraints include the added latency and possible throttling of network round‑trips to the revocation service, versus the risk that a manual exp check may allow a short window of stale privilege if the token is cached by intermediaries or if Keycloak’s revocation list is not immediately consistent across its cluster. Developers must also consider how distributed caches or offline tokens affect the reliability of the revocation flag. Which approach provides tighter least‑privilege guarantees under high‑latency or throttled network conditions? How does enabling quarkus.oidc.revocation.enabled impact throughput and response‑time variance in a production workload? What is the acceptable stale‑privilege window when relying solely on local exp validation, and can it be bounded by application‑level token caching policies?
35275 reputation · 24 Sept 2021, 23:02 UTC
Under high‑latency or throttled network conditions, relying on the stateless quarkus‑jwt to validate the exp claim locally provides more predictable latency and throughput, while automatic revocation (quarkus.oidc.revocation.enabled=true) adds variable network latency unless the revocation check is served from a low‑latency local cache.
exp claim by default (quarkus.jwt.enabled=true and quarkus.jwt.exp.validation=true). No extra code is needed.When network round‑trips to Keycloak are slow or subject to throttling, each request that performs an automatic revocation lookup incurs added latency and increases response‑time variance. This can reduce throughput, especially under bursty traffic. In contrast, the local exp check is a pure in‑memory operation with negligible and consistent overhead, giving tighter latency guarantees.
However, the local expiration check leaves a window where a stolen token remains usable until its natural expiry (plus any clock skew). This window can be bounded by issuing short‑lived access tokens (e.g., 5–15 min) and using secure refresh‑token rotation. Application‑level caching of revoked JTIs (with a TTL equal to the token’s remaining life) can further reduce the window without requiring a per‑request call to Keycloak.
quarkus.oidc.revocation.enabled=true and point to the Keycloak revocation endpoint.quarkus.cache.caffeine.revoked-tokens.enabled=true or a Redis datasource).@ApplicationScoped SecurityPolicy that extracts the JTI from the incoming JWT and rejects the request if the JTI is present in the cache.exp - now).quarkus.jwt.enabled=true and the issuer/public‑key are configured.quarkus.jwt.exp.validation=true (default).Do you already have access to a low‑latency distributed cache (Redis or embedded Caffeine) that can be co‑located with the Quarkus service? If not, the automatic revocation path may introduce unacceptable latency, making the manual expiration approach the safer choice for least‑privilege under high‑latency or throttled conditions.
Use comments to ask for clarification. Post a solution as an answer.
6,940 reputation · 25 Sept 2021, 05:55 UTC
When relying on local exp claim validation in Quarkus, an intermediate proxy or CDN may cache a token past its effective revocation time, creating a stale‑privilege window that natural expiry alone cannot close. This window can be bounded by issuing access tokens with a short TTL (5–15 minutes) and pairing them with refresh‑token rotation, so privilege loss occurs within the token's lifetime rather than at natural expiry. Additionally, Quarkus 3.x moved several OIDC configuration properties; verifying quarkus.oidc.revocation.enabled and the associated endpoint URL against your exact version prevents silent fallback to default exp‑only validation. For workloads where network latency is unpredictable, combining local exp checks with application‑level JTI caching—updated on logout or admin revocation—offers a pragmatic middle ground without per‑request round‑trips.