Struct PathAllowlist

Source
pub struct PathAllowlist {
    root: TrieNode,
}
Expand description

A hierarchical path allowlist that restricts file system access using a prefix tree (Trie).

The allowlist provides a high-performance, zero-overhead mechanism (when unused) to enforce path-based access boundaries for FUSE/virtiofs devices.

§Public API Semantics

Access checks are divided into two distinct operations:

  • is_accessible(path): Checks if a path can be looked up or read (e.g., for lookup, readdir, open).
    • Returns true if the path is explicitly allowed, is a descendant of an allowed path, or is an ancestor directory needed to reach an allowed path.
  • is_writable(path): Checks if a path can be modified (e.g., for mkdir, create, unlink, rename).
    • Returns true ONLY if the path is explicitly allowed or is a descendant of an allowed path. Ancestor directories are never writable.

§Under the Hood: Access Levels & Inheritance

Internally, each path in the Trie is mapped to one of the following **AccessLevel**s:

  • None (Blocked): Complete restriction.
  • Traverse (Traversal Only - Non-inheritable): Granted to ancestor directories. It serves strictly as a traversable pathway to reach allowed paths. Sibling paths under a Traverse directory remain blocked.
  • Full (Full Access - Inheritable): Granted to explicitly allowed paths. This level is automatically propagated to all descendant paths (e.g., allowing /a/b automatically grants Full access to /a/b/c/**).

§Illustrative Scenarios

§Scenario 1: When /a/b and /a/b/c are added to allowlist

Accessible:

  • /, /a, /a/b/** (traversable down to /a/b and all its descendants)

Writable:

  • /a/b/** (full write access inside /a/b and all its descendants)

§Scenario 2: When access to /a/b is revoked (while keeping /a/b/c allowed)

To keep /a/b/c accessible, /a/b is automatically demoted to Traverse (Read-only traversal pathway) rather than being blocked entirely:

Accessible:

  • /, /a, /a/b, /a/b/c/** (traversal is allowed through /a/b, but sibling /a/b/d is now blocked)

Writable:

  • /a/b/c/** (write access is strictly restricted to the remaining allowed subtree)

Fields§

§root: TrieNode

Implementations§

Source§

impl PathAllowlist

Source

pub fn new() -> Self

Creates a new PathAllowlist.

Source

fn parse_components(path: &Path) -> Vec<&OsStr>

Parses a normalized path into its components, ignoring non-normal components.

Source

pub fn add_path<P: AsRef<Path>>(&mut self, path: P) -> bool

Adds a path to the allowed list. The path will be normalized before being added. Returns true if the path was valid and successfully added. Returns false if the path was invalid (e.g. traversed above root).

Source

pub fn remove_path<P: AsRef<Path>>(&mut self, path: P) -> bool

Removes a path from the allowed list. The path will be normalized before removal. Returns true if the path was explicitly allowed and successfully removed (or demoted). Returns false if the path was not explicitly allowed.

Source

fn get_access_level(&self, path: &Path) -> AccessLevel

Resolves the effective access level for a given path by traversing the Trie.

Source

pub fn is_accessible<P: AsRef<Path>>(&self, path: P) -> bool

Checks if a path is accessible (read/lookup).

A path is accessible if it has at least Traverse access level.

Source

pub fn is_writable<P: AsRef<Path>>(&self, path: P) -> bool

Checks if a path is allowed to be written to.

A path is writable only if it has Full access level.

Source

pub fn get_read_dir_filter<P: AsRef<Path>>( &self, parent_path: P, ) -> ReadDirFilter

Returns a ReadDirFilter for the given parent directory path.

This pre-calculates the accessible entries within the directory, avoiding the need to perform full path resolution and Trie traversal for each individual entry during directory listing.

Trait Implementations§

Source§

impl Clone for PathAllowlist

Source§

fn clone(&self) -> PathAllowlist

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for PathAllowlist

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for PathAllowlist

Source§

fn default() -> PathAllowlist

Returns the “default value” for a type. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V