Providers
A provider is a storage backend from which SecretSpec reads secrets and,
when supported, writes them. Providers let one secretspec.toml
describe the secrets an application needs without requiring every
environment to use the same secret store.
For example, a developer can use the system keyring, CI can supply environment variables, and production can use a shared password manager or cloud secret manager. The secret definitions stay the same; only their provider configuration changes.
Provider specifications
Anywhere SecretSpec accepts a provider, you can use one of three forms:
- A provider name, such as
keyringorenv. - A provider URI, such as
dotenv://.env.localoronepassword://Production. The URI configures a particular instance of the provider. - A provider alias, such as
prod_vault, defined in project or user configuration.
Aliases are useful when a URI is shared by several secrets or should have a meaningful, store-independent name.
[providers]prod_vault = "onepassword://Production"
[profiles.production]DATABASE_URL = { description = "Production database", providers = ["prod_vault"] }
secretspec.toml
Available providers
| Provider | Storage backend | Read | Write | Encrypted at rest | TPM-backed keys |
|---|---|---|---|---|---|
| keyring | macOS Keychain, Windows Credential Manager, or Linux Secret Service | ✓ | ✓ | ✓ | — |
| kdbx (0.17+) | KeePass KDBX file (requires the kdbx build feature) | ✓ | KDBX 4 | ✓ | — |
| dotenv | A .env file | ✓ | ✓ | ✗ | — |
| file (0.19+) | One plaintext UTF-8 file per secret | ✓ | ✓ | ✗ | — |
| env | Current process environment | ✓ | ✗ | ✗ | — |
| ejson (0.20+) | EJSON encrypted file (requires the ejson build feature and EJSON CLI) | ✓ | ✗ | ✓ | — |
| null (0.19+) | No storage; uses a manifest default, ephemeral generation, or an ephemeral run prompt | ✗ | ✗ | N/A | — |
| systemd-credential (0.17+) | Credentials passed to the current systemd service | ✓ | ✗ | Depends on the unit’s credential source | Via systemd-creds |
| fly (0.20+) | Fly.io application secrets through flyctl | ✗ | ✓ | ✓ | — |
| cloudflare (0.20+) | Cloudflare account-level Secrets Store through its REST API | ✗ | ✓ | ✓ | — |
| pass | Unix pass password store | ✓ | ✓ | ✓ | Via GnuPG |
| gopass (0.15+) | gopass password store (git-synced, GPG-encrypted) | ✓ | ✓ | ✓ | Via GnuPG |
| protonpass | Proton Pass | ✓ | ✓ | ✓ | — |
| passbolt (0.19+) | Self-hosted Passbolt through go-passbolt-cli | ✓ | ✓ | ✓ | — |
| onepassword | 1Password | ✓ | ✓ | ✓ | — |
| lastpass | LastPass | ✓ | ✓ | ✓ | — |
| dashlane (0.18+) | Dashlane, through the dcli CLI | ✓ | ✗ | ✓ | — |
| keeper (0.18+) | Keeper Secrets Manager (requires the keeper build feature) | ✓ | ✓ | ✓ | — |
| gcsm | Google Cloud Secret Manager (requires the gcsm build feature) | ✓ | ✓ | ✓ | — |
| awssm | AWS Secrets Manager (requires the awssm build feature) | ✓ | ✓ | ✓ | — |
| awsps (0.18+) | AWS Systems Manager Parameter Store (requires the awsps build feature in 0.18+) | ✓ | ✓ | ✓ (SecureString) | — |
| scaleway (0.17+) | Scaleway Secret Manager (requires the scaleway build feature) | ✓ | ✓ | ✓ | — |
| vault | HashiCorp Vault (requires the vault build feature) | ✓ | ✓ | ✓ | — |
| openbao (0.17+) | OpenBao (requires the openbao build feature; 0.16 uses openbao:// through vault) | ✓ | ✓ | ✓ | — |
| bw (0.18+) | Bitwarden Password Manager via the bw CLI (requires the bw build feature) | ✓ | ✓ | ✓ | — |
| bws | Bitwarden Secrets Manager (official bws CLI in SecretSpec 0.17+; requires the bws build feature) | ✓ | ✓ | ✓ | — |
| akv | Azure Key Vault (requires the akv build feature) | ✓ | ✓ | ✓ | — |
| aac (0.20+) | Azure App Configuration, including Key Vault-reference resolution (included by default; aac feature for custom builds) | ✓ | ✓ | ✓ | — |
| infisical (0.16+) | Infisical (requires the infisical build feature) | ✓ | ✓ | ✓ | — |
| age (0.17+) | An age-encrypted file (requires the age build feature) | ✓ | ✓ | ✓ | — |
| sops (0.17+) | SOPS-encrypted files (requires the sops build feature and SOPS CLI) | ✓ | ✓ | ✓ | Depends on the configured SOPS key service |
| kubernetes (0.20+) | Kubernetes ConfigMaps and Secrets (requires the kubernetes build feature) | ✓ | ✓ | Secrets can be encrypted at rest | — |
“TPM-backed keys” means the local key used by the provider can be protected by a TPM 2.0 through the provider path SecretSpec uses. Pass and Gopass inherit this capability from GnuPG when its encryption key is moved to the TPM. systemd credentials inherit it from systemd-creds, which seals encrypted credentials to the TPM2 by default when the host has one. libsecret has an optional TPM2-enabled file backend, but SecretSpec’s Linux keyring transport uses the Secret Service D-Bus API rather than that file backend. macOS Keychain uses Apple’s Secure Enclave rather than a TPM, and Windows Vault credentials are not protected by Credential Guard. An em dash means SecretSpec has no documented TPM integration for that provider; it does not describe other hardware security used internally by the provider service. Each provider page starts with a minimal working example, then covers setup, project configuration, storage conventions, existing provider-native secrets, and CI/CD where applicable.
Configure the default provider
Run the interactive configuration command to select the user-global
provider SecretSpec uses when a secret has no provider-specific
configuration. SecretSpec 0.17+ provides an explicit global namespace;
the legacy spelling without it remains supported:
$ secretspec config global init # 0.17+
Terminal window
SecretSpec 0.17+ can persist the provider and profile non-interactively:
$ secretspec config global init --provider env --profile default
Terminal window
The resulting user configuration contains a default provider:
[defaults]provider = "keyring"profile = "development" # Optional default profile
~/.config/secretspec/config.toml
Use --provider for a one-off override, or SECRETSPEC_PROVIDER for
commands in the current shell or CI job:
# Route every secret in this command to a project .env file.$ secretspec run --provider dotenv -- npm start
# Route every secret in subsequent commands to existing environment variables.$ export SECRETSPEC_PROVIDER=env
$ secretspec check
Terminal window
SECRETSPEC_PROVIDER is a whole-resolution override: it replaces every
per-secret fallback chain. Integrations such as devenv should only
export it when the user explicitly configures a whole-resolution
provider override.
When consuming a JSON or SDK resolution, do not feed its top-level
provider display label back into SECRETSPEC_PROVIDER; mixed
per-secret routes cannot be represented by one provider string. Only
export SECRETSPEC_PROVIDER when the user explicitly selected a
whole-resolution override. Per-secret source_provider remains the
authoritative provenance.
A provider URI can configure the selected backend more precisely:
# Select a specific 1Password vault.$ secretspec run --provider "onepassword://Development" -- npm start
# Select a specific dotenv file.$ secretspec run --provider "dotenv:/home/user/work/.env" -- npm test
Terminal window
Configure provider aliases
Provider aliases can be declared at either project or user scope:
- Define project aliases in the top-level
[providers]table insecretspec.toml. Commit these aliases so team members and CI use the same mapping. - Define user aliases in
[defaults.providers]in~/.config/secretspec/config.toml. Use these for personal mappings that should apply across projects.
If both scopes define the same alias, the project alias takes precedence.
[providers]prod_vault = "onepassword://Production"shared_vault = "onepassword://Shared"local = "keyring://"
[profiles.production]DATABASE_URL = { description = "Production database", providers = ["prod_vault", "local"] }SENTRY_DSN = { description = "Error reporting", providers = ["shared_vault", "local"] }
secretspec.toml
Provider lists may combine aliases, provider names, and inline provider URIs:
[profiles.production]DATABASE_URL = { description = "Production database", providers = ["onepassword://Production", "keyring"] }
secretspec.toml
Alias ref templates
A leaf alias can map the logical {project}, {profile}, and {key}
into its provider’s native coordinates. This lets every link in a
fallback chain—and each side of an import—use a different address:
[providers]remote = { uri = "onepassword://Production", ref = { item = "{project}-{profile}", field = "{key}" } }local = { uri = "dotenv://.env", ref = { item = "{key}" } }
[profiles.production]API_KEY = { description = "API key", providers = ["remote", "local"] }
secretspec.toml
Use per-secret refs = { alias = { item = "..." } } for exceptions. See
Secret
References
for precedence, import-only source aliases, and cached-route
restrictions.
Use the CLI to manage user-level aliases:
# SecretSpec 0.17+$ secretspec config global provider add prod_vault "onepassword://Production"
$ secretspec config global provider list
$ secretspec config global provider remove prod_vault
Terminal window
These commands modify only ~/.config/secretspec/config.toml. Edit the
top-level [providers] table directly to change project aliases.
Provider credentials
Some providers need credentials before they can retrieve secrets. Examples include an access token for Bitwarden Secrets Manager, a Vault token or AppRole credentials, a 1Password service account token, and Azure service-principal credentials.
An alias can load these credentials from another provider. This avoids storing long-lived provider credentials in a shell profile or CI variable when a secure store is available.
The provider credential reference lists every accepted semantic name, its environment fallbacks, and the SecretSpec version that introduced it.
Use the convention address
In an alias’s credentials table, map each semantic credential name to
the provider that stores it:
[providers]keyring = "keyring://"
# Read the access token from keyring before connecting to Bitwarden.bws = { uri = "bws://a9230ec4-5507-4870-b8b5-b3f500587e4c", credentials = { access_token = "keyring" } }
secretspec.toml
A string value such as "keyring" is a provider specification.
SecretSpec reads the credential from that provider at the conventional
{project}/{profile}/{credential} address for the active project and
profile.
Use an explicit address
Use a table with provider and ref when the credential already exists
at a specific provider-native address:
[providers.vault_prod]uri = "vault://secret/myapp?auth=approle"credentials = { role_id = { provider = "onepassword", ref = { vault = "Infra", item = "vault-approle", field = "role_id" } }, secret_id = { provider = "onepassword", ref = { vault = "Infra", item = "vault-approle", field = "secret_id" } }}
secretspec.toml
The ref table uses the same provider-native coordinates as a secret
ref.
Store provider credentials
Use config provider login to prompt for every credential declared by
an alias and write it to the configured source:
$ secretspec config provider login bwsEnter access_token for provider 'bws' (source: keyring): ****✓ stored access_token in keyring at smoke/default/access_token
Terminal window
You can also create a user-level alias with a convention-address credential source from the CLI:
$ secretspec config global provider add bws "bws://project-uuid" --credential access_token=keyring # 0.17+
$ secretspec config provider login bws
Terminal window
Provider credentials follow these rules:
- Configured credentials are authoritative. When an alias declares a credential, SecretSpec reads its configured source. Providers may still use their conventional environment variables when no explicit credential is supplied.
- Credentials remain internal. SecretSpec passes a retrieved
credential to the destination provider in memory. It does not export
the credential or include it in the environment of a process started
by
secretspec run. - Credential chains are one hop. A source provider cannot require provider credentials of its own. SecretSpec validates this before accessing the provider, preventing dependency cycles.
- Convention addresses are profile-specific. A string source uses
the active project and profile. Use a
refsource when multiple projects or profiles should share one provider credential. - Names are provider-specific. The catalog above is exhaustive. Unsupported names are rejected before any source is read.
- A URI may not carry a credential (0.19+). A provider URI with a
password (
scheme://user:PASSWORD@host) is rejected, as is a service account token in theonepassword+token://userinfo. A URI is committed tosecretspec.toml, echoed into shell history, and printed by CI, so a credential written there is already disclosed. Use a provider credential or the provider’s environment variable instead.
Next steps
- Learn how Provider fallback selects and orders sources.
- Cache slow remote routes and diagnose remaining latency with Provider caching (0.17+).
- Review the URI and authentication details for an individual provider in the Providers section.
- Learn how Profiles apply provider defaults to an environment.
- Learn how Secret references separate provider selection from provider-native addresses.
Last updated Oct 08, 2026