Password Agents

systemd 12 and newer support lightweight password agents which can be used to query the user for system-level passwords or passphrases. These are passphrases that are not related to a specific user, but to some kind of hardware or service. This is used for encrypted hard-disk passphrases or to query passphrases of SSL certificates at web server start-up time. The basic idea is that a system component requesting a password entry can simply drop a simple .ini-style file into /run/systemd/ask-password/ which multiple different agents may watch via inotify(), and query the user as necessary. The answer is then sent back to the querier via an AF_UNIX/SOCK_DGRAM socket. Multiple agents might be running at the same time in which case they all should query the user and the agent which answers first wins. Right now systemd ships with the following passphrase agents:

Implementing Agents

It is easy to write additional agents. The basic algorithm to follow looks like this:

Again, it is essential that you stop showing the password box/notification/status icon if the ask.xxxx file is removed or when NotAfter= elapses (if it is set != 0)!

It may happen that multiple password entries are pending at the same time. Your agent needs to be able to deal with that. Depending on your environment you may either choose to show all outstanding passwords at the same time or instead only one and as soon as the user has replied to that one go on to the next one.

If you write a system level agent, a smart way to activate it is using systemd .path units. This will ensure that systemd will watch the /run/systemd/ask-password/ directory and spawn the agent as soon as that directory becomes non-empty. In fact, the console, wall and Plymouth agents are started like this. If systemd is used to maintain user sessions as well you can use a similar scheme to automatically spawn your user password agent as well.

Implementing Queriers

It’s also easy to implement applications that want to query passwords this way (i.e. client for the agents above). Simply bind an AF_UNIX/SOCK_DGRAM socket somewhere (suggestion: you can do this in /run/systemd/ask-password/ under a randomized socket name, not beginning with ask.). Then, create an /run/systemd/ask-password/ask.xxxx (replace the xxxx by some randomized string) file, with the appropriate Message=, PID=, Icon=, Echo=, NotAfter= fields in the [Ask] section. Most importantly, include Socket= pointing to your socket entrypoint. Then, just wait until the password is delivered to you on the socket. Finally, don’t forget to remove the file and the socket once done.

Testing

You may test agents by manually invoking the “systemd-ask-password” tool from a shell. Pass --no-tty to ensure the password is asked via the agent system.

You may test queriers by manually invoking the “systemd-tty-ask-password-agent” from a shell.

Unprivileged Per-User Password Agents

Starting with systemd v257 the scheme is extended to per-user password agents. A second per-user directory $XDG_RUNTIME_DIR/systemd/ask-password/ is now available, with the same protocol as the system-wide counterpart. Unprivileged, per-directory agents should watch this directory in parallel to the system-wide one. Unprivileged queriers (i.e. clients to these agents) should pick the per-user directory to place their password request files in.