-
Notifications
You must be signed in to change notification settings - Fork 18
Open
Labels
enhancementNew feature or requestNew feature or request
Description
I'm using this pattern to load SS in Rust (note there's a macro bug workaround in there, too):
use std::sync::OnceLock;
use secretspec::Resolved;
// Generate typed structs from secretspec.toml
secretspec_derive::declare_secrets!("../secretspec.toml");
// Constants for default provider and profile
pub const PROVIDER: &str = "onepassword://SecretSpecMetacortex";
pub const PROFILE: &str = "default";
// Global SecretSpec instance
static SECRETSPEC: OnceLock<Resolved<SecretSpec>> = OnceLock::new();
/// Get a reference to the global SecretSpec instance
/// Lazily initializes on first access
///
/// NOTE: This uses a workaround for a bug in secretspec where the builder pattern
/// strips vault information from onepassword URIs. The builder extracts only the
/// provider name (e.g., "onepassword") from URIs like "onepassword://VaultName",
/// losing the vault specification.
///
/// TODO: Switch to builder pattern when the bug is fixed:
/// ```
/// SecretSpec::builder()
/// .with_provider(PROVIDER)
/// .with_profile(Profile::Default)
/// .load()
/// ```
///
/// Current workaround uses side-effect based API where `secretspec::Secrets`
/// is a global singleton that holds configuration. When we call set_provider()
/// and set_profile(), we're modifying global state that SecretSpec::load()
/// then reads from.
///
/// PERFORMANCE WARNING: Initial load is VERY slow (~40s for 39 secrets) because
/// SecretSpec appears to make individual `op` CLI calls for each secret instead
/// of batching them. The OnceLock ensures this only happens once per process.
pub fn secretspec() -> &'static Resolved<SecretSpec>
{
SECRETSPEC.get_or_init(|| {
// Load mutable Secrets and set provider/profile directly to preserve vault info
let mut spec =
secretspec::Secrets::load().expect("Failed to load Secrets");
spec.set_provider(PROVIDER);
spec.set_profile(PROFILE);
// Now load SecretSpec using the configured spec
// This will use the provider/profile we just set
SecretSpec::load(None::<String>, None::<Profile>)
.expect("Failed to load SecretSpec")
})
}I want to use SecretSpec for the type safety (Secret expects string args), but it loads all my secrets at startup.
With OnePassword this is very slow!
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request