commit 4aa834670f77f6559322ffcb5592e1d77965ad5d
parent 16aa639f5679535128d52f932d68c5079b65f15f
Author: triesap <tyson@radroots.org>
Date: Sat, 1 Aug 2026 09:51:26 +0000
secrets: add secret zeroization and leakage checks
- Own plaintext in fixed-length zeroizing buffers and zeroize rejected decrypted inputs.
- Move decrypted envelope and file material through the protected owner boundary.
- Add compile-fail, redaction, logging-leakage, and byte-access contract checks.
- Record and verify the reviewed all-feature public API baseline.
Diffstat:
6 files changed, 580 insertions(+), 12 deletions(-)
diff --git a/crates/secrets/src/envelope.rs b/crates/secrets/src/envelope.rs
@@ -225,7 +225,7 @@ impl EncryptedEnvelope {
)
.map_err(|_| Error::DecryptFailed)
})?;
- SecretMaterial::from_slice(plaintext.as_slice())
+ SecretMaterial::from_owned(plaintext)
}
/// Returns the authenticated provider reference.
diff --git a/crates/secrets/src/file.rs b/crates/secrets/src/file.rs
@@ -246,7 +246,7 @@ impl FileProvider {
)
.map_err(|_| Error::DecryptFailed)
})?;
- SecretMaterial::from_slice(plaintext.as_slice())
+ SecretMaterial::from_owned(plaintext)
}
fn persist_noclobber(&self, path: &Path, encoded: &[u8]) -> Result<(), Error> {
diff --git a/crates/secrets/src/wrapping.rs b/crates/secrets/src/wrapping.rs
@@ -7,7 +7,7 @@ use alloc::vec::Vec;
use core::fmt;
use core::future::Future;
use core::pin::Pin;
-use zeroize::Zeroize;
+use zeroize::Zeroizing;
/// Maximum plaintext accepted by the generic wrapping boundary.
pub const SECRET_MATERIAL_MAX_BYTES: usize = 64 * 1024;
@@ -22,7 +22,23 @@ pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
/// This type never implements `Clone` or `Serialize`, and its diagnostics are
/// always redacted. Callers must opt in to the narrow [`Self::expose_secret`]
/// scope when invoking cryptographic code.
-pub struct SecretMaterial(Vec<u8>);
+///
+/// ```compile_fail
+/// use radroots_secrets::wrapping::SecretMaterial;
+///
+/// let material = SecretMaterial::from_slice(b"secret")?;
+/// let _duplicate = material.clone();
+/// # Ok::<(), radroots_secrets::Error>(())
+/// ```
+///
+/// ```compile_fail
+/// use radroots_secrets::wrapping::SecretMaterial;
+///
+/// let material = SecretMaterial::from_slice(b"secret")?;
+/// let _json = serde_json::to_string(&material)?;
+/// # Ok::<(), Box<dyn std::error::Error>>(())
+/// ```
+pub struct SecretMaterial(Zeroizing<Box<[u8]>>);
impl SecretMaterial {
/// Copies caller-supplied material into a zeroizing owner.
@@ -33,12 +49,17 @@ impl SecretMaterial {
max_bytes: SECRET_MATERIAL_MAX_BYTES,
});
}
- Ok(Self(bytes.to_vec()))
+ Ok(Self(Zeroizing::new(Box::from(bytes))))
+ }
+
+ pub(crate) fn from_owned(bytes: Vec<u8>) -> Result<Self, Error> {
+ let bytes = Zeroizing::new(bytes);
+ Self::from_slice(bytes.as_slice())
}
/// Exposes plaintext only for the lifetime of an explicit closure call.
pub fn expose_secret<T>(&self, use_secret: impl FnOnce(&[u8]) -> T) -> T {
- use_secret(self.0.as_slice())
+ use_secret(&self.0[..])
}
/// Returns the plaintext length without exposing its contents.
@@ -60,12 +81,6 @@ impl fmt::Debug for SecretMaterial {
}
}
-impl Drop for SecretMaterial {
- fn drop(&mut self) {
- self.0.zeroize();
- }
-}
-
/// Opaque provider-wrapped material safe for persistence but not diagnostics.
#[derive(Clone, PartialEq, Eq)]
pub struct WrappedSecret(Vec<u8>);
@@ -164,3 +179,24 @@ pub trait KeyWrapping: Send + Sync {
request: UnwrapRequest<'a>,
) -> BoxFuture<'a, Result<SecretMaterial, Error>>;
}
+
+#[cfg(test)]
+mod tests {
+ use super::SecretMaterial;
+ use zeroize::Zeroize;
+
+ #[test]
+ fn owned_plaintext_buffer_zeroizes_in_place() {
+ let mut material =
+ SecretMaterial::from_slice(b"owned plaintext sentinel").expect("valid secret material");
+ let original_len = material.len();
+ material.0.zeroize();
+ assert_eq!(material.len(), original_len);
+ material.expose_secret(|bytes| assert!(bytes.iter().all(|byte| *byte == 0)));
+ }
+
+ #[test]
+ fn rejected_owned_plaintext_is_wrapped_before_validation() {
+ assert!(SecretMaterial::from_owned(Vec::new()).is_err());
+ }
+}
diff --git a/crates/secrets/tests/security_contract.rs b/crates/secrets/tests/security_contract.rs
@@ -0,0 +1,137 @@
+use radroots_secrets::envelope::{Nonce, SealMaterial, SealRequest};
+use radroots_secrets::error::{Operation, SecretIdError};
+use radroots_secrets::id::{BackendKind, KeyVersion};
+use radroots_secrets::wrapping::{SecretMaterial, WrappedSecret};
+use radroots_secrets::{Error, SecretId, SecretRef};
+use std::fs;
+use std::path::{Path, PathBuf};
+
+const PUBLIC_API: &str = include_str!("../../../docs/api/radroots_secrets.txt");
+
+#[test]
+fn reviewed_api_forbids_secret_bearing_clone_serialize_and_byte_access() {
+ for required in [
+ "pub mod radroots_secrets::envelope",
+ "pub mod radroots_secrets::error",
+ "pub mod radroots_secrets::id",
+ "pub mod radroots_secrets::provider",
+ "pub mod radroots_secrets::wrapping",
+ "pub struct radroots_secrets::wrapping::SecretMaterial(_)",
+ "pub struct radroots_secrets::id::SecretRef",
+ "pub trait radroots_secrets::provider::SecretProvider",
+ "pub trait radroots_secrets::wrapping::KeyWrapping",
+ ] {
+ assert!(
+ PUBLIC_API.contains(required),
+ "reviewed public API is missing `{required}`"
+ );
+ }
+
+ for secret_bearing_type in [
+ "radroots_secrets::wrapping::SecretMaterial",
+ "radroots_secrets::id::SecretRef",
+ "radroots_secrets::envelope::SealMaterial",
+ "radroots_secrets::envelope::SealRequest",
+ ] {
+ for forbidden_trait in ["core::clone::Clone", "serde_core::ser::Serialize"] {
+ let forbidden = format!("impl {forbidden_trait} for {secret_bearing_type}");
+ assert!(
+ !PUBLIC_API.contains(&forbidden),
+ "secret-bearing public type exposes forbidden trait: {forbidden}"
+ );
+ }
+ }
+
+ for forbidden in [
+ "SecretMaterial::as_bytes",
+ "SecretMaterial::as_slice",
+ "SecretMaterial::into_bytes",
+ "SecretMaterial::to_vec",
+ "SecretRef::clone",
+ ] {
+ assert!(
+ !PUBLIC_API.contains(forbidden),
+ "reviewed API exposes forbidden plaintext or duplication surface `{forbidden}`"
+ );
+ }
+}
+
+#[test]
+fn diagnostics_snapshot_is_redacted_and_plaintext_free() {
+ const SECRET_ID_SENTINEL: &str = "plaintext-secret-id-sentinel";
+ const PLAINTEXT_SENTINEL: &[u8] = b"plaintext-material-sentinel";
+
+ let id = SecretId::parse(SECRET_ID_SENTINEL).expect("valid secret id");
+ let reference = SecretRef::new(
+ id,
+ BackendKind::External,
+ KeyVersion::new(7).expect("valid key version"),
+ );
+ let plaintext = SecretMaterial::from_slice(PLAINTEXT_SENTINEL).expect("valid material");
+ let wrapped = WrappedSecret::from_bytes(b"wrapped-material-sentinel".to_vec())
+ .expect("valid wrapped material");
+ let sealing_key = SecretMaterial::from_slice(&[0x42; 32]).expect("valid sealing key");
+ let request = SealRequest::new(
+ reference,
+ &plaintext,
+ SealMaterial::new(sealing_key, Nonce::new([0x24; 24])),
+ );
+
+ let diagnostics = [
+ format!("{plaintext:?}"),
+ format!("{wrapped:?}"),
+ format!("{request:?}"),
+ format!("{:?}", Error::DecryptFailed),
+ Error::BackendFailure {
+ backend: BackendKind::External,
+ operation: Operation::Unwrap,
+ }
+ .to_string(),
+ Error::SecretNotFound {
+ backend: BackendKind::External,
+ key_version: 7,
+ }
+ .to_string(),
+ Error::InvalidSecretId(SecretIdError::InvalidCharacter { byte_offset: 9 }).to_string(),
+ ];
+
+ assert_eq!(diagnostics[0], "SecretMaterial(<redacted>)");
+ assert_eq!(diagnostics[1], "WrappedSecret(<redacted>)");
+ assert_eq!(diagnostics[2], "SealRequest(<redacted>)");
+ for diagnostic in diagnostics {
+ assert!(!diagnostic.contains(SECRET_ID_SENTINEL));
+ assert!(!diagnostic.contains("plaintext-material-sentinel"));
+ assert!(!diagnostic.contains("wrapped-material-sentinel"));
+ }
+}
+
+#[test]
+fn production_sources_have_no_plaintext_logging_surface() {
+ let source_root = Path::new(env!("CARGO_MANIFEST_DIR")).join("src");
+ let mut paths = Vec::new();
+ collect_rust_sources(&source_root, &mut paths);
+ assert!(!paths.is_empty());
+
+ for path in paths {
+ let source = fs::read_to_string(&path).expect("read secret source");
+ let production = source.split("\n#[cfg(test)]").next().unwrap_or(&source);
+ for forbidden in ["tracing::", "log::", "println!(", "eprintln!(", "dbg!("] {
+ assert!(
+ !production.contains(forbidden),
+ "secret production source contains logging surface `{forbidden}`: {}",
+ path.display()
+ );
+ }
+ }
+}
+
+fn collect_rust_sources(root: &Path, paths: &mut Vec<PathBuf>) {
+ for entry in fs::read_dir(root).expect("read source directory") {
+ let path = entry.expect("source entry").path();
+ if path.is_dir() {
+ collect_rust_sources(&path, paths);
+ } else if path.extension().and_then(|extension| extension.to_str()) == Some("rs") {
+ paths.push(path);
+ }
+ }
+}
diff --git a/docs/api/README.md b/docs/api/README.md
@@ -41,3 +41,4 @@ expand a package beyond its charter.
| `radroots_transport` | [`radroots_transport.txt`](radroots_transport.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) |
| `radroots_nostr` | [`radroots_nostr.txt`](radroots_nostr.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) |
| `radroots_nostr_connect` | [`radroots_nostr_connect.txt`](radroots_nostr_connect.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) |
+| `radroots_secrets` | [`radroots_secrets.txt`](radroots_secrets.txt) | [release V1 specification](../specs/radroots_crates_release_v1.md) |
diff --git a/docs/api/radroots_secrets.txt b/docs/api/radroots_secrets.txt
@@ -0,0 +1,394 @@
+pub mod radroots_secrets
+pub mod radroots_secrets::envelope
+#[non_exhaustive] pub enum radroots_secrets::envelope::Cipher
+pub radroots_secrets::envelope::Cipher::XChaCha20Poly1305
+#[non_exhaustive] pub enum radroots_secrets::envelope::KeySource
+pub radroots_secrets::envelope::KeySource::ProviderWrapped
+pub struct radroots_secrets::envelope::EncryptedEnvelope
+impl radroots_secrets::envelope::EncryptedEnvelope
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::cipher(&self) -> radroots_secrets::envelope::Cipher
+pub fn radroots_secrets::envelope::EncryptedEnvelope::decode(&[u8]) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub fn radroots_secrets::envelope::EncryptedEnvelope::encode(&self) -> core::result::Result<alloc::vec::Vec<u8>, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::key_source(&self) -> radroots_secrets::envelope::KeySource
+pub async fn radroots_secrets::envelope::EncryptedEnvelope::open(&self, &dyn radroots_secrets::wrapping::KeyWrapping) -> core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::reference(&self) -> &radroots_secrets::id::SecretRef
+pub async fn radroots_secrets::envelope::EncryptedEnvelope::seal(&dyn radroots_secrets::wrapping::KeyWrapping, radroots_secrets::envelope::SealRequest<'_>) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::version(&self) -> u16
+impl core::fmt::Debug for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl serde_core::ser::Serialize for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+pub struct radroots_secrets::envelope::Nonce(_)
+impl radroots_secrets::envelope::Nonce
+pub const fn radroots_secrets::envelope::Nonce::as_bytes(&self) -> &[u8; 24]
+pub const fn radroots_secrets::envelope::Nonce::new([u8; 24]) -> Self
+impl core::fmt::Debug for radroots_secrets::envelope::Nonce
+pub fn radroots_secrets::envelope::Nonce::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct radroots_secrets::envelope::SealMaterial
+impl radroots_secrets::envelope::SealMaterial
+pub const fn radroots_secrets::envelope::SealMaterial::new(radroots_secrets::wrapping::SecretMaterial, radroots_secrets::envelope::Nonce) -> Self
+impl core::fmt::Debug for radroots_secrets::envelope::SealMaterial
+pub fn radroots_secrets::envelope::SealMaterial::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct radroots_secrets::envelope::SealRequest<'a>
+impl<'a> radroots_secrets::envelope::SealRequest<'a>
+pub const fn radroots_secrets::envelope::SealRequest<'a>::new(radroots_secrets::id::SecretRef, &'a radroots_secrets::wrapping::SecretMaterial, radroots_secrets::envelope::SealMaterial) -> Self
+impl core::fmt::Debug for radroots_secrets::envelope::SealRequest<'_>
+pub fn radroots_secrets::envelope::SealRequest<'_>::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub const radroots_secrets::envelope::ENVELOPE_MAX_BYTES: usize
+pub const radroots_secrets::envelope::ENVELOPE_VERSION: u16
+pub mod radroots_secrets::error
+#[non_exhaustive] pub enum radroots_secrets::error::Error
+pub radroots_secrets::error::Error::BackendFailure
+pub radroots_secrets::error::Error::BackendFailure::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::BackendFailure::operation: radroots_secrets::error::Operation
+pub radroots_secrets::error::Error::BackendMismatch
+pub radroots_secrets::error::Error::BackendMismatch::provider: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::BackendMismatch::reference: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::BackendUnavailable
+pub radroots_secrets::error::Error::BackendUnavailable::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::DecryptFailed
+pub radroots_secrets::error::Error::EncryptFailed
+pub radroots_secrets::error::Error::EnvelopeMalformed
+pub radroots_secrets::error::Error::EnvelopeTooLarge
+pub radroots_secrets::error::Error::EnvelopeTooLarge::actual_bytes: usize
+pub radroots_secrets::error::Error::EnvelopeTooLarge::max_bytes: usize
+pub radroots_secrets::error::Error::InsecurePermissions
+pub radroots_secrets::error::Error::InvalidDataKeyLength
+pub radroots_secrets::error::Error::InvalidDataKeyLength::actual_bytes: usize
+pub radroots_secrets::error::Error::InvalidKeyVersion
+pub radroots_secrets::error::Error::InvalidRotation
+pub radroots_secrets::error::Error::InvalidSecretId(radroots_secrets::error::SecretIdError)
+pub radroots_secrets::error::Error::InvalidSecretLength
+pub radroots_secrets::error::Error::InvalidSecretLength::actual_bytes: usize
+pub radroots_secrets::error::Error::InvalidSecretLength::max_bytes: usize
+pub radroots_secrets::error::Error::InvalidServiceName
+pub radroots_secrets::error::Error::InvalidWrappedLength
+pub radroots_secrets::error::Error::InvalidWrappedLength::actual_bytes: usize
+pub radroots_secrets::error::Error::InvalidWrappedLength::max_bytes: usize
+pub radroots_secrets::error::Error::PolicyUnsupported
+pub radroots_secrets::error::Error::PolicyUnsupported::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::PolicyUnsupported::requirement: radroots_secrets::error::PolicyRequirement
+pub radroots_secrets::error::Error::SecretAlreadyExists
+pub radroots_secrets::error::Error::SecretAlreadyExists::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::SecretAlreadyExists::key_version: u32
+pub radroots_secrets::error::Error::SecretNotFound
+pub radroots_secrets::error::Error::SecretNotFound::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::error::Error::SecretNotFound::key_version: u32
+pub radroots_secrets::error::Error::UnsafePath
+pub radroots_secrets::error::Error::UnsupportedBackend
+pub radroots_secrets::error::Error::UnsupportedBackend::backend: u8
+pub radroots_secrets::error::Error::UnsupportedCipher
+pub radroots_secrets::error::Error::UnsupportedCipher::cipher: u8
+pub radroots_secrets::error::Error::UnsupportedEnvelopeVersion
+pub radroots_secrets::error::Error::UnsupportedEnvelopeVersion::version: u16
+pub radroots_secrets::error::Error::UnsupportedKeySource
+pub radroots_secrets::error::Error::UnsupportedKeySource::key_source: u8
+impl core::error::Error for radroots_secrets::error::Error
+impl core::fmt::Display for radroots_secrets::error::Error
+pub fn radroots_secrets::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+#[non_exhaustive] pub enum radroots_secrets::error::Operation
+pub radroots_secrets::error::Operation::Open
+pub radroots_secrets::error::Operation::Provision
+pub radroots_secrets::error::Operation::Read
+pub radroots_secrets::error::Operation::Remove
+pub radroots_secrets::error::Operation::Rotate
+pub radroots_secrets::error::Operation::Unwrap
+pub radroots_secrets::error::Operation::Wrap
+pub radroots_secrets::error::Operation::Write
+#[non_exhaustive] pub enum radroots_secrets::error::PolicyRequirement
+pub radroots_secrets::error::PolicyRequirement::DeviceLocal
+pub radroots_secrets::error::PolicyRequirement::HardwareBacked
+pub radroots_secrets::error::PolicyRequirement::UserPresence
+#[non_exhaustive] pub enum radroots_secrets::error::SecretIdError
+pub radroots_secrets::error::SecretIdError::Empty
+pub radroots_secrets::error::SecretIdError::InvalidCharacter
+pub radroots_secrets::error::SecretIdError::InvalidCharacter::byte_offset: usize
+pub radroots_secrets::error::SecretIdError::TooLong
+pub radroots_secrets::error::SecretIdError::TooLong::actual_bytes: usize
+pub radroots_secrets::error::SecretIdError::TooLong::max_bytes: usize
+impl core::fmt::Display for radroots_secrets::error::SecretIdError
+pub fn radroots_secrets::error::SecretIdError::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub mod radroots_secrets::file
+#[non_exhaustive] pub enum radroots_secrets::file::FileOpenMode
+pub radroots_secrets::file::FileOpenMode::CreateNew
+pub radroots_secrets::file::FileOpenMode::OpenExisting
+pub struct radroots_secrets::file::FileProvider
+impl radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::contains(&self, &radroots_secrets::id::SecretRef) -> core::result::Result<bool, radroots_secrets::error::Error>
+pub fn radroots_secrets::file::FileProvider::open(impl core::convert::AsRef<std::path::Path>, radroots_secrets::file::FileOpenMode, radroots_secrets::wrapping::SecretMaterial) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub fn radroots_secrets::file::FileProvider::provision(&self, &radroots_secrets::id::SecretRef, &radroots_secrets::wrapping::SecretMaterial, radroots_secrets::envelope::Nonce) -> core::result::Result<(), radroots_secrets::error::Error>
+pub fn radroots_secrets::file::FileProvider::remove(&self, &radroots_secrets::id::SecretRef) -> core::result::Result<bool, radroots_secrets::error::Error>
+pub fn radroots_secrets::file::FileProvider::rotate(&self, &radroots_secrets::id::SecretRef, &radroots_secrets::id::SecretRef, &radroots_secrets::wrapping::SecretMaterial, radroots_secrets::envelope::Nonce) -> core::result::Result<(), radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::file::FileProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::file::FileProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+pub mod radroots_secrets::id
+#[non_exhaustive] pub enum radroots_secrets::id::BackendKind
+pub radroots_secrets::id::BackendKind::External
+pub radroots_secrets::id::BackendKind::File
+pub radroots_secrets::id::BackendKind::Keyring
+pub radroots_secrets::id::BackendKind::Memory
+pub struct radroots_secrets::id::KeyVersion(_)
+impl radroots_secrets::id::KeyVersion
+pub const fn radroots_secrets::id::KeyVersion::get(self) -> u32
+pub const fn radroots_secrets::id::KeyVersion::new(u32) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub struct radroots_secrets::id::SecretId(_)
+impl radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::as_str(&self) -> &str
+pub fn radroots_secrets::id::SecretId::parse(impl core::convert::AsRef<str>) -> core::result::Result<Self, radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::str::traits::FromStr for radroots_secrets::id::SecretId
+pub type radroots_secrets::id::SecretId::Err = radroots_secrets::error::Error
+pub fn radroots_secrets::id::SecretId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+pub struct radroots_secrets::id::SecretRef
+impl radroots_secrets::id::SecretRef
+pub const fn radroots_secrets::id::SecretRef::backend(&self) -> radroots_secrets::id::BackendKind
+pub const fn radroots_secrets::id::SecretRef::id(&self) -> &radroots_secrets::id::SecretId
+pub const fn radroots_secrets::id::SecretRef::key_version(&self) -> radroots_secrets::id::KeyVersion
+pub const fn radroots_secrets::id::SecretRef::new(radroots_secrets::id::SecretId, radroots_secrets::id::BackendKind, radroots_secrets::id::KeyVersion) -> Self
+impl core::fmt::Debug for radroots_secrets::id::SecretRef
+pub fn radroots_secrets::id::SecretRef::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub const radroots_secrets::id::SECRET_ID_MAX_BYTES: usize
+pub mod radroots_secrets::keyring
+pub struct radroots_secrets::keyring::KeyringProvider
+impl radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::new(impl core::convert::AsRef<str>) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub fn radroots_secrets::keyring::KeyringProvider::provision(&self, &radroots_secrets::id::SecretRef, &radroots_secrets::wrapping::SecretMaterial) -> core::result::Result<(), radroots_secrets::error::Error>
+pub fn radroots_secrets::keyring::KeyringProvider::remove(&self, &radroots_secrets::id::SecretRef) -> core::result::Result<bool, radroots_secrets::error::Error>
+pub fn radroots_secrets::keyring::KeyringProvider::rotate(&self, &radroots_secrets::id::SecretRef, &radroots_secrets::id::SecretRef, &radroots_secrets::wrapping::SecretMaterial) -> core::result::Result<(), radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::keyring::KeyringProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::keyring::KeyringProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+pub mod radroots_secrets::memory
+pub struct radroots_secrets::memory::MemoryProvider
+impl radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::contains(&self, &radroots_secrets::id::SecretRef) -> core::result::Result<bool, radroots_secrets::error::Error>
+pub fn radroots_secrets::memory::MemoryProvider::new() -> Self
+pub fn radroots_secrets::memory::MemoryProvider::provision(&self, &radroots_secrets::id::SecretRef, radroots_secrets::wrapping::SecretMaterial) -> core::result::Result<(), radroots_secrets::error::Error>
+pub fn radroots_secrets::memory::MemoryProvider::remove(&self, &radroots_secrets::id::SecretRef) -> core::result::Result<bool, radroots_secrets::error::Error>
+pub fn radroots_secrets::memory::MemoryProvider::rotate(&self, &radroots_secrets::id::SecretRef, &radroots_secrets::id::SecretRef, radroots_secrets::wrapping::SecretMaterial) -> core::result::Result<(), radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::memory::MemoryProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::memory::MemoryProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+pub mod radroots_secrets::provider
+#[non_exhaustive] pub enum radroots_secrets::provider::CapabilitySupport
+pub radroots_secrets::provider::CapabilitySupport::Supported
+pub radroots_secrets::provider::CapabilitySupport::Unavailable
+#[non_exhaustive] pub enum radroots_secrets::provider::HardwarePolicy
+pub radroots_secrets::provider::HardwarePolicy::Any
+pub radroots_secrets::provider::HardwarePolicy::PreferHardwareBacked
+pub radroots_secrets::provider::HardwarePolicy::RequireHardwareBacked
+#[non_exhaustive] pub enum radroots_secrets::provider::ResidencyPolicy
+pub radroots_secrets::provider::ResidencyPolicy::Any
+pub radroots_secrets::provider::ResidencyPolicy::DeviceLocal
+#[non_exhaustive] pub enum radroots_secrets::provider::ResidencySupport
+pub radroots_secrets::provider::ResidencySupport::DeviceLocal
+pub radroots_secrets::provider::ResidencySupport::UserProfile
+pub radroots_secrets::provider::ResidencySupport::Volatile
+#[non_exhaustive] pub enum radroots_secrets::provider::UserPresencePolicy
+pub radroots_secrets::provider::UserPresencePolicy::NotRequired
+pub radroots_secrets::provider::UserPresencePolicy::Required
+pub struct radroots_secrets::provider::AccessPolicy
+impl radroots_secrets::provider::AccessPolicy
+pub const fn radroots_secrets::provider::AccessPolicy::new(radroots_secrets::provider::ResidencyPolicy, radroots_secrets::provider::UserPresencePolicy, radroots_secrets::provider::HardwarePolicy) -> Self
+pub const fn radroots_secrets::provider::AccessPolicy::standard() -> Self
+pub struct radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretCapabilities
+pub const fn radroots_secrets::provider::SecretCapabilities::available(radroots_secrets::provider::ResidencySupport, radroots_secrets::provider::CapabilitySupport, radroots_secrets::provider::CapabilitySupport) -> Self
+pub const fn radroots_secrets::provider::SecretCapabilities::hardware_backed(self) -> radroots_secrets::provider::CapabilitySupport
+pub const fn radroots_secrets::provider::SecretCapabilities::is_available(self) -> bool
+pub const fn radroots_secrets::provider::SecretCapabilities::residency(self) -> radroots_secrets::provider::ResidencySupport
+pub const fn radroots_secrets::provider::SecretCapabilities::unavailable() -> Self
+pub const fn radroots_secrets::provider::SecretCapabilities::user_presence(self) -> radroots_secrets::provider::CapabilitySupport
+pub struct radroots_secrets::provider::SelectionPolicy
+impl radroots_secrets::provider::SelectionPolicy
+pub const fn radroots_secrets::provider::SelectionPolicy::new(radroots_secrets::id::BackendKind, radroots_secrets::provider::AccessPolicy) -> Self
+pub fn radroots_secrets::provider::SelectionPolicy::select<'a>(self, &'a [&'a dyn radroots_secrets::provider::SecretProvider]) -> core::result::Result<&'a dyn radroots_secrets::provider::SecretProvider, radroots_secrets::error::Error>
+pub trait radroots_secrets::provider::SecretProvider: radroots_secrets::wrapping::KeyWrapping + core::marker::Send + core::marker::Sync
+pub fn radroots_secrets::provider::SecretProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::provider::SecretProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::file::FileProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::keyring::KeyringProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::memory::MemoryProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+pub mod radroots_secrets::wrapping
+pub struct radroots_secrets::wrapping::SecretMaterial(_)
+impl radroots_secrets::wrapping::SecretMaterial
+pub fn radroots_secrets::wrapping::SecretMaterial::expose_secret<T>(&self, impl core::ops::function::FnOnce(&[u8]) -> T) -> T
+pub fn radroots_secrets::wrapping::SecretMaterial::from_slice(&[u8]) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub fn radroots_secrets::wrapping::SecretMaterial::is_empty(&self) -> bool
+pub fn radroots_secrets::wrapping::SecretMaterial::len(&self) -> usize
+impl core::fmt::Debug for radroots_secrets::wrapping::SecretMaterial
+pub fn radroots_secrets::wrapping::SecretMaterial::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct radroots_secrets::wrapping::UnwrapRequest<'a>
+impl<'a> radroots_secrets::wrapping::UnwrapRequest<'a>
+pub const fn radroots_secrets::wrapping::UnwrapRequest<'a>::new(&'a radroots_secrets::id::SecretRef, &'a radroots_secrets::wrapping::WrappedSecret) -> Self
+pub const fn radroots_secrets::wrapping::UnwrapRequest<'a>::reference(&self) -> &'a radroots_secrets::id::SecretRef
+pub const fn radroots_secrets::wrapping::UnwrapRequest<'a>::wrapped(&self) -> &'a radroots_secrets::wrapping::WrappedSecret
+pub struct radroots_secrets::wrapping::WrapRequest<'a>
+impl<'a> radroots_secrets::wrapping::WrapRequest<'a>
+pub const fn radroots_secrets::wrapping::WrapRequest<'a>::new(&'a radroots_secrets::id::SecretRef, &'a radroots_secrets::wrapping::SecretMaterial) -> Self
+pub const fn radroots_secrets::wrapping::WrapRequest<'a>::plaintext(&self) -> &'a radroots_secrets::wrapping::SecretMaterial
+pub const fn radroots_secrets::wrapping::WrapRequest<'a>::reference(&self) -> &'a radroots_secrets::id::SecretRef
+pub struct radroots_secrets::wrapping::WrappedSecret(_)
+impl radroots_secrets::wrapping::WrappedSecret
+pub fn radroots_secrets::wrapping::WrappedSecret::as_bytes(&self) -> &[u8]
+pub fn radroots_secrets::wrapping::WrappedSecret::from_bytes(impl core::convert::Into<alloc::vec::Vec<u8>>) -> core::result::Result<Self, radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::wrapping::WrappedSecret
+pub fn radroots_secrets::wrapping::WrappedSecret::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub const radroots_secrets::wrapping::SECRET_MATERIAL_MAX_BYTES: usize
+pub const radroots_secrets::wrapping::WRAPPED_SECRET_MAX_BYTES: usize
+pub trait radroots_secrets::wrapping::KeyWrapping: core::marker::Send + core::marker::Sync
+pub fn radroots_secrets::wrapping::KeyWrapping::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::wrapping::KeyWrapping::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::file::FileProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::keyring::KeyringProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::memory::MemoryProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+pub type radroots_secrets::wrapping::BoxFuture<'a, T> = core::pin::Pin<alloc::boxed::Box<(dyn core::future::future::Future<Output = T> + core::marker::Send + 'a)>>
+#[non_exhaustive] pub enum radroots_secrets::Error
+pub radroots_secrets::Error::BackendFailure
+pub radroots_secrets::Error::BackendFailure::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::BackendFailure::operation: radroots_secrets::error::Operation
+pub radroots_secrets::Error::BackendMismatch
+pub radroots_secrets::Error::BackendMismatch::provider: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::BackendMismatch::reference: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::BackendUnavailable
+pub radroots_secrets::Error::BackendUnavailable::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::DecryptFailed
+pub radroots_secrets::Error::EncryptFailed
+pub radroots_secrets::Error::EnvelopeMalformed
+pub radroots_secrets::Error::EnvelopeTooLarge
+pub radroots_secrets::Error::EnvelopeTooLarge::actual_bytes: usize
+pub radroots_secrets::Error::EnvelopeTooLarge::max_bytes: usize
+pub radroots_secrets::Error::InsecurePermissions
+pub radroots_secrets::Error::InvalidDataKeyLength
+pub radroots_secrets::Error::InvalidDataKeyLength::actual_bytes: usize
+pub radroots_secrets::Error::InvalidKeyVersion
+pub radroots_secrets::Error::InvalidRotation
+pub radroots_secrets::Error::InvalidSecretId(radroots_secrets::error::SecretIdError)
+pub radroots_secrets::Error::InvalidSecretLength
+pub radroots_secrets::Error::InvalidSecretLength::actual_bytes: usize
+pub radroots_secrets::Error::InvalidSecretLength::max_bytes: usize
+pub radroots_secrets::Error::InvalidServiceName
+pub radroots_secrets::Error::InvalidWrappedLength
+pub radroots_secrets::Error::InvalidWrappedLength::actual_bytes: usize
+pub radroots_secrets::Error::InvalidWrappedLength::max_bytes: usize
+pub radroots_secrets::Error::PolicyUnsupported
+pub radroots_secrets::Error::PolicyUnsupported::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::PolicyUnsupported::requirement: radroots_secrets::error::PolicyRequirement
+pub radroots_secrets::Error::SecretAlreadyExists
+pub radroots_secrets::Error::SecretAlreadyExists::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::SecretAlreadyExists::key_version: u32
+pub radroots_secrets::Error::SecretNotFound
+pub radroots_secrets::Error::SecretNotFound::backend: radroots_secrets::id::BackendKind
+pub radroots_secrets::Error::SecretNotFound::key_version: u32
+pub radroots_secrets::Error::UnsafePath
+pub radroots_secrets::Error::UnsupportedBackend
+pub radroots_secrets::Error::UnsupportedBackend::backend: u8
+pub radroots_secrets::Error::UnsupportedCipher
+pub radroots_secrets::Error::UnsupportedCipher::cipher: u8
+pub radroots_secrets::Error::UnsupportedEnvelopeVersion
+pub radroots_secrets::Error::UnsupportedEnvelopeVersion::version: u16
+pub radroots_secrets::Error::UnsupportedKeySource
+pub radroots_secrets::Error::UnsupportedKeySource::key_source: u8
+impl core::error::Error for radroots_secrets::error::Error
+impl core::fmt::Display for radroots_secrets::error::Error
+pub fn radroots_secrets::error::Error::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub struct radroots_secrets::EncryptedEnvelope
+impl radroots_secrets::envelope::EncryptedEnvelope
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::cipher(&self) -> radroots_secrets::envelope::Cipher
+pub fn radroots_secrets::envelope::EncryptedEnvelope::decode(&[u8]) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub fn radroots_secrets::envelope::EncryptedEnvelope::encode(&self) -> core::result::Result<alloc::vec::Vec<u8>, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::key_source(&self) -> radroots_secrets::envelope::KeySource
+pub async fn radroots_secrets::envelope::EncryptedEnvelope::open(&self, &dyn radroots_secrets::wrapping::KeyWrapping) -> core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::reference(&self) -> &radroots_secrets::id::SecretRef
+pub async fn radroots_secrets::envelope::EncryptedEnvelope::seal(&dyn radroots_secrets::wrapping::KeyWrapping, radroots_secrets::envelope::SealRequest<'_>) -> core::result::Result<Self, radroots_secrets::error::Error>
+pub const fn radroots_secrets::envelope::EncryptedEnvelope::version(&self) -> u16
+impl core::fmt::Debug for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl serde_core::ser::Serialize for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_secrets::envelope::EncryptedEnvelope
+pub fn radroots_secrets::envelope::EncryptedEnvelope::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+pub struct radroots_secrets::SecretId(_)
+impl radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::as_str(&self) -> &str
+pub fn radroots_secrets::id::SecretId::parse(impl core::convert::AsRef<str>) -> core::result::Result<Self, radroots_secrets::error::Error>
+impl core::fmt::Debug for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::fmt::Display for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+impl core::str::traits::FromStr for radroots_secrets::id::SecretId
+pub type radroots_secrets::id::SecretId::Err = radroots_secrets::error::Error
+pub fn radroots_secrets::id::SecretId::from_str(&str) -> core::result::Result<Self, Self::Err>
+impl serde_core::ser::Serialize for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::serialize<S>(&self, S) -> core::result::Result<<S as serde_core::ser::Serializer>::Ok, <S as serde_core::ser::Serializer>::Error> where S: serde_core::ser::Serializer
+impl<'de> serde_core::de::Deserialize<'de> for radroots_secrets::id::SecretId
+pub fn radroots_secrets::id::SecretId::deserialize<D>(D) -> core::result::Result<Self, <D as serde_core::de::Deserializer>::Error> where D: serde_core::de::Deserializer<'de>
+pub struct radroots_secrets::SecretRef
+impl radroots_secrets::id::SecretRef
+pub const fn radroots_secrets::id::SecretRef::backend(&self) -> radroots_secrets::id::BackendKind
+pub const fn radroots_secrets::id::SecretRef::id(&self) -> &radroots_secrets::id::SecretId
+pub const fn radroots_secrets::id::SecretRef::key_version(&self) -> radroots_secrets::id::KeyVersion
+pub const fn radroots_secrets::id::SecretRef::new(radroots_secrets::id::SecretId, radroots_secrets::id::BackendKind, radroots_secrets::id::KeyVersion) -> Self
+impl core::fmt::Debug for radroots_secrets::id::SecretRef
+pub fn radroots_secrets::id::SecretRef::fmt(&self, &mut core::fmt::Formatter<'_>) -> core::fmt::Result
+pub trait radroots_secrets::KeyWrapping: core::marker::Send + core::marker::Sync
+pub fn radroots_secrets::KeyWrapping::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::KeyWrapping::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::file::FileProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::keyring::KeyringProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+impl radroots_secrets::wrapping::KeyWrapping for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::unwrap<'a>(&'a self, radroots_secrets::wrapping::UnwrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::SecretMaterial, radroots_secrets::error::Error>>
+pub fn radroots_secrets::memory::MemoryProvider::wrap<'a>(&'a self, radroots_secrets::wrapping::WrapRequest<'a>) -> radroots_secrets::wrapping::BoxFuture<'a, core::result::Result<radroots_secrets::wrapping::WrappedSecret, radroots_secrets::error::Error>>
+pub trait radroots_secrets::SecretProvider: radroots_secrets::wrapping::KeyWrapping + core::marker::Send + core::marker::Sync
+pub fn radroots_secrets::SecretProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::SecretProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::file::FileProvider
+pub fn radroots_secrets::file::FileProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::file::FileProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::keyring::KeyringProvider
+pub fn radroots_secrets::keyring::KeyringProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::keyring::KeyringProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities
+impl radroots_secrets::provider::SecretProvider for radroots_secrets::memory::MemoryProvider
+pub fn radroots_secrets::memory::MemoryProvider::backend_kind(&self) -> radroots_secrets::id::BackendKind
+pub fn radroots_secrets::memory::MemoryProvider::capabilities(&self) -> radroots_secrets::provider::SecretCapabilities