Skip to main content

secure_gate/traits/
serializable_secret.rs

1//! Opt-in marker trait for safe, explicit Serde serialization of secrets.
2//!
3//! This trait acts as a deliberate security gate: it enables `Serialize` (and
4//! optionally `Deserialize`) implementations on secret wrapper types (`Fixed<T>`,
5//! `Dynamic<T>`, aliases) **only** when the inner type explicitly opts in.
6//!
7//! Requires the `serde-serialize` feature.
8//!
9//! # Security Properties
10//!
11//! - **No automatic exposure** — Serialization is impossible unless the inner type
12//!   implements `SerializableSecret`.
13//! - **Explicit risk acceptance** — Cloning/serialization increases the chance of
14//!   secret leakage (e.g., via logs, network, disk). This marker forces developers
15//!   to acknowledge and accept that risk.
16//! - **Zeroization preserved** — Serialization does **not** bypass `ZeroizeOnDrop`;
17//!   all copies zeroize on drop.
18//! - **No deserialization by default** — `Deserialize` is **not** automatically
19//!   enabled; use `serde-deserialize` feature + manual impl if needed.
20//!
21//! # When to Use
22//!
23//! Implement `SerializableSecret` **only** when serialization is **truly necessary**:
24//!
25//! - Encrypted backups of keys/tokens
26//! - Secure export for cross-process or cross-device transfer
27//! - Persistent storage in encrypted form
28//!
29//! Prefer **non-serializable designs** wherever possible:
30//! - Derive keys on-the-fly from a master secret
31//! - Use ephemeral in-memory secrets
32//! - Avoid persisting raw secrets at all
33//!
34//! # Example
35//!
36//! ```rust
37//! use secure_gate::{SerializableSecret, Fixed};
38//! use serde::{Serialize, Deserialize};
39//! use zeroize::Zeroize;
40//!
41//! #[derive(Serialize, Deserialize)]
42//! struct BackupKey(Vec<u8>);
43//!
44//! impl Zeroize for BackupKey {
45//!     fn zeroize(&mut self) { self.0.zeroize(); }
46//! }
47//!
48//! // Every impl is a deliberate security decision — audit all usages.
49//! impl SerializableSecret for BackupKey {}
50//!
51//! let key = Fixed::new(BackupKey(vec![0u8; 32]));
52//! // Serialization exposes the secret — encrypt/authenticate output before storage.
53//! // let bytes = bincode::serialize(&key).unwrap();
54//! let _ = key;
55//! ```
56//!
57//! # Warnings
58//!
59//! - **Serialization exposes the secret** — treat serialized output as sensitive.
60//!   Encrypt, authenticate, and protect transmission/storage.
61//! - **Audit every impl** — ensure the inner type correctly implements `Serialize`
62//!   (and `Deserialize` if needed) and `Zeroize`.
63//! - **Prefer ephemeral secrets** — avoid persisting raw secrets when possible.
64//!
65//! This trait is a **marker only** — it has no methods and adds no runtime behavior.
66//! It exists solely to gate `Serialize` (and optionally `Deserialize`) on wrapper types.
67
68/// Marker trait that opts a secret type into serialization.
69///
70/// No methods — its only purpose is to gate the `Serialize` impl on
71/// [`Fixed<T>`](crate::Fixed) and [`Dynamic<T>`](crate::Dynamic).
72/// Requires the `serde-serialize` feature.
73#[cfg(feature = "serde-serialize")]
74pub trait SerializableSecret: serde::Serialize {}