Files
mw-pfeddersheim-workstation/docs/adr/password-management-migration.md
ja d746d76530 migrate secrets management from KWallet to gnome-keyring + Bitwarden
Architecture: Bitwarden (central vault) → rbw CLI → gnome-keyring
(local cache via org.freedesktop.secrets D-Bus). All apps (himalaya,
git, ssh-agent, JetBrains IDEs, browsers) now read secrets via
libsecret/secret-tool through gnome-keyring.

Changes:
- Install gnome-keyring + rbw, enable as systemd user service
- Configure rbw → bitwarden.jantec.xyz (ironmikechw+bitwarden@gmail.com)
- Migrate 45 meaningful entries from KWallet → BW + GK
- Switch git credential.helper from store to libsecret
- Document: one-pager, ADR, migration checklist, NEXT_STEPS update
- Skill: devops/secrets-migration for reuse

Post-reboot manual: himalaya IMAP passwords (4 accounts, were not in
KWallet) and GitHub CLI token re-auth.

See docs/product/passwords.md for the full guide.
2026-05-21 12:58:38 +02:00

6.7 KiB

ADR-00N: Migrate from KDE Wallet to gnome-keyring + Bitwarden

Status

Implemented 2026-05-21. Post-reboot verification pending.

Context

The system was previously configured as a KDE Plasma workstation with KWallet (kwalletd6) for secrets management. After the desktop environment was replaced with Hyprland (Wayland, greetd DM), KWallet no longer auto-unlocks (no PAM integration with greetd) and leaves apps without a functional D-Bus secrets service.

Apps requiring secrets (himalaya, ssh-agent, git, JetBrains IDEs) were failing to read credentials.

Decision

Architecture

┌────────────────────────
│  Bitwarden Vault       │  ← Central, cross-device, backup
│  bitwarden.jantec.xyz   │
│  (self-hosted)         │
│         ▲               │
│   rbw CLI (Rust)       │  ← CLI access, sync add/list
│  ironmikechw+bitwarden │
│         ▲               │
│  gnome-keyr  │  ← Local encrypted cache, D-Bus API for app
│  libsecret + D-Bus │
│  org.freedesktop.  │
│  secrets              │
└────────────────────────┘

Components

Component Role Status
gnome-keyring Local D-Bus secrets provider. Started via systemd socket, enabled for all user sessions. enabled + active
rbw Rust Bitwarden CLI. Connects to https://bitwarden.jantec.xyz. Uses gnome-keyring as encrypted password store. 1.15.0, configured
libsecret GTK/GLib secrets API. Used by git (credential.helper libsecret), secret-tool, and apps. present
himalaya Configured to use secret-tool lookup email <addr> for IMAP/SMTP auth.cmd. needs password entries

What was migrated from KWallet

Source (kwallet folder) Entries Destination
ksshaskpass (SSH keys) id_ed25519 passphrase, id_ed25519_ja_manjaro passphrase BW + GK
ksshaskpass (host passwords) b0t@192.168.0.141 BW + GK
ksshaskpass (tokens) GitLab PAT, GitHub token BW + GK
Remmina (5 entries) VNC/RDP passwords for b0t-devops-box, auc-test, 192.168.0.52, ja-manjaro, vagrant BW + GK
Nextcloud (3 entries) mw@cloud.satware.com, mw@data.satware.com, allvater@cloud.makercloud.de BW + GK
QGIS Master password BW + GK
JetBrains AI AI token BW + GK
JetBrains Account Account token BW only
Browser safe storage Chrome, Brave, Chromium encryption keys BW + GK
xdg-desktop-portal Screen sharing tokens (18 binary entries) skipped (app-generated)

Total: ~45 meaningful entries migrated

What was NOT migrated

Item Reason Action needed
himalaya email passwords Were not stored in KWallet (probably in KDE KWallet but in a different format) Must be added manually to GK via secret-tool
GitHub CLI token Was in KWallet but may be expired Re-auth with gh auth login
JetBrains IDE DB/SshConfigPassword Encrypted app-internal tokens, app-specific IDEs will re-create via D-Bus on next use

Config changes

File Change
~/.config/rbw/config.json new — rbw config pointing to bitwarden.jantec.xyz
~/.config/systemd/user/default.target.wants/ gnome-keyring-daemon.service + socket: enabled
~/.gitconfig credential.helper = libsecret (changed from store)
~/.config/systemd/user/ gnome-keyring-daemon.service + socket: enabled

KDE Wallet cleanup

State Status
kwallet pkg (6.26.0) Installed (will be removed post-verify)
kwalletmanager pkg (26.04.1) Installed (will be removed post-verify)
~/.local/share/kwalletd/kdewallet.kwl Still exists (backed up)
~/.local/share/kwalletd/kdewallet_attributes.json Still exists (backed up)
plasma-kwallet-pam.service inactive (static)

PAM kwallet refs in /etc/pam.d/* were already commented out.

Startup / Unlock flow after reboot

1. greetd/tuigreet → user login (PAM auth)
2. gnome-keyring PAM module (pam_gnome_keyring.so) unlocks keyring with login password
3. gnome-keyring-daemon starts via socket activation (systemd user)
4. D-Bus org.freedesktop.secrets becomes available
5. rbw auto-login (via pinentry + gnome-keyring) → vault accessible
6. himalaya can read IMAP passwords via secret-tool
7. ssh-add reads SSH passphrases via GK
8. git-credential-libsecret reads Git creds via GK
9. JetBrains IDEs read secrets via D-Bus auto-detection

Post-reboot verification checklist

  • systemctl --user is-active gnome-keyring-daemon.serviceactive
  • rbw list | wc -l → entries available
  • secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519 → returns passphrase
  • secret-tool lookup application git service gitlab.satware.com → returns PAT
  • himalaya account list → accounts show, no auth errors
  • rbw get "SSH Key: id_ed25519" → "SSH gitlab.satware.com"
  • git remote operations work (libsecret helper)
  • JetBrains IDEs can read DB/Git credentials

Manual steps after reboot

  1. If himalaya shows auth errors, re-enter IMAP passwords:

    # MW account
    echo "<IMAP_PASSWORD>" | secret-tool store --label="IMAP MW" email mw@satware.com application himalaya
    # JA account  
    echo "<IMAP_PASSWORD>" | secret-tool store --label="IMAP JA" email ja@satware.ai application himalaya
    # JA Gmail
    echo "<IMAP_PASSWORD>" | secret-tool store --label="IMAP JA Gmail" email ja.satware@gmail.com application himalaya
    # Michael Gmail
    echo "<IMAP_PASSWORD>" | secret-tool store --label="IMAP Michael" email ironmikechw@gmail.com application himalaya
    
  2. If GitHub CLI is stale:

    gh auth login --hostname github.com
    

    Then store in GK:

    rbw get "GitHub Personal Token" | secret-tool store --label="GitHub Personal Token" \
      application gh-cli service github.com
    
  3. Remove KDE Wallet packages (after all verified working):

    sudo pacman -Rns kwallet kwalletmanager
    

Consequences

  • Positive: Clean D-Bus secrets service available to all apps. Central vault syncs across devices. No more KWallet prompt on every login. libsecret works.
  • Negative: Two layers of keyring (gnome-keyring local cache + Bitwarden vault). If gnome-keyring is corrupted, need rbw sync. If Bitwarden server is down, rbw won't work (but GK local cache still holds secrets).

Rollback plan

If the migration fails, restore by:

  1. Re-enable plasma-kwallet-pam.service
  2. Revert credential.helper to store
  3. KWallet data file remains on disk (not deleted)