I used to use GDM as my display manager, but I have had some issues with it, which is why I decided to try to switch go greetd, however I cannot for the life of me, figure out how I can make it auto unlock the gnome-keyring using the LUKS password used for disk decryption when logging in automatically. I had it working using GDM by creating a gdm-autologin file I will include the working configuration for GDM at the end. What I have in my new config so far is the following
Everything except the automatic unlocking of the gnome-keyring works perfectly. If I donāt set the initial_session, and log in manually after disk decryption, the keyring is unlocked when entering Hyprland as I would expect.
As stated earlier I had this working with GDM, and I want to only enter my password once on boot, and preferably when decrypting my disk. Here is the config I used for GDM for anyone interested:
So these lines are the reason it works with GDM. When GDM does autologin, it uses the gdm-autologin PAM service. The pam_gdm module retrieves the LUKS passphrase from the kernel keyring and sets the PAM auth token to it (though, this is actually the same as what the pam_systemd_loadkey module would do; we just donāt use that anywhere right now I think), then the pam_gnome_keyring.so module launches the gnome-keyring-daemon and passes it the auth token to unlock the keyring.
So youāll need greetd to be using a similar PAM service when doing autologin. I believe those same GDM pam modules will actually work in another PAM service, believe it or not. If greetd doesnāt also use a PAM service for autologin, then I think youāre out of luck and will have to do something custom.
I tried to put something together based on that PR and some other information I found online, and ended up with this, however it still does not work, even though I think it should based on my (very limited) understanding. This article seems to match with what I am doing, and what is in the PR (which as far as I can tell is for GDM, which I am trying to adapt to greetd). Can you spot the issue with my approach?
Unfortunately not no. I ended up accepting logging in twice on each boot for a while, and now I changed from greetd to sddm where I have not yet tried to get it to work, but at least now I have a pretty theme to look at when logging in the second time.
This canāt be (correctly) done until the Greetd PAM service includes/substacks the login PAM service. See this issue for more details - hopefully someone can prove me wrong.
Also, if pam_systemd_loadkey is used in pull/286587, we could potentially have an all purpose display manager module - decoupled from GDM or any specific DM.
That said - In the meantime, you can either leave your login keyring password blank or add the following to your home-manager config (where āsomepassā is your password in plain-text):
Obviously, neither of these temporary workarounds are ideal, and Iām not a security expert so Iām not sure which is the better option from a security standpoint.
Fair warnings aside, hereās my tuigreet.nix config for an automatic login (Iām sure some of this can be paired down - but itās been a long four days to get to this point):
@cccslater, I can help troubleshoot with a few questions:
is the āecho -n āsomepassā | gnome-keyring-daemon --unlockā line making it into your ~/.profile file?
Are you using bash?
Immediately after logging in, does seahorse show a locked or unlocked padlock, or no padlock at all?
Does journalctl -b | grep gnome-keyring have any helpful info? And does ps aux | grep gnome-keyring-daemon show that the gnome-keyring-daemon is running on boot prior to opening a GTK app?
Which GTK app are you opening? I can try reproducing on my end.
In your configuration.nix, do you have environment.sessionVariables = { XDG_RUNTIME_DIR = "/run/user/$UID"; }; set?
Went through all the steps, typed out a huuuge message, then noticed --unlock is for the login keyring. My login keyring has never worked properly ā I added login.enableGnomeKeyring = true; and now I can unlock the login keyring (in Seahorse).
I managed to unlock from the command line once or twice, but canāt get it working again!
I think the issue is my login keyring keeps emptying itself somehow. Iāve deleted it a few times to try and start it again but I canāt work out how to populate it properly.
OK, with a lot of back and forth and fiddling, I now have a working keyring. Thanks so much for the tips, @guttermonk!
I just got tuigreet auto-unlock working (running nixos 25.11). Credit goes to Ivan Brennan for posting this on sourcehut, and to Tim Ruffing for making the connection between the original message on sourcehut and this thread and for letting me know.
Requirements:
Requires boot.initrd.systemd.enable = true
Requires LUKS encryption
User password must match LUKS password
Here is my tuigreet-autounlock.nix
{ pkgs, lib, ... }:
let
tuigreetBin = "${pkgs.tuigreet}/bin/tuigreet";
session = "start-hyprland > /dev/null";
username = "youruser"; # Change this to your username
# Theme colors and spacing
containerColor = "darkgray";
borderColor = "lightblue";
containerPadding = "3";
timeFormat = "'%I:%M %p | %a ⢠%h | %F'";
# Package for pam_fde_boot_pw - retrieves LUKS password from systemd
# https://git.sr.ht/~kennylevinsen/pam_fde_boot_pw
pam_fde_boot_pw = pkgs.stdenv.mkDerivation {
pname = "pam_fde_boot_pw";
version = "0.1.0";
src = pkgs.fetchzip {
url = "https://git.sr.ht/~kennylevinsen/pam_fde_boot_pw/archive/master.tar.gz";
sha256 = "sha256-dS9ufryg3xfxgUzJKDgrvMZP2qaYH+WJQFw1ogl1isc=";
};
nativeBuildInputs = [ pkgs.pkg-config pkgs.meson pkgs.ninja ];
buildInputs = [ pkgs.pam pkgs.systemd pkgs.keyutils ];
};
in
{
environment.systemPackages = with pkgs; [
tuigreet
libsecret
gnome-keyring
libgnome-keyring
];
# CRITICAL: Required for pam_fde_boot_pw to work
# Stores the LUKS password in systemd so it can be retrieved later
boot.initrd.systemd.enable = true;
# Enable gnome-keyring service
services.gnome.gnome-keyring.enable = true;
# Enable the graphical frontend for managing keyring
programs.seahorse.enable = true;
# PAM Configuration
# The key insight: greetd's initial_session (autologin) doesn't call PAM auth,
# so we inject the LUKS password during the session phase instead using pam_fde_boot_pw.
# See: https://lists.sr.ht/~kennylevinsen/greetd-devel/%3CCAOVAYzup8rEVtq1q4Bw5jZS=tf1WyeWwhHB0jgHvoZyhUuGZeg@mail.gmail.com%3E
security.pam.services.greetd = {
enableGnomeKeyring = true;
# Add pam_fde_boot_pw rule BEFORE gnome_keyring in the session phase
# This ensures the LUKS password is injected before gnome-keyring tries to unlock
# Order 12600: gnome_keyring is typically at 12700, so this runs before it
rules.session.fde_boot_pw = {
order = 12600;
enable = true;
control = "optional";
modulePath = "${pam_fde_boot_pw}/lib/security/pam_fde_boot_pw.so";
args = [ "inject_for=gkr" ];
};
};
# Enable gnome-keyring for other PAM services
security.pam.services = {
greetd-password.enableGnomeKeyring = true;
login.enableGnomeKeyring = true;
gdm-password.enableGnomeKeyring = true;
};
# greetd configuration
services.greetd = {
enable = true;
settings = {
# initial_session is used for autologin
initial_session = {
command = "${session}";
user = "${username}";
};
# default_session is used for manual login
default_session = {
command = "${tuigreetBin} --remember --asterisks --container-padding ${containerPadding} --time --time-format ${timeFormat} --cmd '${session}' --theme 'container=${containerColor};border=${borderColor}'";
user = "greeter";
};
};
};
# greetd systemd service configuration
# CRITICAL for autologin to work properly
# https://www.reddit.com/r/NixOS/comments/u0cdpi/tuigreet_with_xmonad_how/
systemd.services.greetd.serviceConfig = {
Type = "idle"; # DO NOT CHANGE - "simple" breaks autologin!
StandardInput = "tty";
StandardOutput = "tty";
StandardError = "journal";
TTYReset = true;
TTYVHangup = true;
TTYVTDisallocate = true;
KeyringMode = lib.mkForce "inherit";
};
# Disable getty@tty1 to prevent TTY interference
# https://github.com/NixOS/nixpkgs/issues/103746
systemd.services."getty@tty1".enable = false;
systemd.services."autovt@tty1".enable = false;
# SSH agent configuration
programs.ssh.startAgent = false;
environment.sessionVariables = {
SSH_AUTH_SOCK = "/run/user/1000/gcr/ssh";
};
}
How It Works
You unlock LUKS at boot ā systemd stores the password
greetd starts initial_session (autologin, no PAM auth)
When greetd performs auto-login, it skips the PAM auth stack altogether, so neither pam_systemd_loadkey nor pam_gdm are effective. Instead, you can use pam_fde_boot_pw (written by the author of greetd), which ties into the PAM session stack.
I was initially setting KeyringMode to inherit too, but found that shared works as well.
The pam_fde_boot_pw README mentions,
you may need to specify KeyringMode=inherit or KeyringMode=shared
Iāve been using shared since, but mostly because thatās what the existing NixOS module for greetd uses. I donāt know which of inherit or shared is truly the best choice in this case.