Skip to main content

ActScope

Enum ActScope 

Source
pub enum ActScope {
    None,
    All,
    Contexts(Vec<String>),
}
Expand description

A DID’s authority to act — the contexts in which it may make a change. The sibling axis to ApproveScope, with deliberately identical variants, an identical covers predicate, and the same fail-closed None default.

§Why this exists

Unlike ApproveScope, this is not a stored or wire field. The act axis is stored as (role, allowed_contexts), where an empty allowed_contexts means opposite things depending on the role: unrestricted for an admin (that is how a super-admin is spelled), and nothing at all for every other role. Reading the raw field without the role is therefore a bug, and has repeatedly been one — a display that called a least-privilege approver (unrestricted), two acl list --context filters that disagreed on whether an empty list matches every context or none, and a vault scope gate that granted cross-context reads to an entry authorized nowhere.

This type makes the three cases distinguishable so that decode happens in one place instead of at every call site. The decode itself is server-side (vti_common::acl::act_scope_for), because it needs Role; only the shape and the predicate are shared, exactly as for ApproveScope.

It lives beside ApproveScope so the two axes — what a DID may do and what it may confer — read as one model rather than an enum and a convention.

Variants§

§

None

Authorized in no context at all (the fail-closed default). The shape of a least-privilege approver: acts nowhere, may still confer via its ApproveScope.

§

All

Authorized in every context. Combined with the admin role this is a super-admin.

§

Contexts(Vec<String>)

Authorized in these contexts and their subtrees, and only these.

Implementations§

Source§

impl ActScope

Source

pub fn covers(&self, context_id: &str) -> bool

Whether a holder of this scope may act in context_id.

Segment-aware ancestry, identical to ApproveScope::covers, so authority over a parent context covers its whole subtree.

Source

pub fn acts_within(&self, context_id: &str) -> bool

Whether this scope names a context at or beneath context_id — the mirror of covers, with the ancestry test’s arguments swapped.

covers answers “may this entry act in the context?”; this answers “does this entry hold a grant inside the context’s subtree?”. They are different questions and a caller sweeping a subtree — to revoke it, or to audit it — wants this one: a grant at acme/eng/team-a is invisible to covers("acme/eng") because it holds no authority over acme/eng, yet it is precisely what the sweep exists to find.

Two deliberate edges:

  • All is not a match. An unrestricted entry names no context, so it is not a grant of this subtree — it is authority everywhere, which covers already reports. A subtree sweep that returned it would invite a caller revoking a compromised branch to delete its own super-admin. Ask ContextDirection::Any for “everyone whose authority touches this subtree”, which includes it.
  • A Contexts scope matches if any named context is inside the subtree, even when it also names contexts outside it. Such an entry does hold a grant in the subtree, so omitting it would under-report; whether to delete the entry or narrow its scope is then the caller’s decision, made with the entry in hand.
Source

pub fn matches_context( &self, context_id: &str, direction: ContextDirection, ) -> bool

Whether this scope matches context_id when read in direction — the single predicate behind every context-filtered ACL listing.

Source

pub fn is_unrestricted(&self) -> bool

Whether this scope authorizes every context (the super-admin condition when paired with the admin role).

Source

pub fn acts_nowhere(&self) -> bool

Whether this scope authorizes nothing.

Source

pub fn named_contexts(&self) -> &[String]

The contexts named by this scope, or an empty slice for None / All — neither of which is expressible as a list.

Trait Implementations§

Source§

impl Clone for ActScope

Source§

fn clone(&self) -> ActScope

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl Debug for ActScope

Source§

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

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

impl Default for ActScope

Source§

fn default() -> ActScope

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

impl Display for ActScope

Source§

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

Operator-facing rendering. The unrestricted and acts-nowhere cases are spelled out rather than both collapsing to (unrestricted), which is what made them indistinguishable on ACL displays. The wording matches what vta-cli-common’s format_contexts already prints.

Source§

impl Eq for ActScope

Source§

impl PartialEq for ActScope

Source§

fn eq(&self, other: &ActScope) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for ActScope

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> Same for T

Source§

type Output = T

Should always be Self
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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. 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.