mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-20 03:22:18 +00:00
docs(object-data-cache): state the correctness boundary and timing channel (#4695)
docs(object-data-cache): state the correctness boundary and the timing channel The crate doc still described itself as "a minimal skeleton for the initial rollout phase", which stopped being true several releases ago, and neither the crate nor the operator-facing env constant said anything about what the cache does or does not guarantee. Record two things a reader has to know. The correctness boundary: a hit is sound because the key matched metadata the caller just resolved from a read quorum, not because invalidation ran. Process-local invalidation is hygiene that frees capacity; the key is what keeps a stale body from being served. Anyone tempted to weaken the key should meet this sentence first. The timing side channel: a hit skips the erasure read, bitrot verify and decode, so it is reliably faster than a miss. A principal authorized to read an object can time a single GET and learn whether someone read that object within the entry's lifetime. This crosses no authorization boundary — the probe needs read access to that exact object, checked before the cache is consulted — but it does disclose a co-tenant's recent access pattern. Say so where operators look: on RUSTFS_OBJECT_DATA_CACHE_ENABLE. Timing noise would cost precisely the latency the cache exists to save, so the mitigation is to leave the cache off for buckets where access-pattern confidentiality matters. Refs: backlog#1139 Co-authored-by: heihutu <heihutu@gmail.com>
This commit is contained in:
@@ -118,6 +118,25 @@ pub const ENV_OBJECT_SEEK_SUPPORT_THRESHOLD: &str = "RUSTFS_OBJECT_SEEK_SUPPORT_
|
||||
pub const DEFAULT_OBJECT_SEEK_SUPPORT_THRESHOLD: usize = 10 * 1024 * 1024;
|
||||
|
||||
// Object data cache configuration
|
||||
|
||||
/// Enables the in-memory object body cache, which serves whole-object GET
|
||||
/// responses without an erasure read.
|
||||
///
|
||||
/// # Timing side channel
|
||||
///
|
||||
/// A cache hit skips the erasure read, bitrot verification and decode, so it is
|
||||
/// reliably faster than a miss. Any principal authorized to read an object can
|
||||
/// therefore infer, by timing a single GET, whether *someone* read that object
|
||||
/// within the entry's lifetime (see `RUSTFS_OBJECT_DATA_CACHE_TTL_SECS` and
|
||||
/// `..._TIME_TO_IDLE_SECS`).
|
||||
///
|
||||
/// This never crosses an authorization boundary — the probe requires read
|
||||
/// access to the exact bucket and object, checked before the cache is consulted
|
||||
/// — but it does disclose co-tenants' recent access patterns on objects the
|
||||
/// observer may already read. Leave the cache disabled where access-pattern
|
||||
/// confidentiality matters, such as a bucket shared read-only between competing
|
||||
/// tenants. Timing noise is not a viable mitigation: it would cost exactly the
|
||||
/// latency the cache exists to save.
|
||||
pub const ENV_OBJECT_DATA_CACHE_ENABLE: &str = "RUSTFS_OBJECT_DATA_CACHE_ENABLE";
|
||||
pub const ENV_OBJECT_DATA_CACHE_MODE: &str = "RUSTFS_OBJECT_DATA_CACHE_MODE";
|
||||
pub const ENV_OBJECT_DATA_CACHE_MAX_BYTES: &str = "RUSTFS_OBJECT_DATA_CACHE_MAX_BYTES";
|
||||
|
||||
Reference in New Issue
Block a user