envseal 0.3.11

Write-only secret vault with process-level access control — post-agent secret management
Documentation
//! Runtime detection of OS security capabilities that envseal actually uses.
//!
//! Reports only capabilities envseal exercises today. Adding a field here is a
//! commitment that the consuming code path (e.g. `apply_sandbox`,
//! `MasterKey::protect`) actually uses the underlying primitive — never a
//! cosmetic "this OS has X" flag.

/// Snapshot of which security primitives the running kernel/OS supports
/// **and that envseal currently uses**.
#[derive(Debug, Clone, Copy)]
#[allow(clippy::struct_excessive_bools)]
pub struct OsCapabilities {
    /// Whether unprivileged user namespaces are enabled (Linux 3.8+).
    /// Used by [`super::apply_sandbox`].
    pub user_namespaces: bool,
    /// Whether PID namespace isolation is available. Linux only today.
    pub pid_namespace: bool,
    /// Whether mount namespace isolation is available. Linux only today.
    pub mount_namespace: bool,
    /// Whether network namespace isolation is available. Linux only today.
    pub network_namespace: bool,
    /// Whether `memfd_secret()` is supported for root-resistant key storage (Linux 5.14+).
    /// Used by `crate::keychain::MasterKey` to upgrade key memory protection
    /// when available.
    pub memfd_secret: bool,
    /// Whether seccomp-notify is available for syscall supervision (Linux 5.9+).
    pub seccomp_notify: bool,
    /// Whether ptrace is restricted by Yama LSM (Linux).
    pub ptrace_restricted: bool,
}

impl OsCapabilities {
    /// Probe the current OS/kernel for capabilities envseal can use.
    #[must_use]
    pub fn detect() -> Self {
        #[cfg(target_os = "linux")]
        {
            Self {
                user_namespaces: super::user_namespaces_available(),
                pid_namespace: true,
                mount_namespace: true,
                network_namespace: true,
                memfd_secret: std::path::Path::new("/sys/kernel/security").exists(),
                seccomp_notify: std::path::Path::new("/proc/sys/kernel/seccomp").exists(),
                ptrace_restricted: std::fs::read_to_string("/proc/sys/kernel/yama/ptrace_scope")
                    .is_ok_and(|v| v.trim() != "0"),
            }
        }
        #[cfg(not(target_os = "linux"))]
        {
            Self {
                user_namespaces: false,
                pid_namespace: false,
                mount_namespace: false,
                network_namespace: false,
                memfd_secret: false,
                seccomp_notify: false,
                ptrace_restricted: false,
            }
        }
    }
}