Skip to main content

scp_platform/
encrypted.rs

1//! Sealed marker trait for storage backends that encrypt data at rest.
2//!
3//! [`EncryptedStorage`] is a sealed marker trait — only implementable inside
4//! `scp-platform`. External crates can see and require the trait, but cannot
5//! implement it for their own types. This prevents unencrypted backends from
6//! satisfying the bound.
7//!
8//! Production backends (`SqliteStorage`, `AppleStorage`) implement it directly.
9//! Custom backends that don't natively encrypt should be wrapped in
10//! [`EncryptingAdapter`](crate::encrypting_adapter::EncryptingAdapter), which
11//! adds per-value AES-256-GCM encryption and implements `EncryptedStorage`.
12//!
13//! # Why sealed?
14//!
15//! Encryption at rest is a security invariant, not a behavioral contract that
16//! external code can meaningfully promise. Sealing the trait ensures the
17//! compiler enforces the invariant — only code within `scp-platform` can vouch
18//! for a backend's encryption.
19//!
20//! See issue #695 and spec §17.5.
21
22pub(crate) mod private {
23    /// Supertrait seal — prevents external implementations of
24    /// [`EncryptedStorage`](super::EncryptedStorage).
25    pub trait Sealed {}
26}
27
28/// Marker trait for [`Storage`](crate::traits::Storage) backends that encrypt
29/// data at rest.
30///
31/// Sealed — only implementable inside `scp-platform`. External crates can
32/// require this bound but cannot implement it. Wrap custom backends in
33/// [`EncryptingAdapter`](crate::encrypting_adapter::EncryptingAdapter) to
34/// satisfy the bound.
35pub trait EncryptedStorage: crate::traits::Storage + private::Sealed {}
36
37// ---------------------------------------------------------------------------
38// Blanket impl for Arc<T> — matches the Storage blanket in traits.rs
39// ---------------------------------------------------------------------------
40
41impl<T: EncryptedStorage> private::Sealed for std::sync::Arc<T> {}
42impl<T: EncryptedStorage> EncryptedStorage for std::sync::Arc<T> {}
43
44// ---------------------------------------------------------------------------
45// Implementations for production backends
46// ---------------------------------------------------------------------------
47
48#[cfg(feature = "sqlite")]
49impl private::Sealed for crate::sqlite::SqliteStorage {}
50#[cfg(feature = "sqlite")]
51impl EncryptedStorage for crate::sqlite::SqliteStorage {}
52
53#[cfg(feature = "apple")]
54impl private::Sealed for crate::apple::storage::AppleStorage {}
55#[cfg(feature = "apple")]
56impl EncryptedStorage for crate::apple::storage::AppleStorage {}