Skip to content

Commit

Permalink
design pages: Passwordless-GDM integration
Browse files Browse the repository at this point in the history
Passwordless authentication from the GUI.

Signed-off-by: Iker Pedrosa <[email protected]>
  • Loading branch information
ikerexxe committed Jan 17, 2024
1 parent dd73964 commit b3e17c3
Show file tree
Hide file tree
Showing 2 changed files with 313 additions and 0 deletions.
243 changes: 243 additions & 0 deletions src/design-pages/passwordless_gdm.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
Passkey authentication Kerberos integration
=======================================================

Related ticket(s):
------------------
* https://github.com/SSSD/sssd/issues/7069

Problem statement
-----------------
Passwordless authentication is becoming increasingly popular. SSSD and FreeIPA
already provide several authentication mechanisms which make use of it:
`Smart Cards <https://sssd.io/design-pages/smartcards.html>`__,
`External Identity Providers <https://freeipa.readthedocs.io/en/latest/designs/external-idp/external-idp.html>`__ (EIdP)
and `Passkeys <https://sssd.io/design-pages/passkey_kerberos.html>`__.
Unfortunately, the integration of these mechanisms into the graphical interface
leaves much to be desired. Some of them may work in a degraded mode, while
others can’t be used at all.

SSSD and the GUI should be better integrated to make all these authentication
mechanisms effortless for the user. This would increase the overall security of
the system, by providing the benefits of these authentication mechanisms, i.e.
passwordless, MFA, etc.

SSSD and `GDM <https://wiki.gnome.org/Projects/GDM>`__ are working together to
provide a set of interfaces that can be used to enable these authentication
mechanisms in Linux’s GUI. While the initial work targets SSSD-GDM integration,
the objective is that these interfaces can be used by any other desktop
environment.

The use of new tools to authenticate users, such as 2FA, U2F and FIDO2, is
becoming increasingly popular. Currently SSSD provides local authentication of
a centrally managed user with passkeys, but it doesn't provide any way to
authenticate remotely to a system. This diminishes the value provided by SSSD
in some environments like big companies and governments, where remote
authentication is a common pattern.

Use cases
---------
* As a centrally managed user, I want to choose the authentication mechanism
to login from the graphical interface so that I can select the one that best
suits my needs.

* As a centrally managed user, I want to use an external identity provider
(IdP) to login from the graphical interface so that the user interface is
easy to use and consistent across all authentication mechanisms in the
distribution.

* As a centrally managed user, I want to select the smart card identity to
login from the graphical interface so that the authentication is performed
with the correct credentials.

* As a centrally managed user, I want to use a passkey to login from the
graphical interface so that the user interface is easy to use and consistent
across all authentication mechanisms in the distribution.

* As a centrally managed user, I want to get notified when the passkey
authentication has been performed locally so that I am aware that the user
experience might be affected.

Solution overview
-----------------
The objective is to provide usable workflows for users to authenticate in the
graphical interface using passwordless authentication mechanisms. To do this,
we first need to design a communication protocol between SSSD and GDM.

The APIs can be implemented in two ways, either by implementing them in
`D-BUS <https://www.freedesktop.org/wiki/Software/dbus/>`__, or by extending
the PAM conversation to include the new authentication mechanisms. There
doesn’t seem to be any advantage in using D-BUS, whereas a PAM-level API would
give other desktop environments the ability to offer similar features. For this
reason, the GDM PAM extension has been selected.

GDM already provides an interface in ``/usr/include/gdm/gdm-pam-extensions.h``
that SSSD supports. Unfortunately extending this binary interface is hard, so
a JSON based protocol is used. It’s easier to extend and manage, making it
easier to adapt the different packages involved. The previous implementation
will continue to be maintained for backward compatibility.

As for the workflows, they have to provide the user with a way to interact
(i.e. insert the hardware token or enter the PIN), while allowing communication
with the device or the external provider. Each authentication mechanism needs
its own sequence diagram definition, which will be explained later in this
document.

Implementation details
----------------------

Sequence diagram
****************
The communication between SSSD and GDM is explained in the following sequence
diagram.

.. uml:: ../diagrams/passwordless-gdm-auth.pu

* GDM prompts the user for their username.

* The user initiates the login procedure by entering their username.

* GDM starts the PAM conversation.

* GDM starts the authentication process in SSSD.

* pam_sss communicates with the PAM responder to resolve the user.

* PAM responder resolves the username and obtains, among other things, the
available authentication methods and the prompting strings.

* PAM responder prepares the JSON message with the available authentication
mechanisms, the prompts and the user credentials to be requested
(check format in :ref:`data`).

* PAM responder returns this information to pam_sss.

* pam_sss wraps the JSON message in the PAM conversation.

* GDM prompts the user for the user credentials, and at the bottom of the
screen it shows the available authentication mechanisms. If the user selects
another method, GDM already has all the information needed to request the
user credentials for this authentication mechanism.

* The authentication workflow continues, but varies depending on the selected
authentication mechanism. This will be explained separately for each
mechanism.

.. _data:

Data
****
In addition, the messages exchanged follow the JSON standard. SSSD provides the available authentication mechanisms in the following message:

.. code-block:: json
{
"auth-selection": {
"mechanisms": [
{
"$mech1": {
"msg1": "msg1"
},
}
{
"$mech2": {
"msg1": "msg1",
"msg2": "msg2"
},
}
]
}
}
GDM answers with the result for the previous JSON message processing:

.. code-block:: json
{
"auth-selection": {
"code": "$code",
"message": "$message"
}
}
Examples for the two messages are defined in the following lines.

Password
++++++++
.. code-block:: json
{
"auth-selection": {
"mechanisms": [
{
"password": {
"prompt": "Password"
}
}
]
}
}
EIdP
++++
.. code-block:: json
{
"auth-selection": {
"mechanisms": [
{
"eidp": {
"init_prompt": "EIdP login",
"link_prompt": "EIdP login",
"uri": "short.url.com/1234",
"code": "1234"
}
}
]
}
}
Password and EIdP
+++++++++++++++++
.. code-block:: json
{
"auth-selection": {
"mechanisms": [
{
"password": {
"prompt": "Password"
}
},
{
"eidp": {
"init_prompt": "EIdP login",
"link_prompt": "EIdP login",
"uri": "short.url.com/1234",
"code": "1234"
}
}
]
}
}
GDM reply
+++++++++
.. code-block:: json
{
"auth-selection": {
"code": "0",
"message": "Ok"
}
}
Smart card
++++++++++

Passkey
+++++++

Authors
-------
* Iker Pedrosa <[email protected]>
* Ray Strode <[email protected]>
70 changes: 70 additions & 0 deletions src/diagrams/passwordless-gdm-auth.pu
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
@startuml
actor User

box "Client"
participant "passkey"
end box

participant "PAM"

box "SSSD"
participant "PAM responder"
participant "cache"
participant "IPA provider"
participant "krb5_child"
participant "passkey_child"
end box

participant "libkrb5"

box "FreeIPA server"
participant "Kerberos KDC"
participant "ipa-otpd"
participant "LDAP"
participant "passkey_child_ipa"
end box

User -> PAM: Login
PAM -> "PAM responder": pre_authenticate
"PAM responder" -> cache: Retrieve user information
cache -> "PAM responder": User information
"PAM responder" -> "IPA provider": pre_authenticate ()
"IPA provider" -> krb5_child: pre_authenticate ()
krb5_child -> "libkrb5": pre_authenticate ()
"libkrb5" -> "Kerberos KDC": AS-REQ (preauth)
"Kerberos KDC" -> "ipa-otpd": Access-Request (username)
"ipa-otpd" -> LDAP: Retrieve user information
LDAP -> "ipa-otpd": User information
"ipa-otpd" -> "Kerberos KDC": Access-Challenge(State, Reply-Message=assertion req data)
"Kerberos KDC" -> "libkrb5": krb5 error (preauth required PASSKEY, assertion req data)
"libkrb5" -> krb5_child: krb5 error (preauth required PASSKEY, assertion req data)

krb5_child -> "IPA provider": error (preauth required PASSKEY, assertion req data)
"IPA provider" -> "PAM responder": error (preauth required PASSKEY, assertion req data)
"PAM responder" -> PAM: Get PIN
PAM -> User: Ask for PIN
User -> PAM: Input PIN
PAM -> "PAM responder": Set PIN
"PAM responder" -> passkey_child: Run (assertion req data, PIN)
passkey_child -> "passkey": Request assertion (assertion req data, PIN)
"passkey" -> passkey_child: Return assertion
passkey_child -> "PAM responder": Assertion data

"PAM responder" -> "IPA provider": pre_authenticate (assertion)
"IPA provider" -> krb5_child: pre_authenticate (assertion)
krb5_child -> "libkrb5": pre_authenticate (assertion)
"libkrb5" -> "Kerberos KDC": AS-REQ (assertion in preauth)
"Kerberos KDC" -> "ipa-otpd": Access-Request (assertion data)
"ipa-otpd" -> passkey_child_ipa: Validate assertion
passkey_child_ipa -> "ipa-otpd": Authentication success
"ipa-otpd" -> "Kerberos KDC": Access-Accept
"Kerberos KDC" -> "libkrb5": AS-REP with ticket

"libkrb5" -> krb5_child: Kerberos ticket
krb5_child -> krb5_child: Store Kerberos ticket into ccache
krb5_child -> "IPA provider": Authentication success
"IPA provider" -> "PAM responder": Authentication success
"PAM responder" -> PAM: Authentication success
PAM -> User: Authentication success

@enduml

0 comments on commit b3e17c3

Please sign in to comment.