All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- Provider URIs now support spaces and special characters in names
(e.g.,
onepassword://Home Lab). All providers receive automatically percent-decoded values via a newProviderUrlwrapper type. - dotenv provider: setting a secret no longer corrupts neighboring values
that contain double quotes, backslashes, dollar signs, or newlines
(e.g. JSON values). The underlying
serde-envfileserializer did not escape these characters; fix is pinned via a fork until lucagoslar/serde-envfile#6 lands upstream. Fixes #74.
- BWS (Bitwarden Secrets Manager) provider with async SDK integration, secret caching, and full read-write support (requires
--features bws)
secretspec-derivenow depends onsecretspecwithdefault-features = false, avoiding pulling in CLI and provider features when only the derive macro is used.
- All provider features (
gcsm,awssm,vault) are now enabled by default - AWS Secrets Manager (
awssm) provider: batch fetching viaBatchGetSecretValueAPI, reducing N sequential API calls to ceil(N/20) batched calls. For 30 secrets this means 2 API calls instead of 30. Note: requires thesecretsmanager:BatchGetSecretValueIAM permission in addition to existing permissions.
rsa_private_keysecret generation type: generates RSA private keys in PKCS1 PEM format, defaults to 2048 bits, configurable viagenerate = { bits = 4096 }
- Check provider authentication (e.g. OnePassword, LastPass) before prompting
user for secrets, via a
PreflightGuardthat runs the check exactly once per provider instance
- HashiCorp Vault / OpenBao (
vault) provider for Vault KV v1/v2 secret storage, with support for namespaces, TLS configuration, and OpenBao compatibility (requires--features vault) - AWS Secrets Manager (
awssm) provider for AWS secret storage integration (requires--features awssm) - Support running secretspec from subdirectories: the CLI now walks up the directory tree to find the nearest
secretspec.toml, similar tocargoandgit. Also adds a-f/--fileflag (andSECRETSPEC_FILEenv var) to explicitly specify the config file path (#59)
- Extract shared
block_onasync helper from AWSSM and GCSM providers intoprovider::block_on
- GCSM provider no longer panics when called from within an existing tokio runtime
- Keyring and pass providers now support
folder_prefixvia URI (e.g.,keyring://secretspec/shared/{profile}/{key}) to share secrets across projects, matching the existing OnePassword and LastPass behavior
- Support
XDG_CONFIG_HOMEon macOS by switching fromdirectoriestoetceteracrate. Existing macOS configs at~/Library/Application Support/secretspec/are automatically migrated to~/.config/secretspec/(#28)
- Reject empty values when setting a secret
- Improved interactive prompt for missing secrets: lists all missing secrets upfront with descriptions, adds step counter (
[1/3]), and usesinquire::Passwordfor consistent masked input. Removedrpassworddependency.
- Use a fork of inquire to support setting multi-line secrets (#32)
- Declarative secret generation: secrets can now be auto-generated when missing by adding
typeandgeneratefields to secret config. Supported types:password,hex,base64,uuid, andcommand(for arbitrary shell commands). Generation triggers duringcheck/runwhen a secret is missing, and the generated value is stored via the configured provider.
- OnePassword provider: Significant performance improvement by caching authentication status and using batch fetching with parallel threads. Reduces CLI calls from 2N sequential to ~2 sequential + N parallel for N secrets.
- CLI: Add
--no-prompt(-n) flag tosecretspec checkcommand for non-interactive mode. When used, the command exits with non-zero status if secrets are missing instead of prompting for values. Useful for CI/CD pipelines, scripts, and automation. (#55)
- OnePassword provider: Fix duplicate item creation when existing item has no extractable value.
Now uses
op item listfor existence checks and updates by item ID to avoid ambiguity. - OnePassword provider: Handle "More than one item matches" error gracefully by falling back to ID-based lookup.
- Google Cloud Secret Manager (GCSM) provider for GCP secret storage integration (#53)
- LastPass provider: Fix creating new secrets by using correct
lpass addcommand instead of non-existentlpass set(#54)
- CI: Updated macOS runners from deprecated macos-13 to macos-15 (Intel) and macos-latest (ARM)
- Pass (password-store) provider for Unix password manager integration
ensure_secrets()method is now public in the Rust SDK- Support specifying full file paths (ending in
.toml) inextendsfield, in addition to directory paths
- Performance: avoid double validation in
check()for happy path
- Display correct error message when extended config file is not found, instead of the misleading "No secretspec.toml found in current directory" error
- OnePassword provider: Support for
SECRETSPEC_OPCLI_PATHenvironment variable to specify custom path to the OnePassword CLI - OnePassword provider: Automatic detection of Windows Subsystem for Linux 2 (WSL2) and use of
op.exeon that platform - Documentation for
as_pathoption in configuration reference, Rust SDK docs, and landing page - Documentation for per-secret providers with fallback chains on landing page
- OnePassword provider: Use stdin instead of temporary files when creating items for WSL2 compatibility (WSL paths are invalid when passed to Windows executables)
- Output status/progress messages to stderr instead of stdout, fixing direnv integration where stdout was evaluated as shell code
- Profile-level default configuration:
profiles.<name>.defaultssection for shared settings across secrets in a profile - Default providers for profiles: define common providers once and have all secrets use them unless overridden
- Default values and required settings can now be specified at profile level to reduce repetition
as_pathoption for secrets: write secret values to temporary files and return the file path instead of the value. Temporary files are automatically cleaned up when the resolved secrets are dropped in Rust SDK usage. For CLI commands (getandcheck), temporary files are persisted and NOT deleted after the command exits. In the Rust SDK, fields withas_path = trueare generated asPathBuforOption<PathBuf>instead ofString
- Secret
requiredfield is nowOption<bool>to allow profile-level defaults to apply when not explicitly set - Secret
defaultfield can now inherit from profile-level defaults if not specified per-secret - Secret
providersfield can now inherit from profile-level defaults if not specified per-secret - Profile defaults only apply to secrets that don't explicitly set these fields
Secrets::check()now returnsResult<ValidatedSecrets>instead ofResult<()>, allowing callers to access the validated secrets
- CLI: Count optional secrets as "found" in the summary
- Support for piping multi-line secrets via stdin
- Import command now resolves secrets from all profiles, not just the active profile (fixes issue #36)
- Fix incorrect stats in the summary for certain configurations
- Installers for arm/linux
- Integrate
secrecycrate for secure secret handling with automatic memory zeroing - Add
reflect()method to Provider trait for provider introspection - Export
Providertrait from secretspec crate for use in derived code
- Made keyring provider optional via
keyringfeature flag (enabled by default) - Unified provider parsing logic in init command to support all provider formats consistently
- Downgraded keyring dependency to 3.6.2
- Updated
with_providerin derive macro to acceptTryInto<Box<dyn Provider>>for consistent provider handling
- Fixed secret optionality logic: having a default value no longer makes a secret optional in generated types
- SDK: Added
set_provider()andset_profile()methods for configuration - SDK: Removed provider/profile parameters from
set(),get(),check(),validate(), andrun()methods - SDK: Embedded Resolved inside ValidatedSecrets
- Fix stdin handling for piped input in set/check commands
- Fix SECRETSPEC_PROFILE and SECRETSPEC_PROVIDER environment variable resolution
- Ensure CLI arguments take precedence over environment variables
- add CLI integration tests
- Update test script to handle non-TTY environments correctly
- SDK: Hide internal functions
secretspec --version
- Profile inheritance: fields are merged with current profile taking precedence
Initial release of SecretSpec - a declarative secrets manager for development workflows.