When commiting changes related to Rust, make sure to update /CHANGELOG.md with one entry (can be multi-line).
SecretSpec is a declarative secrets manager for development workflows written in Rust. It provides a CLI tool and Rust library for managing environment variables and secrets across different environments using multiple storage backends (keyring, dotenv, environment variables, OnePassword, LastPass).
# Enter development environment
devenv shell
# Run tests
cargo test --all
# Run a single test
cargo test test_name
# Run the CLI
cargo run -- <command>
cargo run -- init --from .env
cargo run -- check
cargo run -- set DATABASE_URL
cargo run -- run -- npm start
# Format code / Run linter
pre-commit run -aThe project is organized as a Rust workspace with two crates:
-
secretspec (src/): Main CLI and library
bin/secretspec.rs: CLI entry point that calls the main CLI modulecli/mod.rs: CLI command definitions (init, config, set/get, check, run, import)lib.rs: Core library withSecretsstruct, validation logic, and CRUD operationsconfig.rs: Core configuration types (Config, Secret), TOML parsing, and inheritance logicprovider/: Storage backend implementations with trait-based plugin architecture
-
secretspec-derive: Proc macro for type-safe code generation
- Reads
secretspec.tomlat compile time - Generates strongly-typed structs from configuration
- Supports both union types (safe for any profile) and profile-specific types
- Validates secret names produce valid Rust identifiers
- Reads
The provider system uses a trait-based architecture defined in src/provider/mod.rs. When implementing new providers:
- Create module in
src/provider/your_provider.rs - Implement the
Providertrait with methods:get(),set(),allows_set(),name(),description() - Use the
#[provider]macro for automatic registration - Handle profile-aware storage paths (e.g.,
secretspec/{project}/{profile}/{key})
Providers support URI-based configuration (e.g., keyring://, onepassword://vault, dotenv://.env.production). The provider system handles URI parsing and provider instantiation directly within each provider module.
When adding a new provider, update these files:
docs/src/content/docs/providers/<provider>.md- Create the provider's doc pagedocs/astro.config.mjs- Add to sidebar navigation under "Providers"docs/src/content/docs/concepts/providers.md- Add to "Available Providers" tabledocs/src/content/docs/reference/providers.md- Add provider section and update "Security Considerations" tableREADME.md- Add to "Providers" list
- CLI flag (
--profile) - Environment variable (
SECRETSPEC_PROFILE) - User config default
- Falls back to "default" profile
- Per-secret providers (with fallback chain): specified in
secretspec.tomlasproviders: [alias1, alias2, ...]- Aliases resolved against
~/.config/secretspec/config.tomlproviders map - Tries each provider in order until secret is found
- Aliases resolved against
- CLI flag (
--provider) - Environment variable (
SECRETSPEC_PROVIDER) - User config default provider
- Falls back to keyring provider
Secrets can specify their own providers using the providers field to override global defaults:
[profiles.production]
DATABASE_URL = { description = "Production DB", providers = ["prod_vault", "keyring"] }
API_KEY = { description = "API Key", providers = ["shared"] }
GITHUB_TOKEN = { description = "GitHub token from env", providers = ["env"] }Provider aliases are defined in ~/.config/secretspec/config.toml:
[defaults]
provider = "keyring"
[providers]
prod_vault = "onepassword://vault/Production"
shared = "onepassword://vault/Shared"
env = "env://"Or managed via CLI:
# Add provider alias
secretspec config provider add prod_vault "onepassword://vault/Production"
# List all aliases
secretspec config provider list
# Remove alias
secretspec config provider remove prod_vault- Check active profile for secret
- Fall back to "default" profile
- Apply defaults if configured
- Validate required secrets are present
Projects can extend other configurations via extends = ["../shared/common"]. The system loads configs recursively and merges them with proper precedence.
- Unit tests are located alongside the code
- Integration tests in
secretspec-derive/tests/andtests/integration/ - UI tests using
trybuildfor macro error testing - Run specific test:
cargo test test_name - Test CI runs on Ubuntu and macOS using devenv
Provider tests are located in secretspec/src/provider/tests.rs and test all provider implementations generically.
# Run provider tests
cargo test --package secretspec provider::tests
# Test specific providers using SECRETSPEC_TEST_PROVIDERS env var
SECRETSPEC_TEST_PROVIDERS=keyring,dotenv cargo test --package secretspec provider::tests::integration_tests
# Run with output visible
SECRETSPEC_TEST_PROVIDERS=dotenv cargo test --package secretspec provider::tests -- --nocaptureThe integration tests cover:
- Basic get/set operations
- Multiple secrets handling
- Special characters and Unicode
- Profile-specific storage
- Error handling for edge cases
Note: Some providers (like env) are read-only and will skip write tests.
The docs site is an Astro Starlight site deployed to https://secretspec.dev/.
docs/astro.config.mjs- Sidebar navigation and site configdocs/src/content/docs/- All content pages (markdown/mdx)index.mdx- Home pagequick-start.mdx- Getting started guideconcepts/- Declarative config, profiles, providers overviewproviders/- Individual provider docs (keyring, dotenv, env, pass, lastpass, onepassword, gcsm)sdk/- Rust SDK docsreference/- Configuration, CLI, providers reference, adding providers guide
- New doc page: Create the
.mdfile and add it to the sidebar indocs/astro.config.mjs - New CLI command: Update
docs/src/content/docs/reference/cli.md - New config option: Update
docs/src/content/docs/reference/configuration.md - New provider: See Adding Provider Documentation above
- New concept: Create
docs/src/content/docs/concepts/<name>.mdand add to sidebar
secretspec.toml: Project secrets configurationsecretspec/src/provider/mod.rs: Provider trait definition and documentationsecretspec/src/cli/mod.rs: CLI command definitionssecretspec/src/bin/secretspec.rs: CLI entry pointsecretspec/src/lib.rs: Core SecretSpec implementationsecretspec-derive/src/lib.rs: Code generation macro implementationsecretspec/src/provider/tests.rs: Generic provider test suite