Skip to main content

tako_rs_plugins/middleware/jwt_auth/
revocation.rs

1//! Token revocation list and remote introspection hooks.
2
3use std::future::Future;
4use std::pin::Pin;
5use std::sync::Arc;
6
7use scc::HashSet as SccHashSet;
8
9/// Token revocation list interface (sync because revocation is on the hot
10/// path and remote checks should go through a cache).
11pub trait RevocationList: Send + Sync + 'static {
12  fn is_revoked(&self, jti: &str) -> bool;
13}
14
15/// Default in-memory revocation list keyed by `jti` (JWT ID claim).
16#[derive(Default, Clone)]
17pub struct InMemoryRevocationList {
18  inner: Arc<SccHashSet<String>>,
19}
20
21impl InMemoryRevocationList {
22  pub fn new() -> Self {
23    Self::default()
24  }
25
26  pub fn revoke(&self, jti: impl Into<String>) {
27    let _ = self.inner.insert_sync(jti.into());
28  }
29
30  pub fn unrevoke(&self, jti: &str) {
31    let _ = self.inner.remove_sync(jti);
32  }
33}
34
35impl RevocationList for InMemoryRevocationList {
36  fn is_revoked(&self, jti: &str) -> bool {
37    self.inner.contains_sync(jti)
38  }
39}
40
41/// Optional remote introspection. Returns true when the token is still
42/// valid; false when it has been revoked / expired upstream.
43pub type IntrospectionFn =
44  Arc<dyn Fn(&str) -> Pin<Box<dyn Future<Output = bool> + Send + 'static>> + Send + Sync + 'static>;
45
46/// Closure that extracts a `jti` (or any revocation-list key) from the
47/// verifier's decoded claims. Required when wiring up [`JwtAuth::revocation`](super::JwtAuth::revocation).
48pub type JtiExtractorFn<C> = Arc<dyn Fn(&C) -> Option<String> + Send + Sync + 'static>;
49
50/// Pair of [`RevocationList`] and a JTI extractor used to wire revocation onto a verifier.
51pub type RevocationCheck<C> = (Arc<dyn RevocationList>, JtiExtractorFn<C>);