Skip to main content

PersistState

Struct PersistState 

Source
pub struct PersistState {
    pub machine_key: MachinePrivateKey,
    pub network_lock_key: NetworkLockPrivateKey,
    pub node_key: NodePrivateKey,
    pub old_node_key: Option<NodePublicKey>,
    pub acme_account_key: Option<Zeroizing<Vec<u8>>>,
}
Expand description

The portion of the key state that should be retained between runs of the same device.

Disco keys are ephemeral and should be generated anew each time a device runs, so are excluded from this state.

§At-rest protection is the embedder’s responsibility

The secret-bearing fields here are zeroized in memory on drop (the dedicated key types and the Zeroizing-wrapped ACME account key), but that is an in-process hygiene measure only. Protecting this state at rest — restrictive file permissions (e.g. 0o600), full-disk or filesystem encryption, secure-enclave/keyring storage — is entirely the responsibility of the embedding application that serializes and writes it to durable storage. This crate neither reads nor writes files and makes no at-rest guarantee (see SECURITY.md).

Fields§

§machine_key: MachinePrivateKey

The MachinePrivateKey for the hardware this Tailnet peer runs on.

§network_lock_key: NetworkLockPrivateKey

The NetworkLockPrivateKey for this Tailnet peer, for use with Tailnet Lock.

§node_key: NodePrivateKey

The NodePrivateKey for this Tailnet peer.

§old_node_key: Option<NodePublicKey>

The node’s PREVIOUS node public key, recorded during a node-key rotation so the next registration sends it as RegisterRequest.OldNodeKey for key continuity (Go’s regen flow). None outside a rotation (the default). Reactive / embedder-driven — matching Go, this fork does NOT auto-rotate the node key before expiry (Go deliberately doesn’t either; key expiry is a human-re-auth control). See PersistState::rotate_node_key.

§acme_account_key: Option<Zeroizing<Vec<u8>>>

The persisted ACME account key (PKCS#8 DER of an ECDSA P-256 key), or None if no ACME account has been provisioned for this node. The acme cert-issuance path loads this to keep the same Let’s Encrypt account identity across renewals; absent, the runtime generates an ephemeral per-call key (a new ACME account each issuance). #[serde(default)] so key files written before this field load as None (mirrors old_node_key).

Wrapped in Zeroizing so the DER private-key bytes are wiped from memory on drop. Zeroizing<Vec<u8>> serializes transparently via its inner Vec, so the persisted JSON shape is identical to a bare Vec<u8> (a byte array).

Implementations§

Source§

impl PersistState

Source

pub fn rotate_node_key(&mut self)

Rotate the node key for re-registration, mirroring Go’s regen flow: record the current node public key as old_node_key and replace the node key with a freshly-generated one. The next registration that uses this state will send the prior key as RegisterRequest.OldNodeKey, so control links the new node key to the node’s existing identity instead of treating it as a brand-new node.

This is the embedder-driven rotation primitive (re-create the device with the returned state). It is reactive, NOT a pre-expiry auto-rotator: Go has no such timer, because node-key expiry is a deliberate periodic human/IdP re-attestation control. Re-registration still requires a valid auth credential, exactly as a fresh registration does.

Trait Implementations§

Source§

impl Clone for PersistState

Source§

fn clone(&self) -> PersistState

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 PersistState

Source§

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

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

impl Default for PersistState

Source§

fn default() -> PersistState

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

impl<'de> Deserialize<'de> for PersistState

Source§

fn deserialize<__D>( __deserializer: __D, ) -> Result<PersistState, <__D as Deserializer<'de>>::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl From<&NodeState> for PersistState

Source§

fn from(value: &NodeState) -> PersistState

Converts to this type from the input type.
Source§

impl From<&PersistState> for NodeState

Source§

fn from(value: &PersistState) -> NodeState

Converts to this type from the input type.
Source§

impl From<NodeState> for PersistState

Source§

fn from(value: NodeState) -> PersistState

Converts to this type from the input type.
Source§

impl From<PersistState> for NodeState

Source§

fn from(value: PersistState) -> NodeState

Converts to this type from the input type.
Source§

impl Serialize for PersistState

Source§

fn serialize<__S>( &self, __serializer: __S, ) -> Result<<__S as Serializer>::Ok, <__S as Serializer>::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. 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> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

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 + Sync + Send>

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 + Sync + Send>

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