Struct PairingGuard
pub struct PairingGuard { /* private fields */ }Implementations§
Source§impl PairingGuard
impl PairingGuard
Sourcepub fn new(
require_pairing: bool,
existing_tokens: &[String],
code_policy: PairingCodePolicy,
) -> Self
pub fn new( require_pairing: bool, existing_tokens: &[String], code_policy: PairingCodePolicy, ) -> Self
Build a guard, minting the startup code under code_policy.
The policy is not retained. PairingGuard outlives any number of
config writes, and root AGENTS.md forbids snapshotting live policy
into a long-lived handle — a code minted after an operator strengthens
[gateway.pairing_code] must use the new policy without a restart.
Every later mint therefore takes the policy the caller resolved from
live config at that moment.
Sourcepub fn rotate_admin_token(&self, data_dir: &Path) -> Result<String>
pub fn rotate_admin_token(&self, data_dir: &Path) -> Result<String>
Start a new admin-token generation: forget the current token, mint a
fresh one, write it owner-only into data_dir, and accept it only
once the file is in place. On any failure the guard accepts no admin
token at all, and whatever file an earlier run left behind never
matches, so the pairing-code admin routes fail closed.
Sourcepub fn admin_token_matches(&self, presented: &str) -> bool
pub fn admin_token_matches(&self, presented: &str) -> bool
True only when presented equals this run’s admin token, compared in
constant time. With no successful rotation, nothing matches.
Sourcepub fn pairing_code(&self) -> Option<String>
pub fn pairing_code(&self) -> Option<String>
The one-time pairing code (generated only on first startup when no tokens exist).
Sourcepub fn require_pairing(&self) -> bool
pub fn require_pairing(&self) -> bool
Whether pairing is required at all.
Sourcepub async fn reserve_pair_unkeyed(
&self,
code: &str,
) -> Option<PairingReservation>
pub async fn reserve_pair_unkeyed( &self, code: &str, ) -> Option<PairingReservation>
Code check WITHOUT per-client lockout accounting, for callers whose
peers all share one network identity and which apply their own
class-wide rate policy instead. The relay enrollment bridge is the
canonical case: every relay-routed client reaches the daemon from
loopback, so keying lockout on the peer address would let five wrong
codes from ONE hostile client lock out EVERY relay-routed enrollee
(shared-fate lockout). Never expose this to a caller that has a real
per-client identity - use PairingGuard::reserve_pair there.
pub async fn reserve_pair( &self, code: &str, client_id: &str, ) -> Result<Option<PairingReservation>, u64>
Sourcepub async fn try_pair(
&self,
code: &str,
client_id: &str,
) -> Result<Option<String>, u64>
pub async fn try_pair( &self, code: &str, client_id: &str, ) -> Result<Option<String>, u64>
Attempt to pair with the given code. Returns a bearer token on success.
Returns Err(lockout_seconds) if locked out due to brute force.
client_id identifies the client for per-client lockout accounting.
Sourcepub fn is_authenticated(&self, token: &str) -> bool
pub fn is_authenticated(&self, token: &str) -> bool
Check if a bearer token is valid (compares against stored hashes).
Sourcepub fn token_is_paired(&self, token: &str) -> bool
pub fn token_is_paired(&self, token: &str) -> bool
Strict membership check for inbound authentication: whether token
hashes to a currently-paired token, regardless of require_pairing.
The gateway’s is_authenticated convenience fails OPEN when pairing
is disabled, which is only correct on surfaces that already treat
the transport as trusted — an auth provider must use this instead,
so an empty token set denies everything.
Sourcepub fn token_hash_is_paired(&self, token_hash: &str) -> bool
pub fn token_hash_is_paired(&self, token_hash: &str) -> bool
Strict membership check by pre-computed SHA-256 hash (see
Self::token_is_paired). Lets an established connection re-check
liveness of its pairing without retaining the bearer itself.
Sourcepub fn hold_paired_tokens(&self) -> HeldPairedTokens<'_>
pub fn hold_paired_tokens(&self) -> HeldPairedTokens<'_>
Hold the paired-token set still: no token can be paired or revoked until the returned guard is dropped, while other readers proceed.
For a caller that must keep a liveness decision true through the effect it guards. Keep the hold short, and do not call this guard’s other methods while holding it: a pairing or revocation queued behind the hold makes a second read on the same thread wait forever.
Sourcepub fn is_paired(&self) -> bool
pub fn is_paired(&self) -> bool
Returns true if the gateway is already paired (has at least one token).
pub fn revoke_token(&self, token: &str) -> bool
Sourcepub fn revoke_token_hash(&self, token_hash: &str) -> bool
pub fn revoke_token_hash(&self, token_hash: &str) -> bool
Revoke a paired token by its SHA-256 hash. Returns true if removed.
pub fn revoke_all_tokens(&self) -> usize
Sourcepub fn generate_new_pairing_code(
&self,
code_policy: PairingCodePolicy,
) -> Option<String>
pub fn generate_new_pairing_code( &self, code_policy: PairingCodePolicy, ) -> Option<String>
Generate a new pairing code that pairs an additional client.
Does not revoke existing tokens. To rotate a compromised token,
pair with revoke_token/revoke_token_hash + a config persist pass.
code_policy is passed per call, resolved by the caller from live
config at this moment — the guard holds no policy of its own, so an
operator who strengthens [gateway.pairing_code] sees the next code
follow the new policy without a restart.
Sourcepub fn generate_pairing_code_if_vacant(
&self,
code_policy: PairingCodePolicy,
) -> Result<String, GeneratePairingCodeError>
pub fn generate_pairing_code_if_vacant( &self, code_policy: PairingCodePolicy, ) -> Result<String, GeneratePairingCodeError>
Issue a code only if no code is currently pending.
code_policy is resolved per call for the same reason as
Self::generate_new_pairing_code.
Sourcepub fn token_hash(token: &str) -> String
pub fn token_hash(token: &str) -> String
Get the token hash for a given plaintext token (for device registry lookup).
Sourcepub fn authenticate_and_hash(&self, token: &str) -> Option<String>
pub fn authenticate_and_hash(&self, token: &str) -> Option<String>
Check if a token is paired and return its hash.
Trait Implementations§
Source§impl Clone for PairingGuard
impl Clone for PairingGuard
Source§fn clone(&self) -> PairingGuard
fn clone(&self) -> PairingGuard
1.0.0 (const: unstable) · §fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
impl !RefUnwindSafe for PairingGuard
impl !UnwindSafe for PairingGuard
impl Freeze for PairingGuard
impl Send for PairingGuard
impl Sync for PairingGuard
impl Unpin for PairingGuard
impl UnsafeUnpin for PairingGuard
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
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