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.
This commit is contained in:
@@ -0,0 +1,187 @@
|
||||
# Password Management Infrastructure
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Bitwarden Vault ───────────╮ │
|
||||
│ bitwarden.jantec.xyz │ Central store │
|
||||
│ (cloud) │ + backup │
|
||||
│ │ │
|
||||
│ ┌─────────────────┐ │ │
|
||||
│ │ rbw CLI ─────┼─── sync/login ───┘ │
|
||||
│ │ (Rust client) │ Add/edit/search │
|
||||
│ └────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────V──────── ┌──────────────────┐ │
|
||||
│ │ gnome-keyring │────────────►│ Applications │ │
|
||||
│ │ (libsecret) │ D-Bus │ himalaya, git, │ │
|
||||
│ │ org.freedesktop.│ Secrets API │ SSH, browsers, │ │
|
||||
│ │ secrets │ │ IDEs │ │
|
||||
│ └─────────────────┘ └──────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### 1. gnome-keyring (local D-Bus secret service)
|
||||
|
||||
- Provides `org.freedesktop.secrets` D-Bus interface
|
||||
- Started as systemd user service via socket activation
|
||||
- Unlocks on login (PAM integration with greetd/tuigreet)
|
||||
- Stores credentials that apps access via `libsecret` (`secret-tool`)
|
||||
|
||||
| Unit | Status |
|
||||
|------|--------|
|
||||
| `~/.config/systemd/user/gnome-keyring-daemon.socket` | enabled |
|
||||
| `~/.config/systemd/user/gnome-keyring-daemon.service` | enabled |
|
||||
|
||||
### 2. rbw (Bitwarden CLI)
|
||||
|
||||
- Unofficial Bitwarden CLI written in Rust
|
||||
- Connects to `https://bitwarden.jantec.xyz`
|
||||
- Uses gnome-keyring as its encrypted password store (via `pinentry`)
|
||||
- Manages vault: `rbw add`, `rbw get`, `rbw list`, `rbw search`, `rbw sync`
|
||||
|
||||
| Config | Value |
|
||||
|--------|-------|
|
||||
| `~/.config/rbw/config.json` | `{"email": "ironmikechw+bitwarden@gmail.com", "base_url": "https://bitwarden.jantec.xyz"}` |
|
||||
| API Keys | Stored in `~/.config/rbw/` (registered via `rbw register`) |
|
||||
| Vault sync | Automatic via `rbw sync` (interval: 3600s) |
|
||||
|
||||
### 3. SSH Key Passphrases
|
||||
|
||||
- Stored in gnome-keyring (libsecret) for `ssh-add` via `gnome-keyring-ssh` PAM module
|
||||
- Passphrases stored under `application=ssh-agent`, `service=ssh`, `ssh-key=<path>`
|
||||
- Keys migrated from KWallet: `id_ed25519`, `id_ed25519_ja_manjaro`
|
||||
|
||||
### 4. Git Credentials
|
||||
|
||||
- **Global helper**: `libsecret` (stores in gnome-keyring instead of `~/.git-credentials` plaintext)
|
||||
- **GitHub**: `gh auth git-credential` helper (for github.com)
|
||||
- **GitLab**: configured as `provider = generic` in `.gitconfig` for gitlab.satware.com
|
||||
|
||||
### 5. Application Credentials Map
|
||||
|
||||
| Application | Storage | Mechanism |
|
||||
|-----------|---------|-----------|
|
||||
| himalaya (email) | gnome-keyring + Bitwarden | `secret-tool lookup email <address>` |
|
||||
| ssh-agent | gnome-keyring | D-Bus secret service |
|
||||
| git (global) | gnome-keyring (`libsecret`) | `git config credential.helper libsecret` |
|
||||
| GitHub CLI | Bitwarden + gnome-keyring | `rbw get "GitHub Personal Token"` + GK entry |
|
||||
| GitLab | gnome-keyring | `secret-tool lookup application git service gitlab.satware.com` |
|
||||
| Chrome/Brave/Chromium | gnome-keyring | Safe Storage encryption keys |
|
||||
| JetBrains IDEs | gnome-keyring | D-Bus secret service auto-detection |
|
||||
| Remmina | gnome-keyring + Bitwarden | VNC/RDP passwords |
|
||||
| Nextcloud | gnome-keyring + Bitwarden | Instance passwords |
|
||||
| QGIS | gnome-keyring + Bitwarden | Master password |
|
||||
|
||||
## Startup / Unlock Flow
|
||||
|
||||
```
|
||||
1. greetd/tuigreet login → PAM auth
|
||||
2. PAM → gnome-keyring PAM module (pam_gnome_keyring.so)
|
||||
3. Keyring unlocked with login password
|
||||
4. gnome-keyring-daemon starts (socket activation)
|
||||
5. D-Bus org.freedesktop.secrets available
|
||||
6. rbw login → decrypts vault via gnome-keyring
|
||||
7. himalaya can read IMAP passwords via secret-tool
|
||||
8. ssh-add can read SSH passphrases via GK
|
||||
9. git-credential-libsecret reads Git creds via GK
|
||||
```
|
||||
|
||||
## Migration History
|
||||
|
||||
- **Before**: KDE Wallet (kwalletd) — no auto-unlock under greetd, no D-Bus support for non-Plasma apps
|
||||
- **After**: gnome-keyring + rbw + Bitwarden.vault → full D-Bus secret service + central vault + CLI access
|
||||
|
||||
## Manual Entry Required
|
||||
|
||||
### himalaya Email Passwords
|
||||
|
||||
The following email account passwords need to be stored in gnome-keyring (they were NOT in KWallet):
|
||||
|
||||
```bash
|
||||
# Store MW account
|
||||
echo "<PASSWORD>" | secret-tool store --label="IMAP MW" email mw@satware.com application himalaya
|
||||
|
||||
# Store JA account
|
||||
echo "<PASSWORD>" | secret-tool store --label="IMAP JA" email ja@satware.ai application himalaya
|
||||
|
||||
# Store JA Gmail
|
||||
echo "<PASSWORD>" | secret-tool store --label="IMAP JA Gmail" email ja.satware@gmail.com application himalaya
|
||||
|
||||
# Store Michael Gmail
|
||||
echo "<PASSWORD>" | secret-tool store --label="IMAP Michael Gmail" email ironmikechw@gmail.com application himalaya
|
||||
```
|
||||
|
||||
## Useful Commands
|
||||
|
||||
```bash
|
||||
# Bitwarden operations
|
||||
rbw list # list all vault entries
|
||||
rbw search <term> # search vault
|
||||
rbw get <name> # get password (truncates on display)
|
||||
rbw get --full "GitHub Personal Token" # get full password (piped)
|
||||
rbw sync # sync with vault
|
||||
rbw add "Service Name" # add new entry (opens $EDITOR)
|
||||
|
||||
# gnome-keyring operations
|
||||
secret-tool lookup email mw@satware.com # lookup by attribute
|
||||
secret-tool search application ssh-agent # search
|
||||
secret-tool store --label="Test" key value # store (pipe data)
|
||||
dbus-send --session --print-reply --dest=org.freedesktop.secrets \
|
||||
/org/freedesktop/secrets/collection/default # low-level D-Bus
|
||||
|
||||
# Verify startup
|
||||
systemctl --user status gnome-keyring-daemon.socket
|
||||
systemctl --user status gnome-keyring-daemon.service
|
||||
|
||||
# Quick health check
|
||||
rbw unlocked && echo "BW: unlocked" || echo "BW: locked"
|
||||
secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519 && echo "GK: SSH OK"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### gnome-keyring not providing secrets on D-Bus
|
||||
```bash
|
||||
systemctl --user restart gnome-keyring-daemon.service
|
||||
```
|
||||
|
||||
### rbw not unlocked
|
||||
```bash
|
||||
rbw unlock # prompts for login password
|
||||
rbw login # prompts for Bitwarden password
|
||||
```
|
||||
|
||||
### SSH keys not auto-unlocking
|
||||
```bash
|
||||
# Check GK entry
|
||||
secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519
|
||||
# If missing, re-add:
|
||||
echo "<PASSPHRASE>" | secret-tool store --label="SSH id_ed25519" \
|
||||
application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519
|
||||
```
|
||||
|
||||
### GitLab/GitHub creds not working
|
||||
```bash
|
||||
# Test GK
|
||||
secret-tool lookup application git service gitlab.satware.com
|
||||
```
|
||||
|
||||
### himalaya password errors
|
||||
```bash
|
||||
# Verify GK
|
||||
secret-tool lookup email mw@satware.com
|
||||
# Re-enter password from Bitwarden
|
||||
rbw get "himala mw@satware.com" | secret-tool store --label="IMAP mw@satware.com" \
|
||||
email mw@satware.com application himalaya
|
||||
```
|
||||
|
||||
## Security Note
|
||||
|
||||
- Bitwarden vault: self-hosted at `bitwarden.jantec.xyz`
|
||||
- Local cache: gnome-keyring (encrypted, session-bound)
|
||||
- No plaintext passwords in config files
|
||||
- `~/.git-credentials` removed on `git config --global credential.helper store`
|
||||
@@ -0,0 +1,91 @@
|
||||
# Password Management - Migration Checklist
|
||||
|
||||
## Pre-Reboot Status (2026-05-21)
|
||||
|
||||
- [x] gnome-keyring installed (`1:50.0-1`)
|
||||
- [x] rbw installed (`1.15.0`)
|
||||
- [x] gnome-keyring-daemon.socket + service enabled + active
|
||||
- [x] rbw configured: `bitwarden.jantec.xyz`, `ironmikechw+bitwarden@gmail.com`
|
||||
- [x] 397 entries synced from Bitwarden vault
|
||||
- [x] 45 entries migrated from KWallet → BW + GK
|
||||
- [x] Duplicate BW entries cleaned (22 removed)
|
||||
- [x] Git credential helper: `libsecret`
|
||||
- [x] himalaya configs using `secret-tool lookup email <addr>`
|
||||
- [x] GitHub token stored in BW + GK
|
||||
- [x] GitLab PAT stored in BW + GK
|
||||
- [x] SSH passphrases stored in BW + GK
|
||||
- [x] Browser safe storage (Chrome/Brave/Chromium) in BW + GK
|
||||
- [x] Remmina passwords (5) in BW + GK
|
||||
- [x] Nextcloud passwords (3) in BW + GK
|
||||
- [x] QGIS Master Password in BW + GK
|
||||
- [x] JetBrains AI Token in BW + GK
|
||||
- [x] Documentation written: `docs/product/passwords.md` + `docs/adr/password-management-migration.md`
|
||||
- [x] AGENTS.md updated with secrets management reference
|
||||
- [x] KDE Wallet data file backed up (not deleted)
|
||||
- [ ] KDE Wallet packages removal (post-verify)
|
||||
|
||||
## Post-Reboot Actions
|
||||
|
||||
### Immediate Checks
|
||||
```bash
|
||||
# 1. Verify gnome-keyring started
|
||||
systemctl --user is-active gnome-keyring-daemon.service
|
||||
|
||||
# 2. Verify rbw can access vault
|
||||
rbw list | head -5
|
||||
|
||||
# 3. Verify GK entries
|
||||
secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519
|
||||
secret-tool lookup application git service gitlab.satware.com
|
||||
secret-tool lookup application nextcloud service cloud.satware.com user mw
|
||||
|
||||
# 4. Check himalaya
|
||||
himalaya account list
|
||||
himalaya -a mw check 2>&1 # tests IMAP auth
|
||||
```
|
||||
|
||||
### Manual Steps Required
|
||||
1. **himalaya passwords** — 4 accounts need passwords re-entered into GK:
|
||||
```bash
|
||||
for addr in mw@satware.com ja@satware.ai ja.satware@gmail.com ironmikechw@gmail.com; do
|
||||
echo "$(rbw get "$addr" | head -1)" | secret-tool store --label="IMAP $addr" email "$addr" application himalaya
|
||||
done
|
||||
```
|
||||
(Or manually look up passwords from BW web UI and enter them)
|
||||
|
||||
2. **GitHub CLI** — Re-login if token stale:
|
||||
```bash
|
||||
gh auth login --hostname github.com --with-token
|
||||
```
|
||||
Then store in GK:
|
||||
```bash
|
||||
rbw get "GitHub Personal Token" | secret-tool store --label="GitHub Token" application gh-cli service github.com
|
||||
```
|
||||
|
||||
### KDE Wallet Cleanup (After Confirmation)
|
||||
```bash
|
||||
# Only after everything works:
|
||||
sudo pacman -Rns kwallet kwalletmanager
|
||||
rm -rf ~/.local/share/kwalletd/
|
||||
```
|
||||
|
||||
## Rollback (If Needed)
|
||||
|
||||
If gnome-keyring + rbw doesn't work properly after reboot:
|
||||
```bash
|
||||
# Restore git credential helper
|
||||
git config --global credential.helper store
|
||||
|
||||
# Kill gnome-keyring
|
||||
systemctl --user stop gnome-keyring-daemon.socket
|
||||
|
||||
# Restore KWallet (if removed)
|
||||
sudo pacman -S kwallet kwalletmanager
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
- All migration data preserved in `~/.local/share/kwalletd/` (not deleted yet)
|
||||
- KWallet PAM refs were already commented out in `/etc/pam.d/*`
|
||||
- JetBrains IDEs will auto-detect `org.freedesktop.secrets` from gnome-keyring; no config change needed
|
||||
- Browser safe storage keys migrated — browsers will use them automatically
|
||||
@@ -0,0 +1,116 @@
|
||||
# Password Management - System Guide
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────┐
|
||||
│ Bitwarden Vault │
|
||||
│ bitwarden.jantec.xyz │ ← Central, synced, backed up
|
||||
│ (self-hosted) │
|
||||
│ ▲ │
|
||||
│ rbw CLI │ ← CLI access, add/list/get/search
|
||||
│ (ironmikechw+bitwarden@gmail.com)│
|
||||
│ ▲ │
|
||||
│ gnome-keyring (local) │ ← D-Bus secrets API for apps
|
||||
│ org.freedesktop.secrets │ ← libsecret, secret-tool
|
||||
└─────────────────────────────────────
|
||||
```
|
||||
|
||||
## How It Works After Reboot / Login
|
||||
|
||||
1. **greetd/tuigreet login** → PAM auth
|
||||
2. **PAM module** → `pam_gnome_keyring.so` unlocks keyring with login password
|
||||
3. **gnome-keyring-daemon** starts via socket activation (systemd user service)
|
||||
4. **D-Bus** `org.freedesktop.secrets` becomes available on session bus
|
||||
5. **rbw** auto-unlocks via pinentry (reads passphrase from gnome-keyring)
|
||||
6. **Apps** read secrets via `libsecret` / `secret-tool`:
|
||||
- `himalaya` → IMAP/SMTP passwords via `secret-tool lookup email <addr>`
|
||||
- `ssh-agent` → SSH key passphrases via `secret-tool lookup ... ssh-key <path>`
|
||||
- `git-credential-libsecret` → Git passwords via libsecret
|
||||
- `JetBrains IDEs` → auto-detect D-Bus secrets service
|
||||
|
||||
## Quick Verification
|
||||
|
||||
```bash
|
||||
# Is gnome-keyring running?
|
||||
systemctl --user is-active gnome-keyring-daemon.service
|
||||
|
||||
# Can rbw access the vault?
|
||||
rbw list | head -5
|
||||
rbw get "SSH Key: id_ed25519" # should return "SSH gitlab.satware.com"
|
||||
|
||||
# Can apps read secrets?
|
||||
secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519
|
||||
secret-tool lookup application git service gitlab.satware.com
|
||||
secret-tool lookup application nextcloud service cloud.satware.com user mw
|
||||
```
|
||||
|
||||
## Migrated Entries (from KDE Wallet)
|
||||
|
||||
| Category | Entries | Storage |
|
||||
|----------|---------|---------|
|
||||
| **SSH passphrases** | id_ed25519, id_ed25519_ja_manjaro | BW + GK |
|
||||
| **SSH host passwords** | b0t@192.168.0.141 | BW + GK |
|
||||
| **Git tokens** | GitLab PAT, GitHub token | BW + GK |
|
||||
| **Remmina** | 5 VNC/RDP passwords | BW + GK |
|
||||
| **Nextcloud** | 3 instance passwords | BW + GK |
|
||||
| **Browser crypto** | Chrome, Brave, Chromium safe storage | BW + GK |
|
||||
| **JetBrains** | AI token, Account token | BW (AI also in GK) |
|
||||
| **QGIS** | Master password | BW + GK |
|
||||
|
||||
Total: ~45 entries migrated.
|
||||
|
||||
## Known Issues (Post-Reboot)
|
||||
|
||||
1. **himalaya email passwords** — Were NOT in KWallet. Need to be re-entered manually:
|
||||
```bash
|
||||
# Run once per account after reboot
|
||||
rbw get "<entry-name>" | secret-tool store --label="IMAP <name>" email <address> application himalaya
|
||||
```
|
||||
Accounts: `mw@satware.com`, `ja@satware.ai`, `ja.satware@gmail.com`, `ironmikechw@gmail.com`
|
||||
|
||||
2. **GitHub CLI token** — May need re-auth:
|
||||
```bash
|
||||
gh auth login --hostname github.com
|
||||
gh auth git-credential store --hostname github.com # saves to GK
|
||||
```
|
||||
|
||||
## Useful Commands
|
||||
|
||||
```bash
|
||||
# Bitwarden
|
||||
rbw list # list all entries
|
||||
rbw search <term> # search
|
||||
rbw get "<name>" # get password (truncated display)
|
||||
rbw get --full "<name>" # get full password
|
||||
rbw add "<name>" # add new entry (opens editor)
|
||||
rbw sync # force sync with server
|
||||
rbw unlock # unlock vault (prompts for login password)
|
||||
|
||||
# Gnome-keyring
|
||||
secret-tool lookup key value ... # lookup by attributes
|
||||
secret-tool search key value ... # search
|
||||
secret-tool store --label="X" key value # store (pipe password via stdin)
|
||||
|
||||
# System
|
||||
systemctl --user status gnome-keyring-daemon.service
|
||||
systemctl --user restart gnome-keyring-daemon.service # if D-Bus secrets missing
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Symptom | Fix |
|
||||
|---------|-----|
|
||||
| `secret-tool lookup` returns empty | `systemctl --user restart gnome-keyring-daemon.service` |
|
||||
| `rbw list` fails | `rbw unlock` (enter login password) |
|
||||
| SSH key asks for passphrase | `secret-tool lookup application ssh-agent service ssh ssh-key /home/mw/.ssh/id_ed25519` — if empty, re-store it |
|
||||
| `gh` commands fail | `gh auth login --hostname github.com` |
|
||||
| himalaya auth errors | Re-enter IMAP passwords via `secret-tool store` (see Known Issues) |
|
||||
| Browser safe storage issues | Browsers recreate their own Safe Storage keys on startup |
|
||||
|
||||
## KDE Wallet Status
|
||||
|
||||
- Packages still installed (`kwallet`, `kwalletmanager`) — harmless, will be removed after verification
|
||||
- Data file preserved at `~/.local/share/kwalletd/kdewallet.kwl` (backup)
|
||||
- PAM references already commented out
|
||||
- No longer used by any application
|
||||
Reference in New Issue
Block a user