DesktopSecrets is a utility that allows you to remove secrets from your filesystem by transforming them to Secret References. It integrates with KeePass, AWS Secrets Manager, AWS Parameter Store, Azure Key Vault, GCP Secret Manager, HashiCorp Vault, 1Password, Windows Credential Manager, macOS Keychain, and local user-provided prompts to make retrieving credentials simple, scriptable, and safe, while minimizing repeated password prompts through configurable caching.
A Secret Reference is an expression that resolves to a secret value
Examples:
keepass(C:\Vaults\cloud.kdbx|/AWS/Prod/api-key)
awssm(MyApp/DB|password)
awsps(/myapp/prod/api-key)
azkv(mykv/dbpass)
gcpsm(my-project/api-key)
vault(secret/data/myapp|password)
op(Personal/GitHub|token)
wincred(MyApp/DBPassword)
keychain(git.example.com|alice)
user(Enter API key)
DesktopSecrets provides the following commands.
Resolves secrets inside one or more .env.tpl files.
Example:
DATABASE_URL=postgresql://localhost:5432/mydb
API_SECRET=keepass($USERPROFILE\Credentials.kdbx|api-key)
LOG_LEVEL=debugtplenv prints the fully resolved environment.
Use tplenv run to execute a command with resolved variables injected.
Resolves a single secret reference passed directly as an argument.
Example:
getsec "API_SECRET=keepass($USERPROFILE\Credentials.kdbx|api-key)"Prompts the user to manually enter a secret value.
SECRET_NAME=user(Title shown in prompt)
Retrieves secrets from the Windows Credential Manager — the built-in credential store accessible via Control Panel › Credential Manager.
Create entries with cmdkey or the GUI:
cmdkey /generic:"MyApp/DBPassword" /user:"myuser" /pass:"mysecret"SECRET_NAME=wincred(TARGET) # password field (default)
SECRET_NAME=wincred(TARGET|password) # password field (explicit)
SECRET_NAME=wincred(TARGET|username) # username field- TARGET — The credential target name used when storing the credential
- Field —
password(default) orusername
DB_PASSWORD=wincred(MyApp/DBPassword)
DB_USER=wincred(MyApp/DBPassword|username)Retrieves secrets from AWS Secrets Manager (awssm) and AWS Parameter Store (awsps).
Uses the standard AWS credential chain — no extra configuration needed:
AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY/AWS_SESSION_TOKENenv vars~/.aws/credentials+~/.aws/config(respectsAWS_PROFILE,AWS_DEFAULT_REGION)- IAM instance roles, ECS task roles, Web Identity tokens
Resolved values are cached in-memory for the configured TTL (same as KeePass).
# Raw string secret
API_KEY=awssm(MyApp/ApiKey)
# JSON field extraction
DB_USER=awssm(MyApp/DB|username)
DB_PASS=awssm(MyApp/DB|password)SecureString parameters are always decrypted automatically.
# Parameter value
API_KEY=awsps(/myapp/prod/api-key)
# JSON field extraction
DB_HOST=awsps(/myapp/prod/db|host)Retrieves secrets from Azure Key Vault (azkv).
Uses DefaultAzureCredential — tries in order: env vars, workload identity, managed identity, Azure CLI (az login), Azure PowerShell, Azure Developer CLI. No extra config needed if any of those are set up.
SECRET_NAME=azkv(VAULT/NAME) # raw secret value
SECRET_NAME=azkv(VAULT/NAME|field) # JSON field extraction
SECRET_NAME=azkv(https://VAULT.vault.azure.net/NAME) # full URL form- VAULT — Key Vault name (e.g.
mykv) or full URL - NAME — secret name
- field — optional JSON field if the secret value is JSON
DB_PASSWORD=azkv(mykv/db-password)
DB_USER=azkv(mykv/db-credentials|username)Retrieves secrets from Google Cloud Secret Manager (gcpsm).
Uses Application Default Credentials — GOOGLE_APPLICATION_CREDENTIALS env var, gcloud auth application-default login, attached service account on GCE/GKE/Cloud Run, etc.
SECRET_NAME=gcpsm(PROJECT/NAME) # latest version
SECRET_NAME=gcpsm(PROJECT/NAME/VERSION) # specific version
SECRET_NAME=gcpsm(PROJECT/NAME|field) # JSON field extraction
SECRET_NAME=gcpsm(projects/P/secrets/N/versions/V) # fully-qualified form- PROJECT — GCP project ID
- NAME — secret name
- VERSION — numeric version or
latest(default) - field — optional JSON field if the secret payload is JSON
API_KEY=gcpsm(my-project/api-key)
DB_PASS=gcpsm(my-project/db-credentials|password)Retrieves generic passwords from the macOS login keychain via the security CLI.
Create entries with the security command or Keychain Access.app:
security add-generic-password -s git.example.com -a alice -w 'the-token'SECRET_NAME=keychain(SERVICE) # any account matching service
SECRET_NAME=keychain(SERVICE|ACCOUNT) # specific accountGIT_TOKEN=keychain(git.example.com|alice)
AWS_KEY=keychain(aws-prod)Retrieves secrets from HashiCorp Vault (vault).
Uses the standard Vault client config — no extra setup needed:
VAULT_ADDR— Vault server URLVAULT_TOKEN— auth token (or file token, AppRole, etc. via standard Vault env vars)VAULT_NAMESPACE— namespace for Vault Enterprise
SECRET_NAME=vault(PATH) # returns raw JSON or single-key value
SECRET_NAME=vault(PATH|field) # extracts a named field- PATH — full Vault path. For KV v2, include
data/(e.g.secret/data/myapp) - field — optional. If omitted and the secret has a single key, its value is returned; otherwise the full JSON object is returned.
# KV v2 mount at 'secret/'
DB_PASSWORD=vault(secret/data/myapp|password)
API_TOKEN=vault(secret/data/myapp|api_token)
# KV v1 mount
LEGACY_KEY=vault(kv/legacy/key)Retrieves secrets from 1Password via the op CLI (op).
Requires the 1Password CLI installed and signed in (op signin).
SECRET_NAME=op(VAULT/ITEM) # default `password` field
SECRET_NAME=op(VAULT/ITEM|field) # named field (1Password-native, not JSON)Under the hood this invokes op read op://VAULT/ITEM/field.
GITHUB_TOKEN=op(Personal/GitHub|token)
DB_PASS=op(Work/Production-DB|password)The KeePass provider retrieves secrets from .kdbx vaults.
It supports:
- absolute paths
- wildcard paths (
*= one level,**= any depth) - escaped slashes (
\/) - attribute selection
- chaining
SECRET_NAME=keepass(VAULT|ENTRY)- VAULT – Path to a KeePass database file (or alias)
- ENTRY – Title or path pattern
If the entry does not start with /, it is treated as:
**/<title>
Example:
keepass(vault.kdbx|api-key)
Searches for any entry named api-key anywhere in the tree.
keepass(vault.kdbx|/AWS/Prod/api-key)
Matches exactly that path.
*matches one group level**matches zero or more group levels
Examples:
keepass(vault.kdbx|/AWS/*/api-key)
keepass(vault.kdbx|/AWS/**/api-key)
keepass(vault.kdbx|/AWS/Prod/My\/Key)
Matches an entry titled My/Key.
keepass(vault.kdbx|/AWS/Prod/api-key|UserName)
keepass(vault.kdbx|/AWS/Prod/api-key|URL)
keepass(vault.kdbx|/AWS/Prod/api-key|Notes)
keepass(vault.kdbx|/AWS/Prod/api-key|customField)
Attribute names are case-sensitive. If omitted, the default attribute is the Password.
Aliases for KeePass databases for more flexibility. Aliases are defined in aliases.yaml and referenced with &.
Example:
cloud:
file: C:\Vaults\cloud.kdbx
master: keepass(&personal|Cloud Master Password)
personal: C:\Vaults\personal.kdbxUsage:
MAPS_API_KEY=keepass(&cloud|/Google/Prod/api-key)
CLAUDE_API_KEY=keepass(&personal|Claude Code API key)
KeePass vaults can be unlocked using secrets retrieved from other providers.
Example:
SECRET=keepass(VAULT_A[keepass(VAULT_B|MasterPassword)]|/Prod/api-key)This:
- Resolves the inner secret reference
- Uses it as the master password for
VAULT_A - Retrieves the final entry
Chaining works with all lookup modes, including wildcards and aliases.
Settings are accessible via the taskbar icon.
- macOS:
~/Library/Application Support/desktop-secrets - Linux:
$XDG_CONFIG_HOME/desktop-secretsor~/.config/desktop-secrets - Windows:
%APPDATA%\desktop-secrets
DESKTOP_SECRETS_CONFIG_FILEDESKTOP_SECRETS_ALIASES_FILEDESKTOP_SECRETS_KEYFILES_FILE
- Go installed and configured
Windows:
go build -o tplenv.exe ./cmd/tplenv
go build -o getsec.exe ./cmd/getsecLinux:
go build -o tplenv ./cmd/tplenv
go build -o getsec ./cmd/getsecgo get github.com/it-atelier-gn/desktop-secrets
import (
"os"
desktopsecrets "github.com/it-atelier-gn/desktop-secrets"
)
func main() {
// Required: allows this binary to be re-launched as the secrets daemon.
if desktopsecrets.Init() {
os.Exit(0)
}
secret, err := desktopsecrets.ResolveSecret("user(DB Password)")
if err != nil {
panic(err)
}
println(secret)
}MIT © 2026 Georg Nelles