Skip to main content

Secret

Struct Secret 

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

Secure credential storage and management system.

This structure manages the complete lifecycle of sensitive credentials including user prompting, encryption, file storage, and decryption. It provides a high-level interface for secure credential handling.

ยงDesign Principles

  • Lazy Loading: Passwords only decrypted when needed
  • Immutable State: Credential changes create new instances
  • Error Recovery: Graceful handling of encryption/decryption failures
  • User Friendly: Clear prompts and error messages

ยงInternal State

The struct maintains both encrypted and decrypted state:

  • File-based encrypted storage for persistence
  • Memory-based decrypted storage for immediate use
  • Cryptographic keys for encryption/decryption operations

ยงLifecycle

  1. Creation: Initialize with file path and user prompt
  2. Retrieval: Check for existing encrypted file
  3. Prompting: Secure password input when needed
  4. Encryption: AES encryption before file storage
  5. Decryption: AES decryption when retrieving

Implementationsยง

Sourceยง

impl Secret

Source

pub fn new(secret_name: &str, prompt: &str) -> Self

Creates a new Secret instance for credential management.

This constructor initializes a new secret manager with the specified file storage location and user prompt text. It loads encryption keys from compile-time embedded metadata and prepares the file path within the applicationโ€™s data directory.

ยงKey Management

Encryption keys are loaded from compile-time metadata:

  • Keys embedded during build process for security
  • Consistent keys across application installations
  • No runtime key generation or derivation needed
ยงFile Path Resolution

The secret file path is resolved using the applicationโ€™s data storage:

  • Platform-appropriate user data directory
  • Service-specific filename for credential isolation
  • Automatic directory creation when needed
ยงArguments
  • secret_name - Filename for storing encrypted credentials (e.g., โ€œ.jira_secretโ€)
  • prompt - User-facing text for password prompts (e.g., โ€œEnter your Jira passwordโ€)
ยงReturns

A new Secret instance ready for credential operations.

ยงExamples
use kasl::libs::secret::Secret;

// Jira password management
let jira_secret = Secret::new(".jira_secret", "Enter your Jira password");

// GitLab token management
let gitlab_secret = Secret::new(".gitlab_token", "Enter your GitLab API token");

// SI Server credentials
let si_secret = Secret::new(".si_credentials", "Enter your SI Server password");
ยงError Handling

Path resolution errors are handled gracefully by falling back to the current directory if the data storage path cannot be created.

Source

pub fn get_or_prompt(&self) -> Result<String>

Retrieves password from cache or prompts user if not available.

This method implements the primary credential retrieval logic:

  1. Check if encrypted file exists and is readable
  2. Attempt to decrypt existing credentials
  3. Prompt user for new credentials if decryption fails
  4. Encrypt and store new credentials for future use
ยงCaching Behavior
  • Cache Hit: Return decrypted password from file
  • Cache Miss: Prompt user and store new password
  • Decryption Error: Re-prompt user (file may be corrupted)
ยงError Recovery

If decryption fails (corrupted file, wrong keys, etc.), the method gracefully falls back to prompting the user for new credentials. This ensures the application can recover from storage corruption.

ยงReturns

Returns the userโ€™s password, either from cache or fresh input.

ยงErrors

Returns an error if:

  • User cancels password prompt
  • File system operations fail
  • Encryption operations fail
ยงExamples
use kasl::libs::secret::Secret;

let secret = Secret::new(".api_token", "Enter API token");

// First call prompts user and caches result
let token = secret.get_or_prompt()?;

// Subsequent calls use cached value
let same_token = secret.get_or_prompt()?;
Source

pub fn try_get_cached(&self) -> Option<String>

Returns a cached password without prompting the user.

Used by background daemons that must not block on stdin. Returns None when the secret file is missing or cannot be decrypted.

Source

pub fn prompt(&self) -> Result<String>

Prompts user for password and stores it securely.

This method handles the complete password input and storage workflow:

  1. Display secure password prompt (no echo)
  2. Encrypt the entered password
  3. Store encrypted data to file
  4. Return the entered password
ยงSecurity Features
  • No Echo: Password characters not displayed on screen
  • Immediate Encryption: Password encrypted before file storage
  • Memory Clearing: Original password cleared after encryption
ยงUser Experience

The prompt uses a colorful theme for better visibility and provides clear instructions to the user. Password input is handled securely without displaying characters.

ยงReturns

Returns the password entered by the user.

ยงErrors

Returns an error if:

  • User cancels password input (Ctrl+C)
  • Password encryption fails
  • File system write operations fail
ยงExamples
use kasl::libs::secret::Secret;

let secret = Secret::new(".password", "Enter your password");

// Force password prompt (ignores cache)
let password = secret.prompt()?;

Trait Implementationsยง

Sourceยง

impl Clone for Secret

Sourceยง

fn clone(&self) -> Secret

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 Secret

Sourceยง

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

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<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Sourceยง

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

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> 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> PolicyExt for T
where T: ?Sized,

Sourceยง

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Sourceยง

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Sourceยง

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

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