1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//! Scope-aware cache invalidation contract.
//!
//! Policy updates, role changes, and tenant suspensions need to reach
//! the authz hot-path cache so the new state takes effect at the next
//! request, not the next TTL expiry. TTL-only invalidation means
//! the cache may serve stale decisions for up to the configured TTL
//! window, which audit findings frequently flag as a control gap.
//!
//! This trait unifies "drop entries matching this scope" across the
//! in-process [`EntityCache`](super::EntityCache), the Moka decorator
//! ([`MokaEntityCache`](super::MokaEntityCache), if compiled in), and
//! the Valkey decorator
//! ([`ValkeyEntityCache`](super::ValkeyEntityCache), if compiled in).
//! Adopters can dispatch through `dyn CacheInvalidator` from policy-
//! update handlers without naming the concrete cache layer.
//!
//! # Scope semantics
//!
//! - [`invalidate_principal`](CacheInvalidator::invalidate_principal):
//! drop every entry whose `principal` field matches. Use when a
//! user's roles change, a token is revoked, or an account is
//! terminated.
//! - [`invalidate_tenant`](CacheInvalidator::invalidate_tenant):
//! drop every entry whose `tenant` field matches. Use when a
//! tenant's policy bundle is reloaded, membership shifts, or the
//! tenant is suspended.
//! - [`invalidate_all`](CacheInvalidator::invalidate_all): drop
//! every entry. Use for global policy reloads only: a multi-tenant
//! deployment paying this hammer on every change negates the cache.
//!
//! Implementations MAY treat scope invalidation as a no-op when the
//! cache backend cannot enumerate keys cheaply (e.g. a write-through
//! cache with no scan support). Adopters who need guaranteed scope
//! invalidation should pick a cache that supports it (the in-process
//! [`EntityCache`](super::EntityCache) does via
//! [`axess_cache::ClockTtlCache::invalidate_by`]).
use EntityUid;
use Future;
/// Scope-aware invalidation for an authz entity-resolution cache.
///
/// All methods are async because the Valkey decorator round-trips to
/// the cluster; in-process impls just return `Ok(())` synchronously.