Skip to main content

Authority

Struct Authority 

Source
pub struct Authority { /* private fields */ }
Expand description

A tailnet-lock authority as a client tracks it: the current trusted-key State and the chain head. Built by replaying the AUM chain (or from a control-provided checkpoint); the client then uses Authority::node_key_authorized to decide whether a peer is trusted.

Implementations§

Source§

impl Authority

Source

pub fn from_state(head: AumHash, state: State) -> Authority

Construct an authority directly from a known head and trusted-key state (e.g. a control-provided checkpoint the client already trusts).

Source

pub fn head(&self) -> AumHash

The current chain head hash (Go Authority.Head).

Source

pub fn state(&self) -> &State

The trusted-key state.

Source

pub fn head_matches(&self, head: &AumHash) -> bool

Whether head (e.g. decoded from TkaInfo.head) matches this authority’s head. A client that finds a mismatch must resync before trusting verifications.

Source

pub fn node_key_authorized( &self, node_key: &[u8], signature_cbor: &[u8], ) -> Result<(), TkaError>

Verify that node_key is authorized under the current authority state by the given node-key-signature CBOR blob (Go Authority.NodeKeyAuthorized).

Fail-closed: a credential-only signature, an untrusted authorizing key, a malformed blob, or a bad signature all return Err.

§Errors

Returns TkaError::Decode if signature_cbor is malformed, TkaError::CredentialCannotAuthorize for a credential-only signature, TkaError::UntrustedKey if the authorizing key is not in the current state, TkaError::NodeKeyMismatch if the signature does not cover node_key, or TkaError::BadSignature if cryptographic verification fails.

Source§

impl Authority

Source

pub fn from_verified_chain(chain: VerifiedAumChain) -> Authority

Build an Authority from a VerifiedAumChain — the trust-boundary constructor.

Because a VerifiedAumChain can only be produced by VerifiedAumChain::verify (which runs Go’s aumVerify on every link), this is the constructor a live client must use when the chain originates from an untrusted source (the control plane / /machine/tka/* sync RPC). The type system makes the signature check un-skippable: there is no way to reach this function with an unverified chain. Mirrors Go tka.Open, which folds only AUMs already verified by Inform.

Source

pub fn from_chain(aums: &[Aum]) -> Result<Authority, TkaError>

Build an Authority by replaying a linear chain of AUMs from genesis to head (Go tka.Authority.Head after computeActiveChain on a single confirmed branch), checking only the chain’s structure (genesis kind, parent links, key-state transitions, checkpoint StateID) — NOT AUM signatures.

§This is NOT a trust boundary

from_chain does not verify that each AUM is signed by keys trusted at its parent. It is safe only for chains whose authenticity is already established by other means — the existing unit tests, and a chain the caller has itself fed through VerifiedAumChain::verify. For any chain that comes from an untrusted source (the control plane), use VerifiedAumChain::verify + Authority::from_verified_chain, which the type system makes impossible to bypass. (A malicious control plane could otherwise forge an AddKey/RemoveKey here and silently defeat tailnet lock — the exact threat TKA exists to stop.)

aums must be ordered parent→child: the first is the genesis — a NoOp, AddKey, or Checkpoint with no parent (Go computeStateAt rejects any other kind as an invalid genesis) — and each subsequent AUM’s prev_aum_hash must equal the prior AUM’s Aum::hash. A slice that is actually a suffix of a chain (its first AUM names a parent not in the slice) is rejected rather than mis-rooted.

For the forked case (competing children of one parent), use Authority::from_forked_chain.

§Errors

TkaError::BadChain if aums is empty or its genesis is an invalid kind; TkaError::BadParent if a link doesn’t chain (incl. a genesis that carries a parent); TkaError::BadKeyState for an invalid add/remove/update or a mismatched checkpoint StateID; TkaError::Decode for a malformed checkpoint/add.

Source

pub fn from_forked_chain( prefix: &[Aum], branches: &[&[Aum]], ) -> Result<Authority, TkaError>

Resolve a single fork point: a shared linear prefix (genesis→fork point, parent-ordered) followed by branches, the competing children of the fork point. The active child is chosen by [pick_next_aum]’s deterministic rules (weight → RemoveKey preference → lowest hash), evaluated against the state at the fork point, and applied. This is the consensus-critical selection every node must make identically; the linear Authority::from_chain is the common (no-fork) case.

Each branch must be exactly one AUM. In this single-AUM-per-branch shape the choice is provably identical to Go’s pickNextAUM over the fork point’s children. A multi-step branch is rejected (TkaError::BadChain) rather than mis-resolved: Go re-runs pickNextAUM at every link (advanceByPrimary), re-evaluating weight against the evolving state, so judging a whole multi-AUM branch by its first AUM alone could pick a different active head than Go and silently fork the trusted-key set. Implementing the per-step loop (and a general multi-fork DAG walk) is deferred to when the sync layer can actually surface such a chain; until then this guard keeps the model honest. (The common re-bootstrap case — competing single-AUM heads — is fully covered.)

§Errors

As Authority::from_chain, plus TkaError::BadChain if branches is empty, or any branch is not exactly one AUM.

Source§

impl Authority

Source

pub fn sync_offer( &self, storage: &dyn AumStore, oldest: AumHash, ) -> Result<SyncOffer, TkaError>

Build the SyncOffer this authority would send a peer (Go Authority.SyncOffer): its head plus an exponentially-spaced sample of ancestors back to oldest, ending with oldest. oldest is the oldest AUM the caller holds (Go a.oldestAncestor.Hash()); our verify-only Authority does not track it, so it is passed in — typically the genesis hash of the chain the caller staged in storage.

storage must contain the chain from head back to oldest; a gap simply truncates the ancestor list early (the walk breaks on the first missing parent, exactly like Go).

Source

pub fn missing_aums( &self, storage: &dyn AumStore, remote_offer: &SyncOffer, oldest: AumHash, ) -> Result<Vec<Aum>, TkaError>

Given a peer’s SyncOffer, compute the AUMs they are missing — the ones to send them so their chain catches up to ours (Go Authority.MissingAUMs). storage must hold our chain. Returns an empty Vec when the peer is already up to date.

Mirrors Go: compute our own offer, find the intersection of the two chains, then gather every AUM from the intersection forward to our head (excluding the intersection AUM itself).

Trait Implementations§

Source§

impl Clone for Authority

Source§

fn clone(&self) -> Authority

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 Authority

Source§

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

Formats the value using the given formatter. 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> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Converts Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Converts Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Converts &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Converts &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> DowncastSend for T
where T: Any + Send,

Source§

fn into_any_send(self: Box<T>) -> Box<dyn Any + Send>

Converts Box<Trait> (where Trait: DowncastSend) to Box<dyn Any + Send>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

impl<T> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_sync(self: Box<T>) -> Box<dyn Any + Send + Sync>

Converts Box<Trait> (where Trait: DowncastSync) to Box<dyn Any + Send + Sync>, which can then be downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Converts Arc<Trait> (where Trait: DowncastSync) to Arc<Any>, which can then be downcast into Arc<ConcreteType> where ConcreteType implements Trait.
Source§

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

Source§

fn __clone_box(&self, _: Private) -> *mut ()

Source§

impl<A, T> DynMessage<A> for T
where A: Actor + Message<T>, T: Send + 'static,

Source§

fn handle_dyn<'a>( self: Box<T>, state: &'a mut A, actor_ref: ActorRef<A>, tx: Option<Sender<Result<Box<dyn Any + Send>, SendError<Box<dyn Any + Send>, Box<dyn Any + Send>>>>>, stop: &'a mut bool, ) -> Pin<Box<dyn Future<Output = Result<(), Box<dyn ReplyError>>> + Send + 'a>>

Handles the dyn message with the provided actor state, ref, and reply sender.
Source§

fn as_any(self: Box<T>) -> Box<dyn Any>

Casts the type to a Box<dyn Any>.
Source§

impl<T> ErasedDestructor for T
where T: 'static,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

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

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> ReplyError for T
where T: Debug + Send + 'static,

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, 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.
Source§

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

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more