Oauth2 pkce faq ()

This commit is contained in:
Firstyear 2024-02-06 12:05:52 +10:00 committed by GitHub
parent aa00ac94d0
commit cd27879e7f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 202 additions and 149 deletions

View file

@ -56,8 +56,8 @@ When we develop features we follow our projects guidelines on [rights and ethics
## Getting in Contact / Questions
We have a Matrix-powered [gitter community channel] where project members are always happy to chat and answer questions.
Alternately you can open a new [github discussion].
We have a Matrix-powered [gitter community channel] where project members are always happy to chat
and answer questions. Alternately you can open a new [github discussion].
[gitter community channel]: https://app.gitter.im/#/room/#kanidm_community:gitter.im
[github discussion]: https://github.com/kanidm/kanidm/discussions

View file

@ -65,7 +65,7 @@
# For Developers
- [Developer Guide](DEVELOPER_README.md)
- [FAQ](developers/faq.md)
- [Frequently Asked Questions](developers/faq.md)
- [Design Documents]()
- [Access Profiles 2022](developers/designs/access_profiles_rework_2022.md)
- [Access Profiles Original](developers/designs/access_profiles_and_security.md)

View file

@ -1,127 +1,118 @@
# Rationale
Kanidm exists to provide an authentication source for external applications.
These applications need to have standardised ways to integrate with Kanidm to
allow that application to interact and trust Kanidm's authentication results.
Kanidm exists to provide an authentication source for external applications. These applications need
to have standardised ways to integrate with Kanidm to allow that application to interact and trust
Kanidm's authentication results.
For web based applications we offer Oauth2/OIDC. For Linux machines we offer a
Kanidm specific HTTPS channel for identifying users (UNIX integration).
Currently, for applications that don't support other protocols we offer an LDAPS
gateway that allows users to bind using their UNIX password.
For web based applications we offer Oauth2/OIDC. For Linux machines we offer a Kanidm specific HTTPS
channel for identifying users (UNIX integration). Currently, for applications that don't support
other protocols we offer an LDAPS gateway that allows users to bind using their UNIX password.
However this has the issue that due to how limited Linux authentication is, UNIX
passwords are always single factor. We also don't want the same UNIX credentials
that are used, e.g. for sudo on machines, to be leaked and used for applications
like email.
However this has the issue that due to how limited Linux authentication is, UNIX passwords are
always single factor. We also don't want the same UNIX credentials that are used, e.g. for sudo on
machines, to be leaked and used for applications like email.
To improve this we need a way to offer authentication services to applications
that are unable to support anything modern.
To improve this we need a way to offer authentication services to applications that are unable to
support anything modern.
Since LDAP is the "lingua franca" of authentication and almost universally
implemented as an authentication for all applications, we can use this to
provide *application specific* password based authentication and remove the
ability to bind with the UNIX password.
Since LDAP is the "lingua franca" of authentication and almost universally implemented as an
authentication for all applications, we can use this to provide _application specific_ password
based authentication and remove the ability to bind with the UNIX password.
# User experience
The administrator configures two applications on their Kanidm instance. One is
"mail" for a generic SMTP+IMAP service. The other is HTTP basic auth to a legacy
web server. Then the administrator configures which users will be able to use
application passwords for each application.
The administrator configures two applications on their Kanidm instance. One is "mail" for a generic
SMTP+IMAP service. The other is HTTP basic auth to a legacy web server. Then the administrator
configures which users will be able to use application passwords for each application.
The mail services and web services are configured to point to Kanidm's LDAP
gateway with a customized search base DN.
The mail services and web services are configured to point to Kanidm's LDAP gateway with a
customized search base DN.
The users can login to the webui or command line and list what linked
applications exist on their accounts that require application passwords.
The users can login to the webui or command line and list what linked applications exist on their
accounts that require application passwords.
The users can then request a new "application password" for the mail server for
their laptop and another one for their phone. They can copy-paste the generated
passwords to their mail clients which uses this password on their behalf.
Similarly, they can request a new application password to access the web server
basic auth.
The users can then request a new "application password" for the mail server for their laptop and
another one for their phone. They can copy-paste the generated passwords to their mail clients which
uses this password on their behalf. Similarly, they can request a new application password to access
the web server basic auth.
# Technical Details
## Client
Currently the LDAP basedn is configurable by an admin, or generated from domain.
For example, example.com <http://example.com/> becomes dc=example,dc=com.
Currently the LDAP basedn is configurable by an admin, or generated from domain. For example,
example.com <http://example.com/> becomes dc=example,dc=com.
Each configured application will define a new naming context, like
app=mail,dc=example,dc=com or app=httpd,dc=example,dc=com
Each configured application will define a new naming context, like app=mail,dc=example,dc=com or
app=httpd,dc=example,dc=com
(NOTE: Should this be app=? Some broken clients could try to validate this rdn
and error, so perhaps it should be a standard rdn value like cn?)
(NOTE: Should this be app=? Some broken clients could try to validate this rdn and error, so perhaps
it should be a standard rdn value like cn?)
The application then uses this app=mail,dc=example,dc=com as their search base
rather than dc=example,dc=com. Within this search base, we show the same content
from dc=example,dc=com.
The application then uses this app=mail,dc=example,dc=com as their search base rather than
dc=example,dc=com. Within this search base, we show the same content from dc=example,dc=com.
(NOTE: We could limit this to application only entries via group membership, but
the issue then is when you have a group for allowing access to the application,
but then still need other groups reflected into the subtree. In this case, if we
limited the view to application access only, we wouldn't be displaying the
non-access groups that the application may still rely on. Ultimately, in this
case the application needs to make it's own authorisation decisions to an
extend. Kanidm can limit which users are members of the access allowed group as
only they can bind still as an extra layer of defence)
(NOTE: We could limit this to application only entries via group membership, but the issue then is
when you have a group for allowing access to the application, but then still need other groups
reflected into the subtree. In this case, if we limited the view to application access only, we
wouldn't be displaying the non-access groups that the application may still rely on. Ultimately, in
this case the application needs to make it's own authorisation decisions to an extend. Kanidm can
limit which users are members of the access allowed group as only they can bind still as an extra
layer of defence)
The application must bind with its api-token if it wishes to read extended user
information. With this, only basic info limited to anonymous rights are granted.
The application must bind with its api-token if it wishes to read extended user information. With
this, only basic info limited to anonymous rights are granted.
(NOTE: We can't assume these DNs are private - I did consider making these
app=<secret key>,dc=example,dc=com, but client applications may disclose this
basedn in ui elements).
app=<secret key>,dc=example,dc=com, but client applications may disclose this basedn in ui
elements).
When a user authenticates the binddn of the account is set to
spn=user,app=name,dc=example,dc=com. This difference in base DN triggers Kanidm
to re-route the authentication to the application specific password, rather than
the UNIX one.
When a user authenticates the binddn of the account is set to spn=user,app=name,dc=example,dc=com.
This difference in base DN triggers Kanidm to re-route the authentication to the application
specific password, rather than the UNIX one.
## Kanidm
### Application Entries
A new class for applications will be added. Each application will have a single
associated group so only members of this group will be able to bind with the
application password for the associated application.
A new class for applications will be added. Each application will have a single associated group so
only members of this group will be able to bind with the application password for the associated
application.
Creating a new application will not create an associated group automatically. It
will be the administrator who will configure the association after creating the
application and optionally a new group. It will be possible to associate
`idm_all_persons` to an application. Removing an application will not delete the
associated group nor its members.
Creating a new application will not create an associated group automatically. It will be the
administrator who will configure the association after creating the application and optionally a new
group. It will be possible to associate `idm_all_persons` to an application. Removing an application
will not delete the associated group nor its members.
When users are removed from a group associated to an application all of their
application passwords for the application will be disabled.
When users are removed from a group associated to an application all of their application passwords
for the application will be disabled.
Application schema class will supplement service account class to allow
generating tokens for them. These are optional since an anonymous bind to kanidm
and searching under the basedn or application base dn will continue to work.
Application schema class will supplement service account class to allow generating tokens for them.
These are optional since an anonymous bind to kanidm and searching under the basedn or application
base dn will continue to work.
Application should have a URL reference to help admins identify where the
application may be located or accessed.
Application should have a URL reference to help admins identify where the application may be located
or accessed.
(NOTE: Future, it could be good to allow customisable instructions for users on
where to go to use their app password?)
(NOTE: Future, it could be good to allow customisable instructions for users on where to go to use
their app password?)
### Accounts
The user may wish to have multiple passwords per application. Each password must
have, at minimum, a label to identify it. For example:
The user may wish to have multiple passwords per application. Each password must have, at minimum, a
label to identify it. For example:
```
MAIL
iphone: abcd...
laptop: bcde...
HTTP
workstation: cdef...
MAIL
iphone: abcd...
laptop: bcde...
HTTP
workstation: cdef...
```
Person accounts will need a new `Attribute::ApplicationPassword` that stores a
`ValueSetApplicationPassword`. Each value in the set is a new type to manage these
secrets and their labeling and the references to the applications.
`ValueSetApplicationPassword`. Each value in the set is a new type to manage these secrets and their
labeling and the references to the applications.
```
struct ApplicationPAssword {
@ -143,70 +134,64 @@ struct ValueSetApplicationPassword {
```
Each value in the set is queried by its UUID. This defines the value as
`Value::ApplicationPassword(Uuid, ApplicationPassword)`. The
`ApplicationPassword` type implements `PartialEq` so two application passwords
are equal if their label is equal and they refer to the same application.
`Value::ApplicationPassword(Uuid, ApplicationPassword)`. The `ApplicationPassword` type implements
`PartialEq` so two application passwords are equal if their label is equal and they refer to the
same application.
The user must be able to delete credentials individually. The generated password
is only displayed once when the user creates it and it is not possible to
recover the clear-text form, only hashed form is stored. It is not allowed to
store duplicated application passwords (same app refer and label).
The user must be able to delete credentials individually. The generated password is only displayed
once when the user creates it and it is not possible to recover the clear-text form, only hashed
form is stored. It is not allowed to store duplicated application passwords (same app refer and
label).
We do not need temporary locks or holds - users can delete and recreate as
needed.
We do not need temporary locks or holds - users can delete and recreate as needed.
### Reference integrity
Since application passwords are related to applications, on delete of an
application all entries that have a bound application password should be removed
from user accounts.
Since application passwords are related to applications, on delete of an application all entries
that have a bound application password should be removed from user accounts.
### Access controls
The "Application administrators" group will manage the applications, and
applications will allow "managed by" so that they can have delegated
administration.
The "Application administrators" group will manage the applications, and applications will allow
"managed by" so that they can have delegated administration.
The "Application user passwords administrators" group will be able to list the
users's application passwords and delete them but only the users will be able
to, additionally to listing and deleting, self-create their own application
passwords.
The "Application user passwords administrators" group will be able to list the users's application
passwords and delete them but only the users will be able to, additionally to listing and deleting,
self-create their own application passwords.
### LDAP
The bind DN regular expression needs to adjusted to detect and determine the
bind dn if it is related to an application or not. The application bind dn
regular expression will capture the user name, and the application name.
The bind DN regular expression needs to adjusted to detect and determine the bind dn if it is
related to an application or not. The application bind dn regular expression will capture the user
name, and the application name.
If the session is related to an application we should only accept application
passwords in the bind. The user needs to be a member of the associated
application group. Binds to an application password must be limited by account
validity and expiration.
If the session is related to an application we should only accept application passwords in the bind.
The user needs to be a member of the associated application group. Binds to an application password
must be limited by account validity and expiration.
We need to add a cache of available applications for lookup.
(NOTE: Caching and reload needs more explanation)
An application can bind with its api-token because the application may need to
search LDAP with elevated read permissions.
An application can bind with its api-token because the application may need to search LDAP with
elevated read permissions.
### kanidm CLI
The `kanidm` command line tool will be extended to satisfy the following
configuration requirements:
The `kanidm` command line tool will be extended to satisfy the following configuration requirements:
* List applications
- List applications
* Create an application
- Create an application
* Delete an application
- Delete an application
* Manage application - group association
- Manage application - group association
* Manage the application api-token
- Manage the application api-token
* List application passwords
- List application passwords
* Create application password
- Create application password
* Delete application password
- Delete application password

View file

@ -9,26 +9,15 @@ You may have noticed that Kanidm requires you to configure TLS in your container
We are a secure-by-design rather than secure-by-configuration system, so TLS for all connections is
considered mandatory and a default rather than an optional feature you add later.
### Why disallow HTTP (without TLS) between my load balancer and Kanidm?
### Can Kanidm work without TLS?
Because Kanidm is one of the keys to a secure network, and insecure connections to them are not best
practice. This can allow account hijacking, privilege escalation, credential disclosures, personal
information leaks and more.
### What are Secure Cookies?
`secure-cookies` is a flag set in cookies that asks a client to transmit them back to the origin
site if and only if the client sees HTTPS is present in the URL.
Certificate authority (CA) verification is _not_ checked - you can use invalid, out of date
certificates, or even certificates where the `subjectAltName` does not match, but the client must
see https:// as the destination else it _will not_ send the cookies.
### How Does That Affect Kanidm?
No, it can not. TLS is required due to our use of `secure-cookies`. `secure-cookies` is a flag set
in cookies that asks a client to transmit them back to the origin site if and only if the client
sees HTTPS is present in the URL.
Kanidm's authentication system is a stepped challenge response design, where you initially request
an "intent" to authenticate. Once you establish this intent, the server sets up a session-id into a
cookie, and informs the client of what authentication methods can proceed.
secure cookie, and informs the client of what authentication methods can proceed.
If you do NOT have a HTTPS URL, the cookie with the session-id is not transmitted. The server
detects this as an invalid-state request in the authentication design, and immediately breaks the
@ -39,6 +28,81 @@ Simply put, we are trying to use settings like `secure_cookies` to add constrain
that you _must_ perform and adhere to best practices - such as having TLS present on your
communication channels.
This is also why we do not allow the server to start without a TLS certificate being configured.
### Why disallow HTTP (without TLS) between my load balancer and Kanidm?
Because Kanidm is one of the keys to a secure network, and insecure connections to them are not best
practice. This can allow account hijacking, privilege escalation, credential disclosures, personal
information leaks and more. The entire path between a client and the server must be protected at all
times.
## OAuth2
[RFC6819 - OAuth2 Threat Model and Security Considerations](https://www.rfc-editor.org/rfc/rfc6819)
is a comprehensive and valuable resource discussing the security of OAuth2 and influences OpenID
Connect as well. In general Kanidm follows and implements many of the recommendations in this
document, as well as choosing not to implement certain known insecure OAuth2 features.
### Why is disabling PKCE considered insecure?
[RFC7636 - Proof Key for Code Exchange by OAuth Public Clients](https://www.rfc-editor.org/rfc/rfc7636)
exists to prevent authorisation code interception attacks. This is where an attacker can retrieve
the authorisation code and then perform the code exchange without the user being aware. A successful
code exchange issues the attacker with an `access_token` and optionally a `refresh_token`. The RFC
has an excellent explanation of the attack. Additionally, this threat is discussed in
[RFC6819 Section 4.4.1](https://www.rfc-editor.org/rfc/rfc6819#section-4.4.1).
As Kanidm aims for "secure by default" design, even with _confidential_ clients, we deem it
important to raise the bar for attackers. For example an attacker may have access to the `client_id`
and `client_secret` of a confidential client as it was mishandled by a system administrator. While
they may not have direct access to the client/application systems, they could still use this
`client_id+secret` to then carry out the authorisation code interception attack listed.
For confidential clients (refered to as a `basic` client in Kanidm due to the use of HTTP Basic for
`client_id+secret` presentation) PKCE may optionally be disabled. This can allow authorisation code
attacks to be carried out - however _if_ TLS is used and the `client_secret` never leaks, then these
attacks will not be possible. Since there are many public references to system administrators
mishandling secrets such as these so we should not rely on this as our sole defence.
For public clients (which have no `client_id` authentication) we strictly enforce PKCE since
disclosure of the authorisation code to an attacker will allow them to perform the code exchange.
OpenID connect internally has a `nonce` parameter in its operations. Commonly it is argued that
this value removes the need for OpenID connect clients to implement PKCE. It does not. This
parameter is not equivalent or a replacement for PKCE. While the `nonce` can assist with certain
attack mitigations, authorisation code interception is not prevented by the presence or validation
of the `nonce` value.
We would strongly encourage OAuth2 client implementations to implement and support PKCE, as it
provides defense in depth to known and exploited authorisation code interception attacks.
### Why is RSA considered legacy
While RSA is cryptographically sound, to achieve the same level as security as ECDSA it requires
signatures and keys that are significantly larger. This has costs for network transmission and CPU
time to verify these signatures. At this time (2024) to achieve the same level of security as a 256
bit ECDSA, RSA requires a 3072 bit key. Similarly a 384 bit ECDSA key requires a 8192 bit RSA for
equivalent cryptographic strength, and a 521 bit ECDSA key would likely require a 16884 bit RSA key
(or greater).
This means that going forward more applications will require ECDSA over RSA due to its increased
strength for significantly faster and smaller key sizes.
Where this has more serious costs is our future desire to add support for Hardware Security Modules.
Since RSA keys are much larger on these devices it may significantly impact performance of the HSM
and may also limit the amount of keys we can store on the device. In the case of some HSM models,
they do not even support RSA keys up to 8192 bits (but they do support ECDSA 384 and 521). An
example of this is TPMs, which only support up to 4096 bit RSA keys at this time.
As a result, we want to guide people toward smaller, faster and more secure cryptographic
standards like ECDSA. We want to encourage application developers to implement ECDSA in their OAuth2
applications as it is likely that limitations of RSA will be hit in the future.
Generally, it's also positive to encourage applications to review and update their cryptographic
implementations over time too. Cryptography and security is not stangnant, it requires continual
review, assessment and improvement.
## Can I change the database backend from SQLite to - name of favourite database here -
No, it is not possible swap out the SQLite database for any other type of SQL server.
@ -58,6 +122,19 @@ store, as each server has it's own cache layer and they are not in contact, it i
writes on one server to never be observed by the second, and if the second were to then write over
those entries it will cause loss of the changes from the first server.
Kanidm now implements it's own eventually consistent distributed replication which also removes the
need for external databases to be considered.
## Why aren't snaps launching with `home_alias` set?
Snaps rely on AppArmor and
[AppArmor doesn't follow symlinks](https://bugs.launchpad.net/apparmor/+bug/1485055). When
`home_alias` is any value other than `none` a symlink will be created and pointing to `home_attr`.
It is recommended to use alternative software packages to snaps.
All users in Kanidm can change their name (and their spn) at any time. If you change `home_attr`
from `uuid` you must have a plan on how to manage these directory renames in your system.
## Why so many crabs?
It's [a rust thing](https://rustacean.net).
@ -72,16 +149,6 @@ discussion!
Don't [ask](https://www.youtube.com/watch?v=0QaAKi0NFkA). They just
[do](https://www.youtube.com/shorts/WizH5ae9ozw).
## Why aren't snaps launching with `home_alias` set?
Snaps rely on AppArmor and
[AppArmor doesn't follow symlinks](https://bugs.launchpad.net/apparmor/+bug/1485055). When
`home_alias` is any value other than `none` a symlink will be created and pointing to `home_attr`.
It is recommended to use alternative software packages to snaps.
All users in Kanidm can change their name (and their spn) at any time. If you change `home_attr`
from `uuid` you must have a plan on how to manage these directory renames in your system.
## Why won't you take this FAQ thing seriously?
Look, people just haven't asked many questions yet.

View file

@ -282,7 +282,8 @@ kanidm system oauth2 enable-localhost-redirects mywebapp
Not all resource servers support modern standards like PKCE or ECDSA. In these situations it may be
necessary to disable these on a per-resource server basis. Disabling these on one resource server
will not affect others.
will not affect others. These settings are explained in detail in
[our FAQ](../frequently_asked_questions.html#oauth2)
<!-- deno-fmt-ignore-start -->