keepassxc-keyring
| Version | 2026.144.1443 |
| Repo | box/cachyos |
KeePassXC as the freedesktop.org Secret Service provider on a target:local host Enables the KeePassXC FdoSecrets plugin, autostarts KeePassXC on login, disables competing Secret Service daemons (gnome-keyring + kwallet) reversibly, installs the pinentry/libsecret runtime deps, and wires gpg-agent + ssh-agent + direnv shell hooks. Verifiable: the keepassxc + pinentry-qt + secret-tool binaries exist and (at deploy scope) FdoSecrets is enabled in keepassxc.ini.
Acceptance plan
Section titled “Acceptance plan”This candy’s plan: — the runnable spec charly check executes against a live deployment. check: steps are idempotent probes; run: steps change state.
| Intent | Step |
|---|---|
run |
mkdir=${HOME}/.config/keepassxc |
run |
command=set -eu python3 - <<‘PY’ import configparser, os p = os.path.expanduser(“~/.config/keepassxc/keepassxc.ini”) cp = configparser.ConfigParser() cp.optionxform = str # preserve key case if os.path.exists(p): cp.read(p) for section in (“FdoSecrets”, “SSHAgent”, “General”, “GUI”): if section not in cp: cp[section] = {} cp[“FdoSecrets”].update({ “Enabled”: “true”, “ShowNotification”: “true”, “ConfirmAccessItem”: “false”, “UnlockBeforeSearch”: “true”, }) cp[“SSHAgent”].update({ “Enabled”: “true”, “UseOpenSSH”: “true”, }) cp[“General”].update({ “RememberLastDatabases”: “true”, “OpenPreviousDatabasesOnStartup”: “true”, }) cp[“GUI”].update({ “MinimizeOnStartup”: “false”, “MinimizeOnClose”: “false”, “ShowTrayIcon”: “true”, }) os.makedirs(os.path.dirname(p), exist_ok=True) with open(p, “w”) as f: cp.write(f, space_around_delimiters=False) PY |
run |
mkdir=${HOME}/.config/autostart |
run |
write=${HOME}/.config/autostart/keepassxc.desktop |
run |
command=set -eu autostart_dir=“${HOME}/.config/autostart” mkdir -p “$autostart_dir” for name in \ gnome-keyring-secrets \ gnome-keyring-ssh \ gnome-keyring-pkcs11 \ org.kde.kwalletd6 \ org.kde.kwalletd5 \ kwalletd \ kwalletd5 \ kwalletd6 \ pam_kwallet_init \ ksecretd ; do src=“/etc/xdg/autostart/${name}.desktop” dst=“${autostart_dir}/${name}.desktop” if [ -f “$src” ]; then cp “$src” “$dst” else cat > “$dst” <<EOF [Desktop Entry] Type=Application Name=${name} (disabled by charly keepassxc-keyring) Exec=/bin/true Hidden=true NoDisplay=true EOF fi if grep -q ‘^Hidden=’ “$dst”; then sed -i ‘s/^Hidden=./Hidden=true/’ “$dst” else printf ‘Hidden=true\n’ >> “$dst” fi if grep -q ‘^X-GNOME-Autostart-enabled=’ “$dst”; then sed -i ‘s/^X-GNOME-Autostart-enabled=./X-GNOME-Autostart-enabled=false/’ “$dst” else printf ‘X-GNOME-Autostart-enabled=false\n’ >> “$dst” fi done |
run |
command=set -eu for unit in \ gnome-keyring-daemon.socket \ gnome-keyring-daemon.service \ kwalletd6.service \ kwalletd5.service \ org.kde.kwalletd6.service \ org.kde.kwalletd5.service \ plasma-kwallet-pam.service \ ksecretd.service ; do if systemctl –user is-enabled “$unit” >/dev/null 2>&1; then systemctl –user disable –now “$unit” >/dev/null 2>&1 || true fi if systemctl –user is-active “$unit” >/dev/null 2>&1; then systemctl –user stop “$unit” >/dev/null 2>&1 || true fi done # Stop any currently-running competitor processes — they hold # org.freedesktop.secrets until killed, blocking KeePassXC from # claiming the bus name. PAM relaunches them at next session, but # the autostart override above (pam_kwallet_init) prevents that. for proc in ksecretd kwalletd6 kwalletd5 gnome-keyring-daemon ; do pkill -x “$proc” >/dev/null 2>&1 || true done |
run |
mkdir=${HOME}/.gnupg |
run |
write=${HOME}/.gnupg/gpg-agent.conf |
run |
command=set -eu systemctl –user enable –now gpg-agent.socket gpg-agent-extra.socket >/dev/null 2>&1 || true gpg-connect-agent reloadagent /bye >/dev/null 2>&1 || true |
run |
command=set -eu systemctl –user enable –now ssh-agent.service >/dev/null 2>&1 || true |
run |
mkdir=${HOME}/.config/environment.d |
run |
write=${HOME}/.config/environment.d/ssh-agent.conf |
run |
command=set -eu for rc in “${HOME}/.bashrc” “${HOME}/.zshrc”; do if [ -f “$rc” ] && grep -qF ‘# opencharly:begin ssh-auth-sock’ “$rc”; then sed -i ‘/# opencharly:begin ssh-auth-sock/,/# opencharly:end ssh-auth-sock/d’ “$rc” fi done rm -f “${HOME}/.config/fish/conf.d/ssh-auth-sock.fish” |
run |
command=set -eu for rc in “${HOME}/.bashrc” “${HOME}/.zshrc”; do if [ -f “$rc” ] && grep -qF ‘# opencharly:begin direnv-hook’ “$rc”; then sed -i ‘/# opencharly:begin direnv-hook/,/# opencharly:end direnv-hook/d’ “$rc” fi done # Legacy fish drop-in path (no charly- prefix) — DELETED in the # cutover; the direnv layer’s shell: schema writes to # ~/.config/fish/conf.d/charly-direnv.fish instead. legacy_fish=“${HOME}/.config/fish/conf.d/direnv.fish” if [ -f “$legacy_fish” ] && grep -qF ‘# opencharly:begin direnv-hook’ “$legacy_fish”; then rm -f “$legacy_fish” fi |
run |
mkdir=${HOME}/.config/systemd/user |
run |
write=${HOME}/.config/systemd/user/keepassxc.service |
run |
command=set -eu systemctl –user daemon-reload systemctl –user enable keepassxc.service >/dev/null 2>&1 || true |
run |
command=set -eu if pgrep -x keepassxc >/dev/null 2>&1; then exit 0 fi if systemctl –user –quiet is-active graphical-session.target 2>/dev/null \ || [ -n “${WAYLAND_DISPLAY:-}” ] || [ -n “${DISPLAY:-}” ] \ || [ -S “${XDG_RUNTIME_DIR:-/run/user/$(id -u)}/wayland-0” ]; then systemd-run –user –quiet –no-block \ –unit=keepassxc-keyring-launch \ /usr/bin/keepassxc >/dev/null 2>&1 || true fi |
check |
the keepassxc binary is installed and executable |
check |
the secret-tool libsecret client is installed |
check |
the FdoSecrets plugin is enabled in keepassxc.ini |
check |
command=test -x /usr/bin/keepassxc |
check |
command=command -v pinentry-qt || command -v pinentry-qt5 || command -v pinentry-qt6 |
check |
command=command -v secret-tool |
check |
command=grep -q ‘^Enabled=true’ ${HOME}/.config/keepassxc/keepassxc.ini |
check |
command=grep -q ‘^OpenPreviousDatabasesOnStartup=true’ ${HOME}/.config/keepassxc/keepassxc.ini |
check |
command=test -r ${HOME}/.config/autostart/keepassxc.desktop |
check |
command=grep -q ‘^pinentry-program /usr/bin/pinentry-qt’ ${HOME}/.gnupg/gpg-agent.conf |
check |
command=systemctl –user is-active gpg-agent.socket |
check |
command=python3 -c “import configparser,os; cp=configparser.ConfigParser(); cp.optionxform=str; cp.read(os.path.expanduser(‘~/.config/keepassxc/keepassxc.ini’)); exit(0 if cp.get(‘SSHAgent’,‘Enabled’,fallback=‘false’)==‘true’ else 1)” |
check |
command=systemctl –user is-enabled keepassxc.service |
check |
command=systemctl –user is-enabled ssh-agent.service |
check |
command=grep -q ‘^SSH_AUTH_SOCK=’ ${HOME}/.config/environment.d/ssh-agent.conf |
check |
command=f=${HOME}/.config/autostart/gnome-keyring-secrets.desktop ! test -f “$f” || grep -q ‘^Hidden=true’ “$f” |
check |
command=f=“${HOME}/.config/fish/conf.d/charly-direnv.fish” if [ -f “$f” ]; then grep -q ‘direnv hook fish’ “$f” && echo FISH-HOOK-OK else echo “FISH-HOOK-OK (fish not per-user-configured on this deploy; login-shell hook covers direnv)” fi |
check |
command=grep -q ‘direnv hook bash’ ${HOME}/.bashrc |