#!/bin/bash set -euo pipefail NAME="${1:?Usage: keepassxc-watch.sh }" SECRETS_DIR="$HOME/.secrets" DB="$SECRETS_DIR/$NAME.kdbx" CREDS="$SECRETS_DIR/$NAME.creds" RUNTIME_DIR="${XDG_RUNTIME_DIR:-/run/user/$(id -u)}" KEYFILE="$RUNTIME_DIR/keepassxc-$NAME.key" wipe_key() { [ -f "$KEYFILE" ] && { shred -u "$KEYFILE" 2>/dev/null || rm -f "$KEYFILE"; } } trap wipe_key EXIT unlock_db() { umask 077 if ! systemd-creds decrypt --name="KeePassXC-$NAME" "$CREDS" "$KEYFILE"; then echo "TPM2 unseal failed for '$NAME'" >&2 return 1 fi chmod 600 "$KEYFILE" dbus-send --print-reply --dest=org.keepassxc.KeePassXC.MainWindow /keepassxc \ org.keepassxc.KeePassXC.MainWindow.openDatabase \ string:"$DB" string:"" string:"$KEYFILE" wipe_key } # Wait for KeePassXC's D-Bus service to spawn for i in $(seq 1 30); do if dbus-send --print-reply --dest=org.keepassxc.KeePassXC.MainWindow /keepassxc \ org.freedesktop.DBus.Introspectable.Introspect &>/dev/null; then break fi sleep 1 done unlock_db || true while true; do dbus-monitor --system "type='signal',interface='org.freedesktop.login1.Session',member='Unlock'" | \ while read -r line; do echo "$line" | grep -q "member=Unlock" && unlock_db done sleep 2 done