[systemd-devel] RFC: userdb authentication protocol

Dominik George nik at naturalnet.de
Mon Jul 21 10:39:42 UTC 2025


Hi,

currently, the userdb system only allows querying for User Records and
Group Records, hence providing a modern replacement for NSS.

I would like to propose an addition to make it support authentication as
well. The additions to the io.systemd.UserDatabase Varlink interface
are:

```varlink
# Start the authentication process for a user
#
# Requires a username, and an optional authentication authToken
# (e.g. a password).
#
# The method can return:
#
#  * a User Record object of the user that was authenticated
#  * a conversation token for the AuthenticateContinue method
#  * nothing at all (authentication finished and successful, but no details provided)
method Authenticate(
        userName : string,
        authToken : ?string,
        variables : []string,
        client : ?string,
        service : string
) -> (
        convToken : ?int,
        user : ?object
)

# Continue an ongogin conversation
#
# For example, the Authenticate method might have requested a conversation
# with the user, like in the OAuth Device Authorization Grant Flow where the
# user will need to open a web page on another device to log in.
# In such a case, the Authenticate method will return a matching error with
# a conversation token, and the client requesting authentication can later
# continue the process using this conversation token.
method AuthenticateContinue(
        convToken : int,
        authToken : ?string,
        variables : []string,
        client : ?string,
        service : string
) -> (
        user : ?object
)

# Cancel an ongogin authentication process for which a conversation token
# has been issued
method AuthenticateCancel(
        convToken : int,
        client : ?string,
        service : string
)

# The authentication process was finished, but the authentication token was invalid
error InvalidAuthToken(message: ?string)

# An authentication token was not provided, but is required
# If a conversation token is issued, the client can use AuthenticateContinue.
# Otherwise, it has to restart the process.
error AuthTokenRequired(convToken: ?int, message: ?string)

# A conversation with the user is required (e.g. ask a non-auth-token question,
# open a website, etc.).
# Once a reply was acquired, the client must continue the process using
# AuthenticateContinue.
error ConvRequired(convToken: int, message: string)

# The authentication is ongoing, but cannot complete right now.
# The service might be waiting for some backend to complete a task,
# or for the user to acknowledge a second factor in some external app
# or whatever. The client should ask for progress after the specified
# interval, but does not need to provide any new information.
error RetryRequired(convToken: int, interval: int, message: ?string)

# An ongoging conversation timed out while waiting for the client to
# continue.
error ConvTimeout(message: ?string)
```

The protocol is designed with PAM compatibility in mind, so it borrows
some of its terminology. However, it is tailored to asynchronous
authentication mechanisms, like various OAuth / OIDC flows.

Concerning backwards compatibility, I propose that:

 * The userdbd multiplexer should try to call the Authenticate methods
   on downstreams, and watch out for any MethodNotImplemented errors.
   If a backend does not implement the Authenticate methods, the
   multiplexer can try to authenticate against a hashedPassword in
   the User Record itself.
 * Implementations that have been done before will continue to work,
   because the proposal only contains additions, but no changes to
   existing methods.

Instead of making a new interface for this, I propose to add it to the
UserDatabase interface, so most code can jsut continue to work, and we
can build on top of the existing multiplexer and socket infrastructure
(however, this might also be possible while defining a second interface,
but I also want to re-use the error types from UserDatabase).

Comments welcome.

Cheers,
Nik
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 297 bytes
Desc: not available
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20250721/3eb1ff0d/attachment.sig>


More information about the systemd-devel mailing list