How to decrypt LUKS-encrypted device on per user basis upon login?

I would suggest creating and enabling a Type=oneshot RemainAfterExit=yes service for the user that creates a file with it's ExecStart directive, and removes it with it's ExecStop directive e.g.

ExecStart="/usr/bin/touch %h/.decrypt"
ExecStop="/usr/bin/rm %h/.decrypt"

You can then create and enable a [email protected] unit file for the system user with an absolute path:

PathExists="/home/user/.decrypt"

This would check for the path created by the user service above, activating the [email protected] unit when it is created, and deactivating it when it is removed, thus establishing an indirect dependency of the system service on the user service.

Note that for this to operate securely, the directory in which the file is created should be writable by the user only, of course.


An alternative solution would be to edit the sudoers file to add permissions for the user in question to run /usr/lib/systemd/systemd-cryptsetup with root permissions with NOPASSWD option enabled.

You would then edit your (user-specific) service file above to read:

ExecStart=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup attach '%I.luks' '/dev/mapper/%I' '%h/%I/secret.key' 'luks,header=%h/%I/header'
ExecStop=/usr/bin/sudo /usr/lib/systemd/systemd-cryptsetup detach '%I.luks'

I'm not sure whether you would also have to enable !requiretty for this to work

Update:

To increase security around this, especially for a multiple-user system, I'd highly recommend creating a couple of scripts to perform the 'attach' and 'detach' steps on behalf of the user rather than giving sudo access to /usr/lib/systemd/systemd-cryptsetup directly, as otherwise any user that is given access to run this command can potentially interfere with other encrypted volumes.