mirror of
https://github.com/kanidm/kanidm.git
synced 2025-05-23 17:33:57 +02:00
docs reordering and cleanup (#2932)
Co-authored-by: Firstyear <william@blackhats.net.au>
This commit is contained in:
parent
21d3f82aa1
commit
2a5e8113e6
book/src
SUMMARY.mdevaluation_quickstart.md
accounts
developers
designs
access_profiles_rework_2022.mdcryptography_key_domains.mdidentity_verification_feature.mdscim_migration_planning.md
release_checklist.mdexamples
installing_client_tools.mdintegrations
preparing_for_your_deployment.mdrepl
server_configuration.mdsupported_features.mdsync
|
@ -36,18 +36,22 @@
|
|||
- [Access Control](access_control/intro.md)
|
||||
|
||||
- [Service Integrations](integrations/readme.md)
|
||||
- [LDAP](integrations/ldap.md)
|
||||
- [OAuth2](integrations/oauth2.md)
|
||||
- [Custom Claims](integrations/oauth2/custom_claims.md)
|
||||
- [Example Configurations](integrations/oauth2/examples.md)
|
||||
- [How does OAuth2 work?](integrations/oauth2/how_does_oauth2_work.md)
|
||||
- [PAM and nsswitch](integrations/pam_and_nsswitch.md)
|
||||
- [SUSE / OpenSUSE](integrations/pam_and_nsswitch/suse.md)
|
||||
- [Fedora](integrations/pam_and_nsswitch/fedora.md)
|
||||
- [Troubleshooting](integrations/pam_and_nsswitch/troubleshooting.md)
|
||||
- [RADIUS](integrations/radius.md)
|
||||
- [SSSD](integrations/sssd.md)
|
||||
- [SSH Key Distribution](integrations/ssh_key_distribution.md)
|
||||
- [OAuth2](integrations/oauth2.md)
|
||||
- [LDAP](integrations/ldap.md)
|
||||
- [RADIUS](integrations/radius.md)
|
||||
|
||||
- [Service Integration Examples](examples/readme.md)
|
||||
- [Kubernetes Ingress](examples/kubernetes_ingress.md)
|
||||
- [OAuth2 Examples](integrations/oauth2/examples.md)
|
||||
- [Traefik](examples/traefik.md)
|
||||
|
||||
- [Replication](repl/readme.md)
|
||||
|
|
|
@ -153,6 +153,8 @@ To reauthenticate
|
|||
kanidm reauth -D william
|
||||
```
|
||||
|
||||
> **NOTE** During reauthentication an account must use the same credential that was used to
|
||||
> [!NOTE]
|
||||
>
|
||||
> During reauthentication an account must use the same credential that was used to
|
||||
> initially authenticate to the session. The reauth flow will not allow any other credentials to be
|
||||
> used!
|
||||
|
|
|
@ -107,7 +107,7 @@ The "admins" role is responsible to manage:
|
|||
|
||||
#### Service Account Admin
|
||||
|
||||
The role would be called "sa\_admins" and would be responsible for top level management of service
|
||||
The role would be called `sa_admins` and would be responsible for top level management of service
|
||||
accounts, and delegating authority for service account administration to managing users.
|
||||
|
||||
- Create service accounts
|
||||
|
|
|
@ -79,7 +79,7 @@ after the JWA algorithms from [RFC7518](https://www.rfc-editor.org/rfc/rfc7518).
|
|||
mapping to OAuth2 concepts and PKCS11 in the future.
|
||||
|
||||
- `ES256` (ECDSA using P-256 and SHA-256, `CKM_ECDSA_SHA256`)
|
||||
- `RS256` (RSASSA-PKCS1-v1\_5 using SHA-256, `CKM_SHA256_RSA_PKCS`)
|
||||
- `RS256` (`RSASSA-PKCS1-v1_5` using `SHA-256`, `CKM_SHA256_RSA_PKCS`)
|
||||
- `HS256` (HMAC using SHA-256, `CKM_SHA256_HMAC`)
|
||||
|
||||
Possible future classes could be
|
||||
|
|
|
@ -12,7 +12,7 @@ state machine, for the idv state machine go [here](#the-identity-verification-st
|
|||
|
||||

|
||||
|
||||
Note that the endpoint path is _/v1/person/:id/\_identify_user_, therefore every request is made up
|
||||
Note that the endpoint path is _`/v1/person/:id/_identify_user`_, therefore every request is made up
|
||||
by the _IdentifyUserRequest_ and an Id. Furthermore to use the api a user needs to be authenticated,
|
||||
so we link their userid to all their idv requests. Since all requests contains this additional
|
||||
information, there is a subset of responses that solely depend on it and therefore can **always** be
|
||||
|
|
|
@ -201,9 +201,9 @@ From this token, retrieve the related synchronisation entry.
|
|||
Assert that the batch updates from and to state identifiers are consistent with the synchronisation
|
||||
entry.
|
||||
|
||||
Retrieve the sync\_parent\_uuid from the sync entry.
|
||||
Retrieve the `sync_parent_uuid` from the sync entry.
|
||||
|
||||
Retrieve the sync\_authority value from the sync entry.
|
||||
Retrieve the `sync_authority` value from the sync entry.
|
||||
|
||||
### Phase 2 - Entry Location, Creation and Authority
|
||||
|
||||
|
@ -213,17 +213,17 @@ such that the subsequent operations are all "modifications" rather than mixed cr
|
|||
|
||||
For each entry in the sync request, if an entry with that uuid exists retrieve it.
|
||||
|
||||
- If an entry exists in the database, assert that its sync\_parent\_uuid is the same as our
|
||||
- If an entry exists in the database, assert that its `sync_parent_uuid` is the same as our
|
||||
agreements.
|
||||
- If there is no sync\_parent\_uuid or the sync\_parent\_uuid does not match, reject the
|
||||
- If there is no `sync_parent_uuid` or the `sync_parent_uuid` does not match, reject the
|
||||
operation.
|
||||
|
||||
- If no entry exists in the database, create a "stub" entry with our sync\_parent\_uuid
|
||||
- If no entry exists in the database, create a "stub" entry with our `sync_parent_uuid`
|
||||
- Create the entry immediately, and then retrieve it.
|
||||
|
||||
### Phase 3 - Entry Assertion
|
||||
|
||||
Remove all attributes in the sync that are overlapped with our sync\_authority value.
|
||||
Remove all attributes in the sync that are overlapped with our `sync_authority` value.
|
||||
|
||||
For all uuids in the entry present set Assert their attributes match what was synced in. Resolve
|
||||
types that need resolving (name2uuid, externalid2uuid)
|
||||
|
@ -232,12 +232,12 @@ Write all
|
|||
|
||||
### Phase 4 - Entry Removal
|
||||
|
||||
For all uuids in the delete\_uuids set: if their sync\_parent\_uuid matches ours, assert they are
|
||||
For all uuids in the `delete_uuids` set: if their `sync_parent_uuid` matches ours, assert they are
|
||||
deleted (recycled).
|
||||
|
||||
### Phase 5 - Commit
|
||||
|
||||
Write the updated "state" from the request to\_state to our current state of the sync
|
||||
Write the updated "state" from the request `to_state` to our current state of the sync
|
||||
|
||||
Write an updated "authority" value to the agreement of what attributes we can change.
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ cargo install wasm-bindgen-cli
|
|||
### Cargo Tasks
|
||||
|
||||
- [ ] Update MSRV if applicable
|
||||
- [ ] RUSTC\_BOOTSTRAP=1 cargo udeps
|
||||
- [ ] `RUSTC_BOOTSTRAP=1 cargo udeps`
|
||||
- [ ] cargo outdated -R
|
||||
- [ ] cargo audit
|
||||
- [ ] cargo test
|
||||
|
|
|
@ -7,8 +7,7 @@ considerations you should be aware of for production deployments.
|
|||
|
||||
## Requirements
|
||||
|
||||
- docker or podman
|
||||
- `x86_64` cpu supporting `x86_64_v2` OR `aarch64` cpu supporting `neon`
|
||||
The only thing you'll need for this is Docker, Podman, or a compatible containerd environment installed and running.
|
||||
|
||||
## Get the software
|
||||
|
||||
|
@ -16,7 +15,15 @@ considerations you should be aware of for production deployments.
|
|||
docker pull docker.io/kanidm/server:latest
|
||||
```
|
||||
|
||||
## Configure the container
|
||||
## Create your configuration
|
||||
|
||||
Create `server.toml`. The important parts are the `domain` and `origin`. For this example, if you use `localhost` and `https://localhost:8443` this will match later commands.
|
||||
|
||||
```toml
|
||||
{{#rustdoc_include ../../examples/server_container.toml}}
|
||||
```
|
||||
|
||||
## Start the container
|
||||
|
||||
```bash
|
||||
docker volume create kanidmd
|
||||
|
@ -27,15 +34,7 @@ docker create --name kanidmd \
|
|||
docker.io/kanidm/kanidm/server:latest
|
||||
```
|
||||
|
||||
## Configure the server
|
||||
|
||||
Create server.toml
|
||||
|
||||
```toml
|
||||
{{#rustdoc_include ../../examples/server_container.toml}}
|
||||
```
|
||||
|
||||
## Add configuration to container
|
||||
## Copy the configuration to the container
|
||||
|
||||
```bash
|
||||
docker cp server.toml kanidmd:/data/server.toml
|
||||
|
@ -73,10 +72,12 @@ docker exec -i -t kanidmd \
|
|||
|
||||
## Setup the client configuration
|
||||
|
||||
This happens on your computer, not in the container.
|
||||
|
||||
```toml
|
||||
# ~/.config/kanidm
|
||||
|
||||
uri = "https://localhost:443"
|
||||
uri = "https://localhost:8443"
|
||||
verify_ca = false
|
||||
```
|
||||
|
||||
|
@ -102,4 +103,10 @@ Then follow the presented steps.
|
|||
|
||||
## What next?
|
||||
|
||||
You can now follow the steps in the [administration section](administration.md)
|
||||
You'll probably want to set it up properly, so that other computers can access it, so [choose a domain name](choosing_a_domain_name.md) and complete the full server installation.
|
||||
|
||||
Alternatively you might like to try configurig one of these:
|
||||
|
||||
- [OAuth2](integrations/oauth2.md) for web services
|
||||
- [PAM and nsswitch](integrations/pam_and_nsswitch.md) for authentication to Linux systems
|
||||
- [Replication](repl/readme.md), if one Kanidm instance isn't enough
|
||||
|
|
|
@ -12,7 +12,9 @@ YAML to update the LetsEncrypt account email for your domain and the FQDN where
|
|||
available. Ensure you adjust this file or Kanidm's configuration to have a matching HTTPS port; the
|
||||
line `traefik.http.services.kanidm.loadbalancer.server.port=8443` sets this on the Traefik side.
|
||||
|
||||
> **NOTE** You will need to generate self-signed certificates for Kanidm, and copy the configuration
|
||||
> [!NOTE]
|
||||
>
|
||||
> You will need to generate self-signed certificates for Kanidm, and copy the configuration
|
||||
> into the `kanidm_data` volume. Some instructions are available in the "Installing the Server"
|
||||
> section of this book.
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Installing Client Tools
|
||||
|
||||
> **NOTE** Running different release versions will likely present incompatibilities. Ensure you're
|
||||
> [!NOTE]
|
||||
>
|
||||
> Running different release versions will likely present incompatibilities. Ensure you're
|
||||
> running matching release versions of client and server binaries. If you have any issues, check
|
||||
> that you are running the latest version of Kanidm.
|
||||
|
||||
|
@ -112,7 +114,9 @@ docker run --rm -i -t \
|
|||
|
||||
If you have a ca.pem you may need to bind mount this in as required as well.
|
||||
|
||||
> **TIP** You can alias the docker run command to make the tools easier to access such as:
|
||||
> [!TIP]
|
||||
>
|
||||
> You can alias the docker run command to make the tools easier to access such as:
|
||||
|
||||
```bash
|
||||
alias kanidm="docker run ..."
|
||||
|
|
|
@ -36,8 +36,8 @@ tree. Kanidm is a flat model, so we have to emulate some tree-like elements, and
|
|||
For this reason, when you search the LDAP interface, Kanidm will make some mapping decisions.
|
||||
|
||||
- The Kanidm domain name is used to generate the DN of the suffix by default.
|
||||
- The domain\_info object becomes the suffix root.
|
||||
- All other entries are direct subordinates of the domain\_info for DN purposes.
|
||||
- The `domain_info` object becomes the suffix root.
|
||||
- All other entries are direct subordinates of the `domain_info` for DN purposes.
|
||||
- Distinguished Names (DNs) are generated from the spn, name, or uuid attribute.
|
||||
- Bind DNs can be remapped and rewritten, and may not even be a DN during bind.
|
||||
|
||||
|
@ -142,7 +142,9 @@ they can be used to gain extended read permissions for those service accounts.
|
|||
Api tokens can also be used to gain extended search permissions with LDAP. To do this you can bind
|
||||
with a dn of `dn=token` and provide the api token in the password.
|
||||
|
||||
> **NOTE** The `dn=token` keyword is guaranteed to not be used by any other entry, which is why it
|
||||
> [!NOTE]
|
||||
>
|
||||
> The `dn=token` keyword is guaranteed to not be used by any other entry, which is why it
|
||||
> was chosen as the keyword to initiate api token binds.
|
||||
|
||||
```bash
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
OAuth is a web authorisation protocol that allows "single sign on". It's key to note OAuth only
|
||||
provides authorisation, as the protocol in its default forms do not provide identity or
|
||||
authentication information. All that OAuth2 provides is information that an entity is authorised for
|
||||
authentication information. All that OAuth can provide is information that an entity is authorised for
|
||||
the requested resources.
|
||||
|
||||
OAuth can tie into extensions allowing an identity provider to reveal information about authorised
|
||||
|
@ -10,129 +10,64 @@ sessions. This extends OAuth from an authorisation only system to a system capab
|
|||
authorisation. Two primary methods of this exist today: RFC7662 token introspection, and OpenID
|
||||
connect.
|
||||
|
||||
## How Does OAuth2 Work?
|
||||
## Resource Server and Clients
|
||||
|
||||
OAuth2 uses a number of terms in surprising ways that makes it often unclear and difficult to
|
||||
understand.
|
||||
|
||||
A user wishes to access a service (resource, resource server) through an OAuth2 client. The client
|
||||
does not have an active session for the user so it redirects to the authorisation server (Kanidm) to
|
||||
determine if the user should be allowed to proceed, and has the appropriate permissions (scopes) for
|
||||
the requested resources.
|
||||
|
||||
The authorisation server checks the current session of the user and may present a login flow if
|
||||
required. Given the identity of the user known to the authorisation sever, and the requested scopes,
|
||||
the authorisation server makes a decision if it allows the authorisation to proceed. The user is
|
||||
then prompted to consent to the authorisation from the authorisation server to the client as some
|
||||
identity information may be revealed by granting this consent.
|
||||
|
||||
If successful and consent is given, the user is redirected back to the client with an authorisation
|
||||
code. The client then contacts the authorisation server directly with this code and exchanges it for
|
||||
a valid OAuth token.
|
||||
|
||||
The client may then optionally contact the token introspection endpoint of the authorisation server
|
||||
about the provided OAuth token, which yields extra metadata about the identity that holds the token
|
||||
from the authorisation. This metadata may include identity information, but also may include
|
||||
extended metadata, sometimes referred to as "claims". Claims are information bound to a token based
|
||||
on properties of the session that may allow the client to make extended authorisation decisions
|
||||
without the need to contact the authorisation server to arbitrate.
|
||||
|
||||
In many cases the client and the resource server are the same entity. When the client and resource
|
||||
server are _separate_ services, the client can then forward the access token to the resource server
|
||||
for authorisation of the user's request.
|
||||
|
||||
It's important to note that OAuth2 at its core is an authorisation system which has layered
|
||||
identity-providing elements on top.
|
||||
|
||||
### Resource Server and Clients
|
||||
|
||||
This is the resource that a user wants to access. Common examples could be Nextcloud, a Wiki, or a
|
||||
This is the resource that a user wants to access. Common [examples](oauth2/examples.md) could be Nextcloud, a Wiki, or a
|
||||
chat service. In these cases the service is both the _client_ and the _resource server_ within the
|
||||
OAuth2 workflow. We will refer to the combination of both client and resource server as a service.
|
||||
|
||||
> NOTE: previous versions of this document incorrectly named clients as resource servers due to
|
||||
> clarity issues in the OAuth2 RFC.
|
||||
|
||||
It's important for you to know _how_ your service will interact with OAuth2. For example, does it
|
||||
support RFC 7662 token introspection or does it rely on OpenID connect for identity information?
|
||||
|
||||
In general Kanidm requires that your service supports:
|
||||
|
||||
- HTTP basic authentication to the authorisation server
|
||||
- PKCE S256 code verification
|
||||
- OIDC only - JWT ES256 for token signatures
|
||||
|
||||
Kanidm issues tokens that are RFC 9068 JWT's allowing service introspection.
|
||||
It's important for you to know _how_ your service will interact with OAuth2. For example, does it rely on OpenID connect for identity information, or does it support RFC7662 token introspection?
|
||||
|
||||
Kanidm will expose its OAuth2 APIs at the following URLs:
|
||||
|
||||
- user auth url: `https://idm.example.com/ui/oauth2`
|
||||
- api auth url: `https://idm.example.com/oauth2/authorise`
|
||||
- token url: `https://idm.example.com/oauth2/token`
|
||||
- User auth: `https://idm.example.com/ui/oauth2`
|
||||
- API auth: `https://idm.example.com/oauth2/authorise`
|
||||
- Token: `https://idm.example.com/oauth2/token`
|
||||
- RFC7662 token introspection URL: `https://idm.example.com/oauth2/token/introspect`
|
||||
- RFC7009 token revoke URL: `https://idm.example.com/oauth2/token/revoke`
|
||||
|
||||
OAuth2 Server Metadata - you need to substitute your OAuth2 `:client_id:` in the following urls:
|
||||
In general Kanidm requires that your service supports:
|
||||
|
||||
- HTTP basic authentication to the authorisation server (Kanidm)
|
||||
- PKCE S256 code verification
|
||||
- If it uses OIDC, JWT ES256 for token signatures
|
||||
|
||||
Kanidm issues tokens that are RFC9068 JWT's allowing service introspection.
|
||||
|
||||
> [!NOTE]
|
||||
>
|
||||
> Previous versions of this document incorrectly named clients as resource servers due to
|
||||
> clarity issues in the OAuth2 RFC.
|
||||
|
||||
### OAuth2 Server Metadata
|
||||
|
||||
You need to substitute your OAuth2 `:client_id:` in the following urls
|
||||
|
||||
- OAuth2 issuer URL: `https://idm.example.com/oauth2/openid/:client_id:/`
|
||||
- OAuth2 RFC8414 discovery:
|
||||
`https://idm.example.com/oauth2/openid/:client_id:/.well-known/oauth-authorization-server`
|
||||
|
||||
OpenID Connect discovery - you need to substitute your OAuth2 `:client_id:` in the following urls:
|
||||
### OpenID Connect Discovery
|
||||
|
||||
You need to substitute your OAuth2 `:client_id:` in the following urls:
|
||||
|
||||
- OpenID connect issuer uri: `https://idm.example.com/oauth2/openid/:client_id:/`
|
||||
- OpenID connect discovery:
|
||||
`https://idm.example.com/oauth2/openid/:client_id:/.well-known/openid-configuration`
|
||||
|
||||
For manual OpenID configuration:
|
||||
### Manual OpenID Configuration
|
||||
|
||||
- OpenID connect userinfo: `https://idm.example.com/oauth2/openid/:client_id:/userinfo`
|
||||
- token signing public key: `https://idm.example.com/oauth2/openid/:client_id:/public_key.jwk`
|
||||
|
||||
### Scope Relationships
|
||||
|
||||
For an authorisation to proceed, the client will request a list of scopes, which are unique to that
|
||||
service. For example, when a user wishes to login to the admin panel of the resource server, it may
|
||||
request the "admin" scope from Kanidm for authorisation. But when a user wants to login, it may only
|
||||
request "access" as a scope from Kanidm.
|
||||
|
||||
As each service may have its own scopes and understanding of these, Kanidm isolates scopes to each
|
||||
service connected to Kanidm. Kanidm has two methods of granting scopes to accounts (users).
|
||||
|
||||
The first is scope mappings. These provide a set of scopes if a user is a member of a specific group
|
||||
within Kanidm. This allows you to create a relationship between the scopes of a service, and the
|
||||
groups/roles in Kanidm which can be specific to that service.
|
||||
|
||||
For an authorisation to proceed, all scopes requested by the client must be available in the final
|
||||
scope set that is granted to the account.
|
||||
|
||||
The second is supplemental scope mappings. These function the same as scope maps where membership of
|
||||
a group provides a set of scopes to the account. However these scopes are NOT consulted during
|
||||
authorisation decisions made by Kanidm. These scopes exists to allow optional properties to be
|
||||
provided (such as personal information about a subset of accounts to be revealed) or so that the
|
||||
service may make its own authorisation decisions based on the provided scopes.
|
||||
|
||||
This use of scopes is the primary means to control who can access what resources. These access
|
||||
decisions can take place either on Kanidm or the service.
|
||||
|
||||
For example, if you have a client that always requests a scope of "read", then users with scope maps
|
||||
that supply the read scope will be allowed by Kanidm to proceed to the service. Kanidm can then
|
||||
provide the supplementary scopes into provided tokens, so that the service can use these to choose
|
||||
if it wishes to display UI elements. If a user has a supplemental "admin" scope, then that user may
|
||||
be able to access an administration panel of the service. In this way Kanidm is still providing the
|
||||
authorisation information, but the control is then exercised by the service.
|
||||
|
||||
## Configuration
|
||||
|
||||
### Create the Kanidm Configuration
|
||||
|
||||
After you have understood your service requirements you first need to configure Kanidm. By default
|
||||
members of `system_admins` or `idm_hp_oauth2_manage_priv` are able to create or manage OAuth2 client
|
||||
integrations.
|
||||
By default, members of the `system_admins` or `idm_hp_oauth2_manage_priv` groups are able to create or manage OAuth2 client integrations.
|
||||
|
||||
You can create a new client by specifying its client name, application display name and the landing
|
||||
page (home page) of the client. The landing page is where users will be redirected to in order to
|
||||
begin an OAuth2 flow from the application portal.
|
||||
page (home page) of the client. The landing page is where users will be redirected to from the Kanidm application portal.
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 create <name> <displayname> <landing page url>
|
||||
|
@ -153,13 +88,6 @@ kanidm system oauth2 update-scope-map <name> <kanidm_group_name> [scopes]...
|
|||
kanidm system oauth2 update-scope-map nextcloud nextcloud_admins admin
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> If you are creating an OpenID Connect (OIDC) client you **MUST** provide a scope map
|
||||
> named `openid`. Without this, OpenID Connect clients **WILL NOT WORK**!
|
||||
|
||||
Also...
|
||||
|
||||
> [!TIP]
|
||||
>
|
||||
> OpenID connect allows a number of scopes that affect the content of the resulting
|
||||
|
@ -167,11 +95,18 @@ Also...
|
|||
> associated claims may be added to the authorisation token. It is not guaranteed that all of the
|
||||
> associated claims will be added.
|
||||
>
|
||||
> - profile - (name, family\_name, given\_name, middle\_name, nickname, preferred\_username,
|
||||
> profile, picture, website, gender, birthdate, zoneinfo, locale, and updated\_at)
|
||||
> - email - (email, email\_verified)
|
||||
> - address - (address)
|
||||
> - phone - (phone\_number, phone\_number\_verified)
|
||||
> - **profile** - name, family_name, given_name, middle_name, nickname, preferred_username,
|
||||
> profile, picture, website, gender, birthdate, zoneinfo, locale, and updated_at
|
||||
> - **email** - email, email_verified
|
||||
> - **address** - address
|
||||
> - **phone** - phone_number, phone_number_verified
|
||||
|
||||
<!-- this is just to split the templates up -->
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> If you are creating an OpenID Connect (OIDC) client you **MUST** provide a scope map
|
||||
> named `openid`. Without this, OpenID Connect clients **WILL NOT WORK**!
|
||||
|
||||
You can create a supplemental scope map with:
|
||||
|
||||
|
@ -195,7 +130,7 @@ oauth2_rs_origin_landing: https://nextcloud.example.com
|
|||
oauth2_rs_token_key: hidden
|
||||
```
|
||||
|
||||
You can see "oauth2\_rs\_basic\_secret" with:
|
||||
You can see the value of `oauth2_rs_basic_secret` with:
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 show-basic-secret nextcloud
|
||||
|
@ -211,61 +146,37 @@ challenge/verification method is set to S256.
|
|||
|
||||
You should now be able to test authorisation to the client.
|
||||
|
||||
## Resetting Client Security Material
|
||||
## Scope Relationships
|
||||
|
||||
In the case of disclosure of the basic secret or some other security event where you may wish to
|
||||
invalidate a services active sessions/tokens. You can reset the secret material of the server with:
|
||||
For an authorisation to proceed, the client will request a list of scopes. For example, when a user wishes to login to the admin panel of the resource server, it may
|
||||
request the "admin" scope from Kanidm for authorisation. But when a user wants to login, it may only
|
||||
request "access" as a scope from Kanidm.
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 reset-secrets
|
||||
```
|
||||
As each service may have its own scopes and understanding of these, Kanidm isolates scopes to each
|
||||
service connected to Kanidm. Kanidm has two methods of granting scopes to accounts (users).
|
||||
|
||||
Each client has unique signing keys and access secrets, so this is limited to each service.
|
||||
The first is scope mappings. These provide a set of scopes if a user is a member of a specific group
|
||||
within Kanidm. This allows you to create a relationship between the scopes of a service, and the
|
||||
groups/roles in Kanidm which can be specific to that service.
|
||||
|
||||
## Custom Claim Maps
|
||||
For an authorisation to proceed, all scopes requested by the client must be available in the final
|
||||
scope set that is granted to the account.
|
||||
|
||||
Some OAuth services may consume custom claims from an id token for access control or other policy
|
||||
decisions. Each custom claim is a key:values set, where there can be many values associated to a
|
||||
claim name. Different applications may expect these values to be formatted (joined) in different
|
||||
ways.
|
||||
The second part is supplemental scope mappings. These function the same as scope maps where membership of
|
||||
a group provides a set of scopes to the account. However these scopes are NOT consulted during
|
||||
authorisation decisions made by Kanidm. These scopes exist to allow optional properties to be
|
||||
provided (such as personal information about a subset of accounts to be revealed) or so that the
|
||||
service may make its own authorisation decisions based on the provided scopes.
|
||||
|
||||
Claim values are mapped based on membership to groups. When an account is a member of multiple
|
||||
groups that would receive the same claim, the values of these maps are merged.
|
||||
This use of scopes is the primary means to control who can access what resources. These access
|
||||
decisions can take place either on Kanidm or the service.
|
||||
|
||||
To create or update a claim map on a client:
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 update-claim-map <name> <claim_name> <kanidm_group_name> [values]...
|
||||
kanidm system oauth2 update-claim-map nextcloud account_role nextcloud_admins admin login ...
|
||||
```
|
||||
|
||||
To change the join strategy for a claim name. Valid strategies are csv (comma separated value), ssv
|
||||
(space separated value) and array (a native json array). The default strategy is array.
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 update-claim-map-join <name> <claim_name> [csv|ssv|array]
|
||||
kanidm system oauth2 update-claim-map-join nextcloud account_role csv
|
||||
```
|
||||
|
||||
Example claim formats:
|
||||
|
||||
```text
|
||||
# csv
|
||||
claim: "value_a,value_b"
|
||||
|
||||
# ssv
|
||||
claim: "value_a value_b"
|
||||
|
||||
# array
|
||||
claim: ["value_a", "value_b"]
|
||||
```
|
||||
|
||||
To delete a group from a claim map
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 delete-claim-map <name> <claim_name> <kanidm_group_name>
|
||||
kanidm system oauth2 delete-claim-map nextcloud account_role nextcloud_admins
|
||||
```
|
||||
For example, if you have a client that always requests a scope of "read", then users with scope maps
|
||||
that supply the read scope will be allowed by Kanidm to proceed to the service. Kanidm can then
|
||||
provide the supplementary scopes into provided tokens, so that the service can use these to choose
|
||||
if it wishes to display UI elements. If a user has a supplemental "admin" scope, then that user may
|
||||
be able to access an administration panel of the service. In this way Kanidm is still providing the
|
||||
authorisation information, but the control is then exercised by the service.
|
||||
|
||||
## Public Client Configuration
|
||||
|
||||
|
@ -297,11 +208,13 @@ kanidm system oauth2 enable-localhost-redirects mywebapp
|
|||
|
||||
## Alternate Redirect URLs
|
||||
|
||||
{{#template ../templates/kani-warning.md imagepath=../images title=WARNING text=SECURITY RISK }}
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> Security Risk!
|
||||
>
|
||||
> You **MUST NOT** share a single OAuth2 client definition between multiple applications.
|
||||
>
|
||||
> The ability to configure multiple redirect URLs is **NOT** to allow you to share a single Kanidm
|
||||
> The ability to configure multiple redirect URLs is **NOT** intended to allow you to share a single Kanidm
|
||||
> client definition between multiple OAuth2 clients.
|
||||
>
|
||||
> Sharing OAuth2 client configurations between applications **FUNDAMENTALLY BREAKS** the OAuth2
|
||||
|
@ -317,10 +230,6 @@ exchange, the system can redirect to the native application.
|
|||
|
||||
To support this Kanidm allows supplemental opaque origins to be configured on clients.
|
||||
|
||||
> [!WARNING]
|
||||
>
|
||||
> The ability to configure multiple origins is NOT intended to allow you to share a single Kanidm client definition between multiple OAuth2 clients. This fundamentally breaks the OAuth2 security model and is NOT SUPPORTED as a configuration. Multiple origins is only to allow supplemental redirects within the _same_ client application.
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 add-redirect-url <name> <url>
|
||||
kanidm system oauth2 remove-redirect-url <name> <url>
|
||||
|
@ -332,7 +241,7 @@ Supplemental URLs are shown in the OAuth2 client configuration in the `oauth2_rs
|
|||
|
||||
### Strict Redirect URLs
|
||||
|
||||
Kanidm previously enforce that redirection targets only matched by _origin_, not the full URL. In
|
||||
Kanidm previously enforced that redirection targets only matched by _origin_, not the full URL. In
|
||||
1.4.0 these URLs will enforce a full URL match instead.
|
||||
|
||||
To indicate your readiness for this transition, all OAuth2 clients must have the field
|
||||
|
@ -349,19 +258,6 @@ kanidm system oauth2 enable-strict-redirect-url <name>
|
|||
kanidm system oauth2 disable-strict-redirect-url <name>
|
||||
```
|
||||
|
||||
### Why Does Sharing a Client Weaken OAuth2?
|
||||
|
||||
By sharing a client ID between multiple applications this implies that all of these applications are
|
||||
a singular client in Kanidm's view. This means tokens issued to one application can be reused on any
|
||||
other application.
|
||||
|
||||
This limits your ability to enforce scopes, presents a large compromise blast radius if a token is
|
||||
stolen, and also increases the damage radius if the client credentials are stolen.
|
||||
|
||||
Generally this also provides a bad user experience since the Kanidm application portal only lists a
|
||||
single landing URL of the client, so subsequent applications that "piggy back" can not be redirected
|
||||
to from the application portal meaning that users will not easily be able to access the application.
|
||||
|
||||
## Extended Options for Legacy Clients
|
||||
|
||||
Not all clients support modern standards like PKCE or ECDSA. In these situations it may be necessary
|
||||
|
@ -385,241 +281,13 @@ To enable legacy cryptography (RSA PKCS1-5 SHA256):
|
|||
kanidm system oauth2 warning-enable-legacy-crypto <client name>
|
||||
```
|
||||
|
||||
## Example Integrations
|
||||
## Resetting Client Security Material
|
||||
|
||||
### Apache mod\_auth\_openidc
|
||||
|
||||
Add the following to a `mod_auth_openidc.conf`. It should be included in a `mods_enabled` folder or
|
||||
with an appropriate include.
|
||||
|
||||
```conf
|
||||
# NB: may be just path, reduces copy-paste
|
||||
OIDCRedirectURI /oauth2/callback
|
||||
OIDCCryptoPassphrase <random password here>
|
||||
OIDCProviderMetadataURL https://kanidm.example.com/oauth2/openid/<client name>/.well-known/openid-configuration
|
||||
OIDCScope "openid"
|
||||
OIDCUserInfoTokenMethod authz_header
|
||||
OIDCClientID <client name>
|
||||
OIDCClientSecret <client password>
|
||||
OIDCPKCEMethod S256
|
||||
OIDCCookieSameSite On
|
||||
# Set the `REMOTE_USER` field to the `preferred_username` instead of the UUID.
|
||||
# Remember that the username can change, but this can help with systems like Nagios which use this as a display name.
|
||||
# OIDCRemoteUserClaim preferred_username
|
||||
```
|
||||
|
||||
Other scopes can be added as required to the `OIDCScope` line, eg:
|
||||
`OIDCScope "openid scope2 scope3"`
|
||||
|
||||
In the virtual host, to handle OIDC redirect, a special location _must_ be defined:
|
||||
|
||||
```apache
|
||||
# NB: you must allocate this virtual location matching OIDCRedirectURI and allow it for _any valid user_
|
||||
<Location /oauth2/callback>
|
||||
AuthType openid-connect
|
||||
Require valid-user
|
||||
</Location>
|
||||
```
|
||||
|
||||
In the virtual host, to protect a location/directory
|
||||
[see wiki](https://github.com/OpenIDC/mod_auth_openidc/wiki/Authorization):
|
||||
|
||||
```apache
|
||||
<Directory /foo>
|
||||
AuthType openid-connect
|
||||
|
||||
# you can authorize by the groups if you requested OIDCScope "openid groups"
|
||||
# Require claim groups:<spn | uuid>
|
||||
Require claim groups:apache_access_allowed@example.com
|
||||
|
||||
# or authorize by exact preferred_username
|
||||
# Require user john.doe
|
||||
</Directory>
|
||||
```
|
||||
|
||||
### Miniflux
|
||||
|
||||
Miniflux is a feedreader that supports OAuth 2.0 and OpenID connect. It automatically appends the
|
||||
`.well-known` parts to the discovery endpoint. The application name in the redirect URL needs to
|
||||
match the `OAUTH2_PROVIDER` name.
|
||||
|
||||
```conf
|
||||
OAUTH2_PROVIDER = "oidc";
|
||||
OAUTH2_CLIENT_ID = "miniflux";
|
||||
OAUTH2_CLIENT_SECRET = "<oauth2_rs_basic_secret>";
|
||||
OAUTH2_REDIRECT_URL = "https://feeds.example.com/oauth2/oidc/callback";
|
||||
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://idm.example.com/oauth2/openid/<oauth2_rs_name>";
|
||||
```
|
||||
|
||||
### Nextcloud
|
||||
|
||||
Install the module [from the nextcloud market place](https://apps.nextcloud.com/apps/user_oidc) - it
|
||||
can also be found in the Apps section of your deployment as "OpenID Connect user backend".
|
||||
|
||||
In Nextcloud's config.php you need to allow connection to remote servers and enable PKCE:
|
||||
|
||||
```php
|
||||
'allow_local_remote_servers' => true,
|
||||
|
||||
'user_oidc' => [
|
||||
'use_pkce' => true,
|
||||
],
|
||||
```
|
||||
|
||||
You may optionally choose to add:
|
||||
|
||||
```php
|
||||
'allow_user_to_change_display_name' => false,
|
||||
'lost_password_link' => 'disabled',
|
||||
```
|
||||
|
||||
If you forget this, you may see the following error in logs:
|
||||
In the case of disclosure of the basic secret or some other security event where you may wish to
|
||||
invalidate a services active sessions/tokens. You can reset the secret material of the server with:
|
||||
|
||||
```bash
|
||||
Host 172.24.11.129 was not connected to because it violates local access rules
|
||||
kanidm system oauth2 reset-secrets
|
||||
```
|
||||
|
||||
In the settings menu, configure the discovery URL and client ID and secret.
|
||||
|
||||
You can choose to disable other login methods with:
|
||||
|
||||
```bash
|
||||
php occ config:app:set --value=0 user_oidc allow_multiple_user_backends
|
||||
```
|
||||
|
||||
You can login directly by appending `?direct=1` to your login page. You can re-enable other backends
|
||||
by setting the value to `1`
|
||||
|
||||
### Velociraptor
|
||||
|
||||
Velociraptor supports OIDC. To configure it select "Authenticate with SSO" then "OIDC" during the
|
||||
interactive configuration generator. Alternately, you can set the following keys in
|
||||
server.config.yaml:
|
||||
|
||||
```yaml
|
||||
GUI:
|
||||
authenticator:
|
||||
type: OIDC
|
||||
oidc_issuer: https://idm.example.com/oauth2/openid/:client\_id:/
|
||||
oauth_client_id: <client name/>
|
||||
oauth_client_secret: <client secret>
|
||||
```
|
||||
|
||||
Velociraptor does not support PKCE. You will need to run the following:
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 warning-insecure-client-disable-pkce <client name>
|
||||
```
|
||||
|
||||
Initial users are mapped via their email in the Velociraptor server.config.yaml config:
|
||||
|
||||
```yaml
|
||||
GUI:
|
||||
initial_users:
|
||||
- name: <email address>
|
||||
```
|
||||
|
||||
Accounts require the `openid` and `email` scopes to be authenticated. It is recommended you limit
|
||||
these to a group with a scope map due to Velociraptors high impact.
|
||||
|
||||
```bash
|
||||
# kanidm group create velociraptor_users
|
||||
# kanidm group add_members velociraptor_users ...
|
||||
kanidm system oauth2 create_scope_map <client name> velociraptor_users openid email
|
||||
```
|
||||
|
||||
### Grafana
|
||||
|
||||
Grafana is a open source analytics and interactive visualization web application. It provides
|
||||
charts, graphs and alerts when connected to supported data source.
|
||||
|
||||
Prepare the environment:
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 create grafana "grafana.domain.name" https://grafana.domain.name
|
||||
kanidm system oauth2 update-scope-map grafana grafana_users email openid profile groups
|
||||
kanidm system oauth2 enable-pkce grafana
|
||||
kanidm system oauth2 get grafana
|
||||
kanidm system oauth2 show-basic-secret grafana
|
||||
<SECRET>
|
||||
```
|
||||
|
||||
Create Grafana user groups:
|
||||
|
||||
```bash
|
||||
kanidm group create 'grafana_superadmins'
|
||||
kanidm group create 'grafana_admins'
|
||||
kanidm group create 'grafana_editors'
|
||||
kanidm group create 'grafana_users'
|
||||
```
|
||||
|
||||
Setup the claim-map that will set what role each group will map to in Grafana:
|
||||
|
||||
```bash
|
||||
kanidmm oauth2 update-claim-map-join 'grafana' 'grafana_role' array
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_superadmins' 'GrafanaAdmin'
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_admins' 'Admin'
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_editors' 'Editor'
|
||||
```
|
||||
|
||||
Don't forget that every Grafana user needs be member of one of above group and have name and e-mail:
|
||||
|
||||
```bash
|
||||
kanidm person update <user> --legalname "Personal Name" --mail "user@example.com"
|
||||
kanidm group add-members 'grafana_users' 'my_user_group_or_user_name'
|
||||
```
|
||||
|
||||
And add the following to your Grafana config:
|
||||
|
||||
```ini
|
||||
[auth.generic_oauth]
|
||||
enabled = true
|
||||
name = Kanidm
|
||||
client_id = grafana
|
||||
client_secret = <SECRET>
|
||||
scopes = openid,profile,email,groups
|
||||
auth_url = https://idm.example.com/ui/oauth2
|
||||
token_url = https://idm.example.com/oauth2/token
|
||||
api_url = https://idm.example.com/oauth2/openid/grafana/userinfo
|
||||
use_pkce = true
|
||||
use_refresh_token = true
|
||||
allow_sign_up = true
|
||||
login_attribute_path = preferred_username
|
||||
groups_attribute_path = groups
|
||||
role_attribute_path = contains(grafana_role[*], 'GrafanaAdmin') && 'GrafanaAdmin' || contains(grafana_role[*], 'Admin') && 'Admin' || contains(grafana_role[*], 'Editor') && 'Editor' || 'Viewer'
|
||||
allow_assign_grafana_admin = true
|
||||
```
|
||||
|
||||
### Vouch Proxy
|
||||
|
||||
> **WARNING** Vouch proxy requires a unique identifier but does not use the proper scope, "sub". It
|
||||
> uses the fields "username" or "email" as primary identifiers instead. As a result, this can cause
|
||||
> user or deployment issues, at worst security bypasses. You should avoid Vouch Proxy if possible
|
||||
> due to these issues.
|
||||
>
|
||||
> - <https://github.com/vouch/vouch-proxy/issues/309>
|
||||
> - <https://github.com/vouch/vouch-proxy/issues/310>
|
||||
|
||||
Note: **You need to run at least the version 0.37.0**
|
||||
|
||||
Vouch Proxy supports multiple OAuth and OIDC login providers. To configure it you need to pass:
|
||||
|
||||
```yaml
|
||||
oauth:
|
||||
auth_url: https://idm.wherekanidmruns.com/ui/oauth2
|
||||
callback_url: https://login.wherevouchproxyruns.com/auth
|
||||
client_id: <oauth2_rs_name> # Found in kanidm system oauth2 get XXXX (should be the same as XXXX)
|
||||
client_secret: <oauth2_rs_basic_secret> # Found in kanidm system oauth2 get XXXX
|
||||
code_challenge_method: S256
|
||||
provider: oidc
|
||||
scopes:
|
||||
- email # Required due to vouch proxy reliance on mail as a primary identifier
|
||||
token_url: https://idm.wherekanidmruns.com/oauth2/token
|
||||
user_info_url: https://idm.wherekanidmruns.com/oauth2/openid/<oauth2_rs_name>/userinfo
|
||||
```
|
||||
|
||||
The `email` scope needs to be passed and thus the mail attribute needs to exist on the account:
|
||||
|
||||
```bash
|
||||
kanidm person update <ID> --mail "YYYY@somedomain.com" --name idm_admin
|
||||
```
|
||||
Each client has unique signing keys and access secrets, so this is limited to each service.
|
||||
|
|
44
book/src/integrations/oauth2/custom_claims.md
Normal file
44
book/src/integrations/oauth2/custom_claims.md
Normal file
|
@ -0,0 +1,44 @@
|
|||
# Custom Claim Maps
|
||||
|
||||
Some OAuth2 services may consume custom claims from an id token for access control or other policy
|
||||
decisions. Each custom claim is a key:values set, where there can be many values associated to a
|
||||
claim name. Different applications may expect these values to be formatted (joined) in different
|
||||
ways.
|
||||
|
||||
Claim values are mapped based on membership to groups. When an account is a member of multiple
|
||||
groups that would receive the same claim, the values of these maps are merged.
|
||||
|
||||
To create or update a claim map on a client:
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 update-claim-map <name> <claim_name> <kanidm_group_name> [values]...
|
||||
kanidm system oauth2 update-claim-map nextcloud account_role nextcloud_admins admin login ...
|
||||
```
|
||||
|
||||
To change the join strategy for a claim name. Valid strategies are csv (comma separated value), ssv
|
||||
(space separated value) and array (a native json array). The default strategy is array.
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 update-claim-map-join <name> <claim_name> [csv|ssv|array]
|
||||
kanidm system oauth2 update-claim-map-join nextcloud account_role csv
|
||||
```
|
||||
|
||||
Example claim formats:
|
||||
|
||||
```text
|
||||
# csv
|
||||
claim: "value_a,value_b"
|
||||
|
||||
# ssv
|
||||
claim: "value_a value_b"
|
||||
|
||||
# array
|
||||
claim: ["value_a", "value_b"]
|
||||
```
|
||||
|
||||
To delete a group from a claim map
|
||||
|
||||
```shell
|
||||
kanidm system oauth2 delete-claim-map <name> <claim_name> <kanidm_group_name>
|
||||
kanidm system oauth2 delete-claim-map nextcloud account_role nextcloud_admins
|
||||
```
|
238
book/src/integrations/oauth2/examples.md
Normal file
238
book/src/integrations/oauth2/examples.md
Normal file
|
@ -0,0 +1,238 @@
|
|||
# Example OAuth2 Configurations
|
||||
|
||||
## Apache `mod_auth_openidc`
|
||||
|
||||
Add the following to a `mod_auth_openidc.conf`. It should be included in a `mods_enabled` folder or
|
||||
with an appropriate include.
|
||||
|
||||
```conf
|
||||
# NB: may be just path, reduces copy-paste
|
||||
OIDCRedirectURI /oauth2/callback
|
||||
OIDCCryptoPassphrase <random password here>
|
||||
OIDCProviderMetadataURL https://kanidm.example.com/oauth2/openid/<client name>/.well-known/openid-configuration
|
||||
OIDCScope "openid"
|
||||
OIDCUserInfoTokenMethod authz_header
|
||||
OIDCClientID <client name>
|
||||
OIDCClientSecret <client password>
|
||||
OIDCPKCEMethod S256
|
||||
OIDCCookieSameSite On
|
||||
# Set the `REMOTE_USER` field to the `preferred_username` instead of the UUID.
|
||||
# Remember that the username can change, but this can help with systems like Nagios which use this as a display name.
|
||||
# OIDCRemoteUserClaim preferred_username
|
||||
```
|
||||
|
||||
Other scopes can be added as required to the `OIDCScope` line, eg:
|
||||
`OIDCScope "openid scope2 scope3"`
|
||||
|
||||
In the virtual host, to handle OIDC redirect, a special location _must_ be defined:
|
||||
|
||||
```apache
|
||||
# NB: you must allocate this virtual location matching OIDCRedirectURI and allow it for _any valid user_
|
||||
<Location /oauth2/callback>
|
||||
AuthType openid-connect
|
||||
Require valid-user
|
||||
</Location>
|
||||
```
|
||||
|
||||
In the virtual host, to protect a location/directory
|
||||
[see wiki](https://github.com/OpenIDC/mod_auth_openidc/wiki/Authorization):
|
||||
|
||||
```apache
|
||||
<Directory /foo>
|
||||
AuthType openid-connect
|
||||
|
||||
# you can authorize by the groups if you requested OIDCScope "openid groups"
|
||||
# Require claim groups:<spn | uuid>
|
||||
Require claim groups:apache_access_allowed@example.com
|
||||
|
||||
# or authorize by exact preferred_username
|
||||
# Require user john.doe
|
||||
</Directory>
|
||||
```
|
||||
|
||||
## Miniflux
|
||||
|
||||
Miniflux is a feedreader that supports OAuth 2.0 and OpenID connect. It automatically appends the
|
||||
`.well-known` parts to the discovery endpoint. The application name in the redirect URL needs to
|
||||
match the `OAUTH2_PROVIDER` name.
|
||||
|
||||
```conf
|
||||
OAUTH2_PROVIDER = "oidc";
|
||||
OAUTH2_CLIENT_ID = "miniflux";
|
||||
OAUTH2_CLIENT_SECRET = "<oauth2_rs_basic_secret>";
|
||||
OAUTH2_REDIRECT_URL = "https://feeds.example.com/oauth2/oidc/callback";
|
||||
OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://idm.example.com/oauth2/openid/<oauth2_rs_name>";
|
||||
```
|
||||
|
||||
## Nextcloud
|
||||
|
||||
Install the module [from the nextcloud market place](https://apps.nextcloud.com/apps/user_oidc) - it
|
||||
can also be found in the Apps section of your deployment as "OpenID Connect user backend".
|
||||
|
||||
In Nextcloud's config.php you need to allow connection to remote servers and enable PKCE:
|
||||
|
||||
```php
|
||||
'allow_local_remote_servers' => true,
|
||||
|
||||
'user_oidc' => [
|
||||
'use_pkce' => true,
|
||||
],
|
||||
```
|
||||
|
||||
You may optionally choose to add:
|
||||
|
||||
```php
|
||||
'allow_user_to_change_display_name' => false,
|
||||
'lost_password_link' => 'disabled',
|
||||
```
|
||||
|
||||
If you forget this, you may see the following error in logs:
|
||||
|
||||
```bash
|
||||
Host 172.24.11.129 was not connected to because it violates local access rules
|
||||
```
|
||||
|
||||
In the settings menu, configure the discovery URL and client ID and secret.
|
||||
|
||||
You can choose to disable other login methods with:
|
||||
|
||||
```bash
|
||||
php occ config:app:set --value=0 user_oidc allow_multiple_user_backends
|
||||
```
|
||||
|
||||
You can login directly by appending `?direct=1` to your login page. You can re-enable other backends
|
||||
by setting the value to `1`
|
||||
|
||||
## Velociraptor
|
||||
|
||||
Velociraptor supports OIDC. To configure it select "Authenticate with SSO" then "OIDC" during the
|
||||
interactive configuration generator. Alternately, you can set the following keys in
|
||||
server.config.yaml:
|
||||
|
||||
```yaml
|
||||
GUI:
|
||||
authenticator:
|
||||
type: OIDC
|
||||
oidc_issuer: https://idm.example.com/oauth2/openid/:client_id:/
|
||||
oauth_client_id: <client name/>
|
||||
oauth_client_secret: <client secret>
|
||||
```
|
||||
|
||||
Velociraptor does not support PKCE. You will need to run the following:
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 warning-insecure-client-disable-pkce <client name>
|
||||
```
|
||||
|
||||
Initial users are mapped via their email in the Velociraptor server.config.yaml config:
|
||||
|
||||
```yaml
|
||||
GUI:
|
||||
initial_users:
|
||||
- name: <email address>
|
||||
```
|
||||
|
||||
Accounts require the `openid` and `email` scopes to be authenticated. It is recommended you limit
|
||||
these to a group with a scope map due to Velociraptors high impact.
|
||||
|
||||
```bash
|
||||
# kanidm group create velociraptor_users
|
||||
# kanidm group add_members velociraptor_users ...
|
||||
kanidm system oauth2 create_scope_map <client name> velociraptor_users openid email
|
||||
```
|
||||
|
||||
## Grafana
|
||||
|
||||
Grafana is a open source analytics and interactive visualization web application. It provides
|
||||
charts, graphs and alerts when connected to supported data source.
|
||||
|
||||
Prepare the environment:
|
||||
|
||||
```bash
|
||||
kanidm system oauth2 create grafana "grafana.domain.name" https://grafana.domain.name
|
||||
kanidm system oauth2 update-scope-map grafana grafana_users email openid profile groups
|
||||
kanidm system oauth2 enable-pkce grafana
|
||||
kanidm system oauth2 get grafana
|
||||
kanidm system oauth2 show-basic-secret grafana
|
||||
<SECRET>
|
||||
```
|
||||
|
||||
Create Grafana user groups:
|
||||
|
||||
```bash
|
||||
kanidm group create 'grafana_superadmins'
|
||||
kanidm group create 'grafana_admins'
|
||||
kanidm group create 'grafana_editors'
|
||||
kanidm group create 'grafana_users'
|
||||
```
|
||||
|
||||
Setup the claim-map that will set what role each group will map to in Grafana:
|
||||
|
||||
```bash
|
||||
kanidmm oauth2 update-claim-map-join 'grafana' 'grafana_role' array
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_superadmins' 'GrafanaAdmin'
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_admins' 'Admin'
|
||||
kanidm system oauth2 update-claim-map 'grafana' 'grafana_role' 'grafana_editors' 'Editor'
|
||||
```
|
||||
|
||||
Don't forget that every Grafana user needs be member of one of above group and have name and e-mail:
|
||||
|
||||
```bash
|
||||
kanidm person update <user> --legalname "Personal Name" --mail "user@example.com"
|
||||
kanidm group add-members 'grafana_users' 'my_user_group_or_user_name'
|
||||
```
|
||||
|
||||
And add the following to your Grafana config:
|
||||
|
||||
```ini
|
||||
[auth.generic_oauth]
|
||||
enabled = true
|
||||
name = Kanidm
|
||||
client_id = grafana
|
||||
client_secret = <SECRET>
|
||||
scopes = openid,profile,email,groups
|
||||
auth_url = https://idm.example.com/ui/oauth2
|
||||
token_url = https://idm.example.com/oauth2/token
|
||||
api_url = https://idm.example.com/oauth2/openid/grafana/userinfo
|
||||
use_pkce = true
|
||||
use_refresh_token = true
|
||||
allow_sign_up = true
|
||||
login_attribute_path = preferred_username
|
||||
groups_attribute_path = groups
|
||||
role_attribute_path = contains(grafana_role[*], 'GrafanaAdmin') && 'GrafanaAdmin' || contains(grafana_role[*], 'Admin') && 'Admin' || contains(grafana_role[*], 'Editor') && 'Editor' || 'Viewer'
|
||||
allow_assign_grafana_admin = true
|
||||
```
|
||||
|
||||
## Vouch Proxy
|
||||
|
||||
> **WARNING** Vouch proxy requires a unique identifier but does not use the proper scope, "sub". It
|
||||
> uses the fields "username" or "email" as primary identifiers instead. As a result, this can cause
|
||||
> user or deployment issues, at worst security bypasses. You should avoid Vouch Proxy if possible
|
||||
> due to these issues.
|
||||
>
|
||||
> - <https://github.com/vouch/vouch-proxy/issues/309>
|
||||
> - <https://github.com/vouch/vouch-proxy/issues/310>
|
||||
|
||||
Note: **You need to run at least the version 0.37.0**
|
||||
|
||||
Vouch Proxy supports multiple OAuth and OIDC login providers. To configure it you need to pass:
|
||||
|
||||
```yaml
|
||||
oauth:
|
||||
auth_url: https://idm.wherekanidmruns.com/ui/oauth2
|
||||
callback_url: https://login.wherevouchproxyruns.com/auth
|
||||
client_id: <oauth2_rs_name> # Found in kanidm system oauth2 get XXXX (should be the same as XXXX)
|
||||
client_secret: <oauth2_rs_basic_secret> # Found in kanidm system oauth2 get XXXX
|
||||
code_challenge_method: S256
|
||||
provider: oidc
|
||||
scopes:
|
||||
- email # Required due to vouch proxy reliance on mail as a primary identifier
|
||||
token_url: https://idm.wherekanidmruns.com/oauth2/token
|
||||
user_info_url: https://idm.wherekanidmruns.com/oauth2/openid/<oauth2_rs_name>/userinfo
|
||||
```
|
||||
|
||||
The `email` scope needs to be passed and thus the mail attribute needs to exist on the account:
|
||||
|
||||
```bash
|
||||
kanidm person update <ID> --mail "YYYY@somedomain.com" --name idm_admin
|
||||
```
|
45
book/src/integrations/oauth2/how_does_oauth2_work.md
Normal file
45
book/src/integrations/oauth2/how_does_oauth2_work.md
Normal file
|
@ -0,0 +1,45 @@
|
|||
# How Does OAuth2 Work?
|
||||
|
||||
OAuth2 uses a number of terms in ways that can make it unclear and difficult to understand.
|
||||
|
||||
A user wishes to access a service (resource, resource server) through an OAuth2 client. The client
|
||||
does not have an active session for the userm so it redirects to the authorisation server (Kanidm) to
|
||||
determine if the user has the appropriate permissions (scopes) for
|
||||
the requested resources, and should be allowed to proceed.
|
||||
|
||||
The authorisation server checks the current session of the user and may present a login flow if
|
||||
required. Based on the identity of the user and the requested scopes,
|
||||
the authorisation server makes a decision if it allows the authorisation to proceed. The user is
|
||||
then prompted to consent to the authorisation from the authorisation server to the client as some
|
||||
identity information may be revealed by granting this consent.
|
||||
|
||||
If successful and consent is given, the user is redirected back to the client with an authorisation
|
||||
code. The client then contacts the authorisation server directly with this code and exchanges it for
|
||||
a valid OAuth token.
|
||||
|
||||
The client may then optionally contact the token introspection endpoint of the authorisation server
|
||||
about the provided OAuth token, which yields extra metadata about the identity that holds the token
|
||||
from the authorisation. This metadata may include identity information, but also may include
|
||||
extended metadata, sometimes referred to as "claims". Claims are information bound to a token based
|
||||
on properties of the session that may allow the client to make extended authorisation decisions
|
||||
without the need to contact the authorisation server to arbitrate.
|
||||
|
||||
In many cases the client and the resource server are the same entity. When the client and resource
|
||||
server are _separate_ services, the client can then forward the access token to the resource server
|
||||
for authorisation of the user's request.
|
||||
|
||||
It's important to note that OAuth2 at its core is an authorisation system which has layered
|
||||
identity-providing elements on top.
|
||||
|
||||
### Why Does Sharing a Client Weaken OAuth2?
|
||||
|
||||
By sharing a client ID between multiple applications this implies that all of these applications are
|
||||
a singular client in Kanidm's view. This means tokens issued to one application can be reused on any
|
||||
other application.
|
||||
|
||||
This limits your ability to enforce scopes, presents a large compromise blast radius if a token is
|
||||
stolen, and also increases the damage radius if the client credentials are stolen.
|
||||
|
||||
Generally this also provides a bad user experience since the Kanidm application portal only lists a
|
||||
single landing URL of the client, so subsequent applications that "piggy back" can not be redirected
|
||||
to from the application portal meaning that users will not easily be able to access the application.
|
0
book/src/integrations/oauth2_claims.md
Normal file
0
book/src/integrations/oauth2_claims.md
Normal file
|
@ -37,7 +37,9 @@ You can check the privileged tasks daemon is running with:
|
|||
systemctl status kanidm-unixd-tasks
|
||||
```
|
||||
|
||||
> **NOTE** The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality. If
|
||||
> [!NOTE]
|
||||
>
|
||||
> The `kanidm_unixd_tasks` daemon is not required for PAM and nsswitch functionality. If
|
||||
> disabled, your system will function as usual. It is however strongly recommended due to the
|
||||
> features it provides supporting Kanidm's capabilities.
|
||||
|
||||
|
|
|
@ -44,12 +44,12 @@ Enter password:
|
|||
|
||||
### Public Key Caching Configuration
|
||||
|
||||
If you have kanidm\_unixd running, you can use it to locally cache SSH public keys. This means you
|
||||
If you have `kanidm_unixd` running, you can use it to locally cache SSH public keys. This means you
|
||||
can still SSH into your machines, even if your network is down, you move away from Kanidm, or some
|
||||
other interruption occurs.
|
||||
|
||||
The kanidm\_ssh\_authorizedkeys command is part of the kanidm-unix-clients package, so should be
|
||||
installed on the servers. It communicates to kanidm\_unixd, so you should have a configured
|
||||
The `kanidm_ssh_authorizedkeys` command is part of the `kanidm-unix-clients` package, so should be
|
||||
installed on the servers. It communicates to `kanidm_unixd`, so you should have a configured
|
||||
PAM/nsswitch setup as well.
|
||||
|
||||
You can test this is configured correctly by running:
|
||||
|
@ -75,8 +75,10 @@ Restart sshd, and then attempt to authenticate with the keys.
|
|||
It's highly recommended you keep your client configuration and sshd_configuration in a configuration
|
||||
management tool such as salt or ansible.
|
||||
|
||||
> **NOTICE:** With a working SSH key setup, you should also consider adding the following
|
||||
> sshd\_config options as hardening.
|
||||
> [!NOTE]
|
||||
>
|
||||
> With a working SSH key setup, you should also consider adding the following
|
||||
> `sshd_config` options as hardening.
|
||||
|
||||
```text
|
||||
PermitRootLogin no
|
||||
|
@ -90,11 +92,13 @@ KerberosAuthentication no
|
|||
|
||||
In this mode, the authorised keys commands will contact Kanidm directly.
|
||||
|
||||
> **NOTICE:** As Kanidm is contacted directly there is no SSH public key cache. Any network outage
|
||||
> [!NOTE]
|
||||
>
|
||||
> As Kanidm is being contacted directly there is no SSH public key cache. Any network outage
|
||||
> or communication loss may prevent you accessing your systems. You should only use this version if
|
||||
> you have a requirement for it.
|
||||
|
||||
The kanidm\_ssh\_authorizedkeys\_direct command is part of the kanidm-clients package, so should be
|
||||
The `kanidm_ssh_authorizedkeys_direct` command is part of the kanidm-clients package, so should be
|
||||
installed on the servers.
|
||||
|
||||
To configure the tool, you should edit /etc/kanidm/config, as documented in
|
||||
|
|
|
@ -16,7 +16,9 @@ docker pull kanidm/radius:latest
|
|||
docker pull kanidm/tools:latest
|
||||
```
|
||||
|
||||
> **NOTE** Our preferred deployment method is in containers, and this documentation assumes you're
|
||||
> [!NOTE]
|
||||
>
|
||||
> Our preferred deployment method is in containers, and this documentation assumes you're
|
||||
> running in docker. Kanidm will alternately run as a daemon/service, and server builds are
|
||||
> available for multiple platforms if you prefer this option. You may need to adjust the example
|
||||
> commands throughout this document to suit your desired server type if you choose not to use
|
||||
|
@ -98,7 +100,9 @@ the series of intermediates, and the final certificate should be the CA root. Fo
|
|||
-----END CERTIFICATE-----
|
||||
```
|
||||
|
||||
> **HINT** If you are using Let's Encrypt the provided files "fullchain.pem" and "privkey.pem" are
|
||||
> [!NOTE]
|
||||
>
|
||||
> If you are using Let's Encrypt the provided files "fullchain.pem" and "privkey.pem" are
|
||||
> already correctly formatted as required for Kanidm.
|
||||
|
||||
You can validate that the leaf certificate matches the key with the command:
|
||||
|
@ -130,7 +134,9 @@ for example) then you can validate with this command.
|
|||
openssl verify -untrusted fullchain.pem fullchain.pem
|
||||
```
|
||||
|
||||
> **NOTE** Here "-untrusted" flag means a list of further certificates in the chain to build up to
|
||||
> [!NOTE]
|
||||
>
|
||||
> Here "-untrusted" flag means a list of further certificates in the chain to build up to
|
||||
> the root is provided, but that the system CA root should be consulted. Verification is NOT
|
||||
> bypassed or allowed to be invalid.
|
||||
|
||||
|
|
|
@ -14,7 +14,9 @@ docker exec -i -t <container name> \
|
|||
|
||||
You must then copy the new certificate to other nodes in the topology.
|
||||
|
||||
> **NOTE** In the future we will develop a replication coordinator so that you don't have to
|
||||
> [!NOTE]
|
||||
>
|
||||
> In the future we will develop a replication coordinator so that you don't have to
|
||||
> manually renew this. But for now, if you want replication, you have to do it the hard way.
|
||||
|
||||
## Refresh a Lagging Consumer
|
||||
|
|
|
@ -30,7 +30,9 @@ Once configured, deploy this config to your servers and restart the nodes.
|
|||
|
||||
## Manual Node Configurations
|
||||
|
||||
> **NOTE** In the future we will develop a replication coordinator so that you don't have to
|
||||
> [!NOTE]
|
||||
>
|
||||
> In the future we will develop a replication coordinator so that you don't have to
|
||||
> manually configure this. But for now, if you want replication, you have to do it the hard way.
|
||||
|
||||
Each node has an identify certificate that is internally generated and used to communicate with
|
||||
|
@ -91,7 +93,9 @@ docker exec -i -t <container name> \
|
|||
|
||||
## Partially Automated Node Configurations
|
||||
|
||||
> **NOTE** In the future we will develop a replication coordinator so that you don't have to
|
||||
> [!NOTE]
|
||||
>
|
||||
> In the future we will develop a replication coordinator so that you don't have to
|
||||
> manually configure this. But for now, if you want replication, you have to do it the hard way.
|
||||
|
||||
This is the same as the manual process, but a single server is defined as the "primary" and the
|
||||
|
|
|
@ -18,7 +18,7 @@ docs page for your particular build.
|
|||
|
||||
> [!WARNING]
|
||||
>
|
||||
> You MUST set the "domain", "origin", "tls_chain" and "tls_path" options via one method
|
||||
> You MUST set the `domain`, `origin`, `tls_chain` and `tls_path` options via one method
|
||||
> or the other, or the server cannot start!
|
||||
|
||||
The following is a commented example configuration.
|
||||
|
@ -54,7 +54,7 @@ configuration file in `/data/server.toml`.
|
|||
docker run -p 443:8443 -v kanidmd:/data kanidm/server:latest
|
||||
```
|
||||
|
||||
### Using the NET\_BIND\_SERVICE capability
|
||||
### Using the `NET_BIND_SERVICE` capability
|
||||
|
||||
If you plan to run without using docker port mapping or some other reverse proxy, and your
|
||||
`bindaddress` or `ldapbindaddress` port is less than `1024` you will need the `NET_BIND_SERVICE` in
|
||||
|
|
|
@ -52,7 +52,7 @@ This is a list of supported features and standards within Kanidm.
|
|||
- [OpenID Connect Core 1.0](https://openid.net/specs/openid-connect-core-1_0.html)
|
||||
- RBAC claim and scope mapping
|
||||
- PII scope claim requests
|
||||
- ES256 id\_token signatures
|
||||
- ES256 `id_token` signatures
|
||||
- [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)
|
||||
|
||||
# RADIUS
|
||||
|
|
|
@ -37,7 +37,7 @@ submitted.
|
|||
## Creating a Sync Account
|
||||
|
||||
Creating a sync account requires administration permissions. By default this is available to members
|
||||
of the "system\_admins" group which "admin" is a memberof by default.
|
||||
of the `system_admins` group which `admin` is a memberof by default.
|
||||
|
||||
```bash
|
||||
kanidm system sync create <sync account name>
|
||||
|
|
Loading…
Reference in a new issue