Skip to main content

SecretManager

Struct SecretManager 

Source
pub struct SecretManager<B, E, const V: usize = 256, const S: usize = 32>{ /* private fields */ }
Expand description

Convenience facade that runs a SecretSyncer and a KeyRotator together.

SecretManager is the right choice when a single service instance should both rotate keys and consume them. Internally it:

  1. Calls SecretSyncer::initial_load synchronously so the ring is hydrated before start returns (any failure is propagated as the Err variant).
  2. Spawns the syncer and rotator as independent tokio tasks that run until the CancellationToken is cancelled.

The SecretGroup trait is forwarded to the inner InMemorySecretGroup so you can call current and resolve directly on the manager.

For split deployments — a dedicated rotation service plus many reader nodes — use KeyRotator and SecretSyncer independently instead.

§Type parameters

Implementations§

Source§

impl<B, E, const V: usize, const S: usize> SecretManager<B, E, V, S>

Source

pub fn new( group_id: impl Into<String>, group: Arc<InMemorySecretGroup<V, S>>, backend: B, encryptor: E, rotation_interval: Duration, propagation_delay: Duration, poll_interval: Option<Duration>, generate_key: Option<fn() -> [u8; S]>, ) -> Self

Create a new SecretManager.

§Arguments
  • group_id — identifies the logical key group in storage
  • group — the ring buffer that will be kept hydrated; typically wrapped in Arc so application code can read it concurrently
  • backend — implements both SecretBackend (read) and SecretRotationBackend (write)
  • encryptor — encrypts keys on write, decrypts on read
  • rotation_interval — how long a key lives before a new one is generated
  • propagation_delay — head-start given to syncers before a new key becomes current; set to at least your maximum expected poll latency
  • poll_interval — how often the syncer polls for new keys; None uses 5 seconds
  • generate_key — custom key-material generator; None uses a CSPRNG fill
Source

pub async fn start( self, token: CancellationToken, ) -> Result<SecretManagerHandle, <B as SecretBackend>::Error>

Hydrate the ring buffer and spawn background tasks.

Performs the initial load synchronously — if it fails the error is returned and no tasks are spawned. On success, the syncer and rotator are launched and a SecretManagerHandle is returned.

§Graceful shutdown
let token = CancellationToken::new();
let handle = SecretManager::new("payments-signing", group, backend, encryptor,
    Duration::from_secs(3600), Duration::from_secs(30), None, None)
    .start(token.clone()).await?;

// … serve traffic …

token.cancel();      // signal tasks to stop
handle.wait().await; // block until both tasks have exited

Trait Implementations§

Source§

impl<B, E, const V: usize, const S: usize> SecretGroup<V, S> for SecretManager<B, E, V, S>

Source§

fn current(&self) -> (u8, [u8; S])

Return (current_version, key_bytes).
Source§

fn resolve(&self, version: u8) -> Option<[u8; S]>

Look up a key by version. Returns None for slots that have never been written.

Auto Trait Implementations§

§

impl<B, E, const V: usize, const S: usize> Freeze for SecretManager<B, E, V, S>
where B: Freeze, E: Freeze,

§

impl<B, E, const V: usize = 256, const S: usize = 32> !RefUnwindSafe for SecretManager<B, E, V, S>

§

impl<B, E, const V: usize, const S: usize> Send for SecretManager<B, E, V, S>

§

impl<B, E, const V: usize, const S: usize> Sync for SecretManager<B, E, V, S>

§

impl<B, E, const V: usize, const S: usize> Unpin for SecretManager<B, E, V, S>
where B: Unpin, E: Unpin,

§

impl<B, E, const V: usize, const S: usize> UnsafeUnpin for SecretManager<B, E, V, S>
where B: UnsafeUnpin, E: UnsafeUnpin,

§

impl<B, E, const V: usize = 256, const S: usize = 32> !UnwindSafe for SecretManager<B, E, V, S>

Blanket Implementations§

Source§

impl<T> AggregateExpressionMethods for T

Source§

fn aggregate_distinct(self) -> Self::Output
where Self: DistinctDsl,

DISTINCT modifier for aggregate functions Read more
Source§

fn aggregate_all(self) -> Self::Output
where Self: AllDsl,

ALL modifier for aggregate functions Read more
Source§

fn aggregate_filter<P>(self, f: P) -> Self::Output
where P: AsExpression<Bool>, Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,

Add an aggregate function filter Read more
Source§

fn aggregate_order<O>(self, o: O) -> Self::Output
where Self: OrderAggregateDsl<O>,

Add an aggregate function order Read more
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> 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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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<Unshared, Shared> IntoShared<Shared> for Unshared
where Shared: FromUnshared<Unshared>,

Source§

fn into_shared(self) -> Shared

Creates a shared type from an unshared type.
Source§

impl<T> IntoSql for T

Source§

fn into_sql<T>(self) -> Self::Expression

Convert self to an expression for Diesel’s query builder. Read more
Source§

fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
where &'a Self: AsExpression<T>, T: SqlType + TypedExpressionType,

Convert &self to an expression for Diesel’s query builder. Read more
Source§

impl<T, Conn> RunQueryDsl<Conn> for T

Source§

fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
where Conn: AsyncConnectionCore + Send, Self: ExecuteDsl<Conn> + 'query,

Executes the given command, returning the number of rows affected. Read more
Source§

fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
where U: Send, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Executes the given query, returning a Vec with the returned rows. Read more
Source§

fn load_stream<'conn, 'query, U>( self, conn: &'conn mut Conn, ) -> Self::LoadFuture<'conn>
where Conn: AsyncConnectionCore, U: 'conn, Self: LoadQuery<'query, Conn, U> + 'query,

Executes the given query, returning a [Stream] with the returned rows. Read more
Source§

fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
where U: Send + 'conn, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Runs the command, and returns the affected row. Read more
Source§

fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
where U: Send, Conn: AsyncConnectionCore, Self: LoadQuery<'query, Conn, U> + 'query,

Runs the command, returning an Vec with the affected rows. Read more
Source§

fn first<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<<Self::Output as LoadQuery<'query, Conn, U>>::LoadFuture<'conn>, LoadNext<Pin<Box<<Self::Output as LoadQuery<'query, Conn, U>>::Stream<'conn>>>>>
where U: Send + 'conn, Conn: AsyncConnectionCore, Self: LimitDsl, Self::Output: LoadQuery<'query, Conn, U> + Send + 'query,

Attempts to load a single record. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
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> WindowExpressionMethods for T

Source§

fn over(self) -> Self::Output
where Self: OverDsl,

Turn a function call into a window function call Read more
Source§

fn window_filter<P>(self, f: P) -> Self::Output
where P: AsExpression<Bool>, Self: FilterDsl<<P as AsExpression<Bool>>::Expression>,

Add a filter to the current window function Read more
Source§

fn partition_by<E>(self, expr: E) -> Self::Output
where Self: PartitionByDsl<E>,

Add a partition clause to the current window function Read more
Source§

fn window_order<E>(self, expr: E) -> Self::Output
where Self: OrderWindowDsl<E>,

Add a order clause to the current window function Read more
Source§

fn frame_by<E>(self, expr: E) -> Self::Output
where Self: FrameDsl<E>,

Add a frame clause to the current window function Read more
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