SecretSpec 0.15: Provider credentials, Azure Key Vault / Gopass, and PHP SDK | SecretSpec<br>Skip to content
SecretSpec 0.15: Provider credentials, Azure Key Vault / Gopass, and PHP SDK
Jul 16, 2026<br>Domen Kožar
SecretSpec 0.15<br>ships:
Provider credentials —<br>authenticate one secret provider with credentials stored in another, without<br>exporting them to the application environment.
Azure Key Vault — store and resolve secrets with<br>service-principal, Azure CLI, managed-identity, or AKS workload-identity<br>authentication.
Gopass — use a GPG-encrypted, git-synchronized<br>password store, including multi-user and multi-store setups.
PHP SDK — use the shared SecretSpec resolver from PHP-FPM,<br>Laravel, Symfony, and CLI applications through a native extension or<br>ext-ffi.
AWS creation guardrails — set a customer-managed KMS<br>key and required tags when SecretSpec creates an AWS Secrets Manager secret.
secretspec export — resolve secrets without<br>launching a command, with shell, dotenv, JSON, and GitHub Actions output.
Provider and resolution fixes — ordered lazy<br>fallback chains, early ref validation, correctly merged profile overrides,<br>stable output, and broader Node.js Linux compatibility.
Credentials for the secret store<br>Section titled “Credentials for the secret store”
Suppose Bitwarden Secrets Manager holds an application’s<br>secrets, but its machine access token is kept in the user’s<br>OS keyring. Declare the relationship on the provider<br>alias:
secretspec.toml[providers]
keyring = "keyring://"
[providers.bws]
uri = "bws://a9230ec4-5507-4870-b8b5-b3f500587e4c"
[providers.bws.credentials]
access_token = "keyring"
Before SecretSpec connects to Bitwarden, it reads access_token from the<br>keyring at the normal {project}/{profile}/access_token address. The active<br>profile is part of that address, so production and<br>development can authenticate as different machines without changing the alias.
When a credential already has a provider-native address, use a ref. Here a<br>Vault AppRole is kept as two fields of one<br>1Password item:
secretspec.toml[providers.vault_prod]
uri = "vault://secret/myapp?auth=approle"
[providers.vault_prod.credentials]
role_id.provider = "onepassword"
role_id.ref.vault = "Infra"
role_id.ref.item = "vault-approle"
role_id.ref.field = "role_id"
secret_id.provider = "onepassword"
secret_id.ref.vault = "Infra"
secret_id.ref.item = "vault-approle"
secret_id.ref.field = "secret_id"
The credential source uses the same ref coordinates<br>as application secrets. The difference is where the value goes: SecretSpec<br>hands it directly to the destination provider in memory. It is not added to the<br>environment of a process started by<br>secretspec run.
Provider credential names are semantic and checked before a source is opened.<br>Bitwarden accepts access_token; Vault accepts token, role_id, and<br>secret_id; 1Password accepts service_account_token; Azure Key Vault accepts<br>tenant_id, client_id, and client_secret. A configured credential is<br>authoritative, while a provider’s usual environment fallback remains available<br>when no credential source is declared.
Credential chains deliberately stop after one hop. The store containing a<br>provider credential cannot itself depend on another provider credential. This<br>keeps the bootstrap path finite and makes dependency mistakes fail before any<br>store is contacted.
Log in once, without an environment variable<br>Section titled “Log in once, without an environment variable”
The new<br>config provider login command<br>prompts for every credential an alias declares and writes it to the configured<br>source:
Terminal window$ secretspec config provider login bws
Enter access_token for provider 'bws' (source: keyring): ****
✓ stored access_token in keyring at my-app/default/access_token
A user-level alias and its credential source can also be declared entirely with<br>config provider add:
Terminal windowsecretspec config provider add bws "bws://project-uuid" \
--credential access_token=keyring
secretspec config provider login bws
Credentials are fetched once per invocation and profile, then reused for every<br>secret routed through that alias. Each credential read, and each value stored by<br>login, gets an audit event marked with the semantic<br>credential name and source store. As with every SecretSpec audit event, the<br>credential value is never recorded.
See Provider Credentials for the<br>full configuration and resolution rules.
Azure Key Vault<br>Section titled “Azure Key Vault”
Azure Key Vault joins the provider list with the akv:// scheme:
Terminal window# Use service-principal credentials, or the current Azure CLI session
secretspec run --provider akv://myvault -- npm start
# Use the platform's managed identity
secretspec check --provider akv://myvault?auth=managed_identity
# Use AKS workload identity federation
secretspec run --provider akv://myvault?auth=workload_identity -- ./deploy
The default authentication mode first looks for the tenant_id, client_id,<br>and client_secret provider...