-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
design pages: Passwordless-GDM integration
Passwordless authentication from the GUI. Signed-off-by: Iker Pedrosa <[email protected]>
- Loading branch information
Showing
2 changed files
with
313 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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]> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |