Trait Provider

Source
pub trait Provider: Send + Sync {
    // Required methods
    fn get(
        &self,
        project: &str,
        key: &str,
        profile: &str,
    ) -> Result<Option<SecretString>>;
    fn set(
        &self,
        project: &str,
        key: &str,
        value: &SecretString,
        profile: &str,
    ) -> Result<()>;
    fn name(&self) -> &'static str;

    // Provided methods
    fn allows_set(&self) -> bool { ... }
    fn reflect(&self) -> Result<HashMap<String, Secret>> { ... }
}
Expand description

Trait defining the interface for secret storage providers.

All secret storage backends must implement this trait to integrate with SecretSpec. The trait is designed to be flexible enough to support various storage mechanisms while maintaining a consistent interface.

§Thread Safety

Providers must be Send + Sync as they may be used across thread boundaries in multi-threaded applications.

§Profile Support

Providers should support profile-based secret isolation, allowing different values for the same key across environments (e.g., development, staging, production).

§Implementation Guidelines

  • Providers should handle their own error cases and return appropriate Result types
  • Storage paths should follow the pattern: {provider}/{project}/{profile}/{key}
  • Providers may choose to be read-only by overriding allows_set
  • Provider names should be lowercase and descriptive

Required Methods§

Source

fn get( &self, project: &str, key: &str, profile: &str, ) -> Result<Option<SecretString>>

Retrieves a secret value from the provider.

§Arguments
  • project - The project namespace for the secret
  • key - The secret key/name to retrieve
  • profile - The profile context (e.g., “default”, “production”)
§Returns
  • Ok(Some(value)) if the secret exists
  • Ok(None) if the secret doesn’t exist
  • Err if there was an error accessing the provider
§Example
match provider.get("myapp", "DATABASE_URL", "production")? {
    Some(url) => println!("Database URL: {}", url),
    None => println!("DATABASE_URL not found"),
}
Source

fn set( &self, project: &str, key: &str, value: &SecretString, profile: &str, ) -> Result<()>

Stores a secret value in the provider.

§Arguments
  • project - The project namespace for the secret
  • key - The secret key/name to store
  • value - The secret value to store
  • profile - The profile context (e.g., “default”, “production”)
§Returns
  • Ok(()) if the secret was successfully stored
  • Err if there was an error or the provider is read-only
§Errors

This method should return an error if allows_set returns false.

§Example
provider.set("myapp", "API_KEY", "secret123", "production")?;
Source

fn name(&self) -> &'static str

Returns the name of this provider.

This should match the name registered with the provider macro.

Provided Methods§

Source

fn allows_set(&self) -> bool

Returns whether this provider supports setting values.

By default, providers are assumed to support writing. Read-only providers (like environment variables) should override this to return false.

§Returns
  • true if the provider supports set operations
  • false if the provider is read-only
§Example
if provider.allows_set() {
    provider.set("myapp", "TOKEN", "value", "default")?;
} else {
    eprintln!("Provider is read-only");
}
Source

fn reflect(&self) -> Result<HashMap<String, Secret>>

Discovers and returns all secrets available in this provider.

This method is used to introspect the provider and find all available secrets. It’s particularly useful for importing secrets from external sources.

§Returns

A HashMap where keys are secret names and values are Secret configurations. The default implementation returns an empty map, indicating the provider doesn’t support reflection.

§Example
let secrets = provider.reflect()?;
for (name, secret) in secrets {
    println!("Found secret: {} = {:?}", name, secret);
}

Trait Implementations§

Source§

impl TryFrom<&Url> for Box<dyn Provider>

Source§

type Error = SecretSpecError

The type returned in the event of a conversion error.
Source§

fn try_from(url: &Url) -> Result<Self>

Performs the conversion.
Source§

impl TryFrom<&str> for Box<dyn Provider>

Source§

type Error = SecretSpecError

The type returned in the event of a conversion error.
Source§

fn try_from(s: &str) -> Result<Self>

Performs the conversion.
Source§

impl TryFrom<String> for Box<dyn Provider>

Source§

fn try_from(s: String) -> Result<Self>

Creates a provider instance from a URI string.

This function handles various URI formats and normalizes them before parsing. It supports both full URIs and shorthand notations.

§URI Formats
  • Full URI: scheme://authority/path (e.g., onepassword://vault/Production)
§Special Cases
  • 1password: Will error suggesting to use onepassword instead
  • Bare provider names: Automatically converted to provider://
§Examples
use std::convert::TryFrom;

// Simple provider name
let provider = Box::<dyn Provider>::try_from("keyring".to_string())?;

// Full URI with configuration
let provider = Box::<dyn Provider>::try_from("onepassword://vault/Production".to_string())?;

// Dotenv with path
let provider = Box::<dyn Provider>::try_from("dotenv:.env.production".to_string())?;
Source§

type Error = SecretSpecError

The type returned in the event of a conversion error.

Implementors§