Use GoPass as the backend for the freedesktop.org Secret Service API.
┌─────────┐ ┌─────────┐ ┌─────────┐ ┌──────────────┐
│ Firefox │ │ Chrome │ │ VS Code │ │ Electron app │ ...
└────┬────┘ └────┬────┘ └────┬────┘ └──────┬───────┘
│ │ │ │
└───────────┴─────┬─────┴─────────────┘
│ D-Bus Secret Service API
┌────────┴─────────┐
│ gopass-secret- │
│ service │ ← this project
└────────┬─────────┘
│ Go API
┌─────┴─────┐
│ GoPass │
└─────┬─────┘
│ GPG
┌──────────┴───────────┐
│ ~/.password-store/ │
│ (git-syncable) │
└──────────────────────┘
Linux desktop apps store secrets (passwords, tokens, API keys) via the Secret Service API, which typically means GNOME Keyring or KDE Wallet. If you use GoPass, your secrets end up in two places — GoPass for the terminal, keyring for GUI apps.
gopass-secret-service bridges this gap. Desktop apps write secrets into GoPass transparently, giving you:
- One store for everything — CLI and GUI apps use the same GoPass entries
- GPG encryption you control — audit with
gopass ls, inspect withgopass show - Git sync across machines — GoPass's built-in git support works for all secrets
- No GNOME/KDE dependency — single binary, works with any window manager or DE
- Drop-in replacement for GNOME Keyring's Secret Service component
Works with any application that uses libsecret or the Secret Service D-Bus API:
Firefox, Chromium/Chrome, VS Code, Electron apps (Slack, Discord, etc.), NetworkManager, GNOME apps, secret-tool, Python secretstorage, and more.
Replaces the Secret Service component of GNOME Keyring or KDE Wallet. Other keyring functions (SSH agent, GPG agent) are unaffected.
Works great with secrets-dispatcher
Add per-operation approval, trust rules, and audit logging on top of gopass-secret-service. See which process is accessing which secret, approve or deny in real time, and auto-approve trusted patterns.
Prerequisites: GoPass installed and configured with a GPG key.
# Install — prebuilt static binary (linux amd64/arm64)
curl -Lo ~/.local/bin/gopass-secret \
https://github.com/nikicat/gopass-secret-service/releases/latest/download/gopass-secret-linux-amd64
chmod +x ~/.local/bin/gopass-secret
# ...or with Go
go install github.com/nikicat/gopass-secret-service/cmd/gopass-secret@latest
# Start the daemon (replace GNOME Keyring if running)
gopass-secret service -r &
# Verify — store and retrieve a secret
echo "test123" | secret-tool store --label='Test' app test
secret-tool lookup app test # → test123
# Install as a systemd user service (auto-start on login)
gopass-secret service installThe most common setup — use gopass-secret-service instead of GNOME Keyring for secret storage:
# One-time: start with --replace to take over the D-Bus name
gopass-secret service -r
# Permanent: install as a systemd user service
gopass-secret service install
systemctl --user start gopass-secret-serviceTo prevent GNOME Keyring from grabbing the Secret Service bus name at login, disable its secret service component:
# Copy the desktop file to override it
cp /etc/xdg/autostart/gnome-keyring-secrets.desktop ~/.config/autostart/
echo "Hidden=true" >> ~/.config/autostart/gnome-keyring-secrets.desktopOr simply use the -r / --replace flag — gopass-secret-service will take over from whatever is currently running.
Each release ships static Linux binaries (amd64/arm64) plus a checksums.txt:
curl -Lo ~/.local/bin/gopass-secret \
https://github.com/nikicat/gopass-secret-service/releases/latest/download/gopass-secret-linux-amd64
chmod +x ~/.local/bin/gopass-secretgo install github.com/nikicat/gopass-secret-service/cmd/gopass-secret@latestgit clone https://github.com/nikicat/gopass-secret-service.git
cd gopass-secret-service
make build
make install # Installs to ~/.local/bin (no root required)Make sure ~/.local/bin is in your PATH:
export PATH="$HOME/.local/bin:$PATH" # Add to your .bashrc/.zshrcsudo make install-system # Installs to /usr/local/binmake install PREFIX=/opt/myapps # Custom location
make help # Show all available targetsgopass-secret service # run the D-Bus daemon in the foreground
gopass-secret service -r # replace existing provider (e.g., GNOME Keyring)
gopass-secret service -d # debug logging
gopass-secret service install # install systemd user service
gopass-secret service uninstall # remove systemd user service
gopass-secret add|get|list # manage secrets from the CLI
gopass-secret config # show effective configurationSee the full CLI, configuration, and environment variable reference for all options.
Secrets are stored in GoPass under a configurable prefix (default: secret-service):
~/.password-store/
└── secret-service/
├── default/ # Default collection
│ ├── i<uuid>.gpg # Secret items
│ └── _meta.gpg # Collection metadata
└── _aliases.gpg # Collection aliases
Each secret is stored with its value on the first line, followed by metadata and attributes:
the-secret-value
---
_ss_label: My Secret
_ss_created: 2024-01-15T10:30:00Z
_ss_modified: 2024-01-15T10:30:00Z
username: user@example.com
If gopass-secret-service hangs on startup waiting for a GPG passphrase (with a ~1 minute timeout), you may have a circular dependency:
- gopass-secret-service starts and initializes GoPass
- GoPass needs to decrypt the store, triggering GPG
- GPG uses
pinentry-gnome3to prompt for the passphrase pinentry-gnome3tries to check libsecret (Secret Service) for cached passphrases- But gopass-secret-service hasn't finished starting yet → deadlock
Solution: Disable external password cache in gpg-agent while keeping pinentry-gnome3:
echo "no-allow-external-cache" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agentThis only disables libsecret integration. GPG-agent's internal passphrase cache still works (controlled by default-cache-ttl, default 10 minutes), so you won't be prompted repeatedly.
To increase the cache duration:
cat >> ~/.gnupg/gpg-agent.conf << 'EOF'
no-allow-external-cache
default-cache-ttl 28800
max-cache-ttl 28800
EOF
gpgconf --kill gpg-agentAlternative: Use a pinentry that doesn't use libsecret:
echo "pinentry-program /usr/bin/pinentry-qt" >> ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agentOther options: pinentry-gtk, pinentry-curses, pinentry-tty.
make test # Run tests
./test.sh # Run integration tests (Docker)
make build # Build
make lint # LintMIT License