--- title: SDDM KWallet PAM Setup for Hyprland type: note permalink: dotfiles/research/sddm-kwallet-pam-setup-for-hyprland tags: - sddm - kwallet - pam - hyprland - arch - research - authoritative --- # SDDM KWallet PAM Setup for Hyprland ## Summary Complete, source-verified setup for automatic KWallet unlock on SDDM password login, for a non-Plasma (Hyprland) Arch Linux system. ## Freshness - confidence: high - last_validated: 2026-03-11 - volatility: low (KDE Plasma 6 PAM module is stable; Arch Wiki last edited 2026-03-10) - review_after_days: 90 - validation_count: 1 - contradiction_count: 0 ## Sources consulted - [source] Arch Wiki "KDE Wallet" — https://wiki.archlinux.org/title/KDE_Wallet (last edited 2026-03-10) - [source] Arch Wiki "SDDM" — https://wiki.archlinux.org/title/SDDM (last edited 2026-03-04) - [source] Arch package database `kwallet-pam` 6.6.2-1 file listing — https://archlinux.org/packages/extra/x86_64/kwallet-pam/files/ - [source] Arch package database `kwallet` 6.23.0-1 file listing — https://archlinux.org/packages/extra/x86_64/kwallet/files/ - [source] Real-world Hyprland dotfiles from GitHub (wayblueorg/wayblue, AhmedAmrNabil/nix-config) ## (1) Package to install - [fact] Package: **`kwallet-pam`** — in the official **`extra`** repository (NOT AUR) - [fact] Install command: `sudo pacman -S kwallet-pam` - [fact] Current version: **6.6.2-1** (as of 2026-03-03) - [fact] Dependencies: `kwallet`, `pam`, `libgcrypt`, `socat` (all already present or auto-resolved) - [fact] Files installed: - `/usr/lib/security/pam_kwallet5.so` — the PAM module - `/usr/lib/pam_kwallet_init` — session-start helper script - `/etc/xdg/autostart/pam_kwallet_init.desktop` — XDG autostart for Plasma/DE environments - `/usr/lib/systemd/user/plasma-kwallet-pam.service` — systemd user service ### Critical naming fact - [fact] **The PAM module is `pam_kwallet5.so` even for KDE Frameworks 6 / Plasma 6.** There is no `pam_kwallet6.so`. The "5" in the name is a legacy artifact. The previous discovery note incorrectly stated `pam_kwallet6.so` would be provided — this was wrong. - [fact] The existing `/etc/pam.d/sddm` and `/etc/pam.d/sddm-autologin` files already reference `pam_kwallet5.so` — they just need the package installed; **no module name changes are needed**. ## (2) PAM configuration ### Plasma 6 / ksecretd consideration The Arch Wiki (section "Configure PAM on Plasma 6 (KF6)", updated 2026-03-10) says Plasma 6 uses `ksecretd` as the secret service daemon. The PAM session line should include `kwalletd=/usr/bin/ksecretd` to point to the new daemon. - [fact] `ksecretd` binary is at `/usr/bin/ksecretd` and is shipped by the `kwallet` package (6.23.0-1) - [fact] `kwalletd6` binary is at `/usr/bin/kwalletd6` and is also in the `kwallet` package - [decision] For a non-Plasma Hyprland setup, the question is which daemon to target. The Arch Wiki recommends `kwalletd=/usr/bin/ksecretd` for KF6. Since the user has `kwalletd6` and `ksecretd` both installed via the `kwallet` package, and the Arch Wiki explicitly documents this parameter for KF6, the documentation should use the `kwalletd=/usr/bin/ksecretd` parameter. ### Recommended `/etc/pam.d/sddm` (password login) The file already has the right structure. After installing `kwallet-pam`, the existing lines become functional. However, for Plasma 6 / KF6 compatibility, the session line should add the `kwalletd=` parameter: ``` #%PAM-1.0 auth sufficient pam_u2f.so cue auth include system-login -auth optional pam_gnome_keyring.so -auth optional pam_kwallet5.so account include system-login password include system-login session optional pam_keyinit.so force revoke session include system-login -session optional pam_gnome_keyring.so auto_start -session optional pam_kwallet5.so auto_start kwalletd=/usr/bin/ksecretd ``` Key points: - [fact] The `-` prefix on `-auth` and `-session` lines means "skip silently if module is missing" — this is already present in the default SDDM PAM files - [fact] The `auth` line captures the user password for later use by the session line - [fact] The `session` line with `auto_start` tells the module to start kwalletd/ksecretd and unlock the wallet - [fact] `kwalletd=/usr/bin/ksecretd` directs the module to use KF6's ksecretd daemon instead of the legacy kwalletd5 ### Recommended `/etc/pam.d/sddm-autologin` This file is for SDDM autologin ONLY. Since the chosen model is password login, this file is informational but should still be kept correct: ``` #%PAM-1.0 auth sufficient pam_u2f.so cue auth required pam_permit.so -auth optional pam_kwallet5.so account include system-local-login password include system-local-login session include system-local-login -session optional pam_kwallet5.so auto_start kwalletd=/usr/bin/ksecretd ``` - [caveat] Autologin skips password entry → PAM has no password to pass to `pam_kwallet5.so` → wallet cannot be unlocked unless LUKS passphrase forwarding is used (see section 5) ### Minimal edit needed for existing system Since the existing `/etc/pam.d/sddm` already has `pam_kwallet5.so` lines, the only change needed is: 1. Install `kwallet-pam` (makes the module file appear at `/usr/lib/security/pam_kwallet5.so`) 2. Add `kwalletd=/usr/bin/ksecretd` to the session line for KF6 compatibility The auth line does NOT need the `kwalletd=` parameter — only the session line does. ## (3) Wallet initialization for non-Plasma (Hyprland) users ### Step A: Create the wallet The wallet **must** be named `kdewallet` (the default name). PAM unlock only works with this specific wallet name. **Option 1 — GUI (recommended if kwalletmanager is available):** ```bash sudo pacman -S kwalletmanager kwalletmanager6 ``` Then: File > New Wallet > name it `kdewallet` > set password to match login password > choose **blowfish** encryption (NOT GPG). **Option 2 — Headless/CLI:** No pure-CLI wallet creation tool exists. The wallet is created automatically when: 1. The PAM module is installed and configured 2. The user logs in via SDDM with password 3. `pam_kwallet_init` runs and kwalletd6/ksecretd starts 4. If no wallet exists, kwalletd6 creates one on first access For a truly headless init, trigger it by running in the session: ```bash # Ensure kwalletd6/ksecretd is running (D-Bus activated) dbus-send --session --dest=org.kde.kwalletd6 --print-reply \ /modules/kwalletd6 org.kde.KWallet.open \ string:"kdewallet" int64:0 string:"init" ``` This prompts for the wallet password interactively (Qt dialog). ### Step B: Ensure wallet password matches login password - [requirement] The KWallet password MUST be identical to the Unix user login password. PAM passes the login password to the kwallet module; if they differ, the wallet won't unlock. - [requirement] If the user password is changed later, the wallet password must be updated to match. Use `kwalletmanager6` > Change Password, or delete and recreate the wallet. ### Step C: kwalletrc configuration Create `~/.config/kwalletrc` if it doesn't exist: ```ini [Wallet] Default Wallet=kdewallet Enabled=true First Use=false [org.freedesktop.secrets] apiEnabled=true ``` The `apiEnabled=true` setting enables the org.freedesktop.secrets D-Bus API, allowing libsecret-based apps (Chromium, VSCode, etc.) to use KWallet. ### Step D: Autostart `pam_kwallet_init` in Hyprland The `kwallet-pam` package installs an XDG autostart entry (`/etc/xdg/autostart/pam_kwallet_init.desktop`), but Hyprland does NOT process XDG autostart files by default. Add to `~/.config/hypr/hyprland.conf`: ``` exec-once = /usr/lib/pam_kwallet_init ``` This script reads the PAM-cached credentials and passes them to kwalletd6/ksecretd to unlock the wallet. ### Step E: D-Bus activation service (optional but recommended) Create `~/.local/share/dbus-1/services/org.freedesktop.secrets.service`: ```ini [D-BUS Service] Name=org.freedesktop.secrets Exec=/usr/bin/kwalletd6 ``` This ensures kwalletd6 auto-starts when any app requests secrets via D-Bus, even before the wallet is explicitly opened. ## (4) Verification ### Quick verification after login ```bash # 1. Check the PAM module is installed ls -la /usr/lib/security/pam_kwallet5.so # 2. Check kwalletd6 or ksecretd is running pgrep -a kwalletd6 || pgrep -a ksecretd # 3. Check the wallet is open dbus-send --session --dest=org.kde.kwalletd6 --print-reply \ /modules/kwalletd6 org.kde.KWallet.isOpen \ string:"kdewallet" # 4. Check wallet files exist ls -la ~/.local/share/kwalletd/ # 5. Query the wallet (should return without prompting for password) kwallet-query -l kdewallet # 6. Check environment variables set by pam_kwallet_init echo $PAM_KWALLET5_LOGIN ``` ### Full integration test 1. Log out of Hyprland 2. At SDDM greeter, type user password and log in 3. After Hyprland starts, run `kwallet-query -l kdewallet` — it should list folders without prompting 4. Open a KWallet-aware app (e.g., Chromium with `--password-store=kwallet5`) and verify it stores/retrieves credentials ### Troubleshooting if wallet doesn't auto-unlock - Check `journalctl --user -u plasma-kwallet-pam.service` for errors - Check `journalctl -b | grep -i kwallet` for PAM-level errors - Verify wallet password matches login password exactly - Verify wallet is named exactly `kdewallet` (not `default` or any other name) - Verify wallet uses blowfish encryption, not GPG ## (5) Caveats ### U2F / pam_u2f.so interaction - [risk] The existing `/etc/pam.d/sddm` has `auth sufficient pam_u2f.so cue` as the FIRST auth line. When `sufficient` succeeds, PAM skips remaining auth modules — including `pam_kwallet5.so`. - [consequence] If the user authenticates via U2F key only (no password typed), the kwallet module never captures a password → wallet cannot be unlocked automatically. - [mitigation] This is acceptable if U2F is used as a convenience shortcut and the user accepts that wallet won't auto-unlock in that case. The wallet can be manually unlocked later. - [alternative] To make U2F + kwallet work together, change `sufficient` to a two-factor setup where password is always required. But this changes the security model and is out of scope for this documentation. ### Autologin caveat - [risk] SDDM autologin (`pam_permit.so`) provides no password → `pam_kwallet5.so` has nothing to unlock the wallet with. - [fact] The Arch Wiki documents a workaround using `pam_systemd_loadkey.so` for LUKS-encrypted systems: the LUKS passphrase can be forwarded from the initramfs to the PAM stack, allowing wallet unlock even with autologin. - [requirement] This requires: (1) systemd-based initramfs (`sd-encrypt` hook, not classic `encrypt`), (2) `pam_systemd_loadkey.so` line in sddm-autologin, (3) sddm.service override with `KeyringMode=inherit`. - [fact] The current system uses classic `encrypt` hook, NOT `sd-encrypt`, so this workaround is NOT available without migrating the initramfs to systemd hooks. - [decision] Since password login (not autologin) was chosen, this is informational only. ### Fingerprint reader caveat - [fact] KWallet cannot be unlocked using a fingerprint reader (per Arch Wiki). Similar to U2F — no password is available. ### GPG encryption caveat - [fact] `kwallet-pam` does NOT work with GPG-encrypted wallets. The wallet MUST use standard blowfish encryption. ### hyprlock caveat - [fact] hyprlock uses `auth include login` in `/etc/pam.d/hyprlock`. The login PAM chain does NOT include kwallet PAM modules. Unlocking hyprlock will NOT re-open the wallet if it was closed. - [mitigation] Typically the wallet stays open for the session duration. If the wallet is configured with `Leave Open=true` (in kwalletrc or kwalletmanager), it won't close automatically. ### Password change caveat - [fact] If the user's login password is changed (via `passwd`), the wallet password must be manually updated to match. PAM does not automatically synchronize wallet passwords on password change. ## Relations - related_to [[LUKS SDDM KWallet discovery]] - related_to [[luks-sddm-kwallet-login-integration]] - related_to [[LUKS SDDM KWallet documentation targets]]