mirror of
https://github.com/keycloak/keycloak.git
synced 2026-01-09 23:12:06 -03:30
Closes #42947 Signed-off-by: Sebastian Łaskawiec <sebastian.laskawiec@defenseunicorns.com> Signed-off-by: Alexander Schwartz <alexander.schwartz@ibm.com> Co-authored-by: Alexander Schwartz <alexander.schwartz@ibm.com>
122 lines
4.7 KiB
Plaintext
122 lines
4.7 KiB
Plaintext
ifeval::[{project_community}==true]
|
|
|
|
[[_identity_broker_kubernetes]]
|
|
=== Kubernetes identity providers
|
|
|
|
:tech_feature_name: Kubernetes service accounts trust relationship provider
|
|
:tech_feature_id: kubernetes
|
|
include::../../topics/templates/techpreview.adoc[]
|
|
|
|
:tech_feature_name: Authenticate clients based on assertions issued by an identity provider
|
|
:tech_feature_id: client-auth-federated
|
|
include::../../topics/templates/techpreview.adoc[]
|
|
|
|
A Kubernetes identity provider supports authenticating clients with Kubernetes service account tokens.
|
|
It depends on the preview feature `client-auth-federated`.
|
|
|
|
The default issuer URL for a Kubernetes cluster is `\https://kubernetes.default.svc.cluster.local`. You can discover
|
|
this value by decoding a service account token to retrieve the value of the `iss` claim.
|
|
|
|
Keycloak must be able to invoke the endpoint `<ISSUER>/.well-known/openid-configuration` and additionally the
|
|
JWKS endpoint returned in the well-known configuration. By default, these endpoints require authentication with a
|
|
service account token. ${project_name} will automatically use the token from `/var/run/secrets/kubernetes.io/serviceaccount/token`
|
|
if available and the token issuer matches the configured issuer.
|
|
|
|
Each identity provider must have a unique issuer. Each client must also have a unique subject identifier for each
|
|
issuer. As the subject identifier is built from the namespace and service account name, each client must have its own
|
|
service account if multiple clients share a namespace.
|
|
|
|
As a security best practice, do not use the `default` service account in a namespace, as it is shared with all Pods in a namespace.
|
|
Instead, create an individual service account for each client.
|
|
|
|
Kubernetes service account tokens can be reused multiple times. As a security best practice, reduce the expiration time
|
|
and make sure tokens can not be intercepted in communication between the client and {project_name}.
|
|
|
|
|
|
.Procedure
|
|
. Click *Identity Providers* in the menu.
|
|
. From the `Add provider` list, select `Kubernetes`.
|
|
+
|
|
. Enter your initial configuration options or proceed with the defaults.
|
|
+
|
|
.Kubernetes settings
|
|
|===
|
|
|Configuration|Description
|
|
|
|
|Alias
|
|
|The alias for the identity provider is used to link a client to the provider
|
|
|
|
|Kubernetes Issuer URL
|
|
|The issuer URL of service account tokens. The URL `<ISSUER>.well-known/openid-configuration` must be available to {project_name})
|
|
|
|
|===
|
|
+
|
|
. When you create a new realm with the preview feature `client-auth-federated` enabled, the client authentication flow is already configured correctly. For existing realms, add to the client authentication flow the execution of *Signed JWT - Federated* as an alternative step. As built-in flows can not be updated, and if the default flow is your default, you will first need to duplicate the existing clients
|
|
. For each confidential OpenID Connect client that should authenticate via this provider:
|
|
.. Change in the *Credentials* tab the *Client Authenticator* to *Signed JWT - Federated*.
|
|
.. As *Identity provider*, enter the alias of the Kubernetes identity provider added in step 3.
|
|
.. As *Federated Subject*, enter the subject identifier as issued by Kubernetes. This is usually `system:serviceaccount:<namespace>:<serviceaccount>`.
|
|
+
|
|
|
|
. For the Pod in Kubernetes add a service account:
|
|
+
|
|
--
|
|
[source]
|
|
----
|
|
apiVersion: v1
|
|
kind: Pod
|
|
...
|
|
spec:
|
|
serviceAccountName: <serviceaccount>
|
|
...
|
|
volumes:
|
|
- name: aud-token
|
|
projected:
|
|
defaultMode: 420
|
|
sources:
|
|
- serviceAccountToken:
|
|
audience: https://example.com:8443/realms/test <1>
|
|
expirationSeconds: 600 <2>
|
|
path: my-aud-token
|
|
----
|
|
. Issuer URL of the {project_name} realm.
|
|
. Maximum time allowed by Kubernetes and {project_name} is 3600 seconds
|
|
--
|
|
+
|
|
|
|
To verify your setup, assuming the client has a service account configured:
|
|
|
|
. In the Pod, retrieve the token
|
|
+
|
|
[source]
|
|
----
|
|
cat /var/run/secrets/tokens/my-aud-token
|
|
----
|
|
. Use the token as the client credentials
|
|
+
|
|
[source]
|
|
----
|
|
curl -k https://example.com:8443/realms/<realm>/protocol/openid-connect/token \
|
|
-H 'Content-Type: application/x-www-form-urlencoded' \
|
|
--data-urlencode grant_type=client_credentials \
|
|
--data-urlencode client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
|
|
--data-urlencode client_assertion=<token>
|
|
----
|
|
. Verify the response
|
|
+
|
|
[source,json]
|
|
----
|
|
{
|
|
"access_token": "ey...bw",
|
|
"expires_in": 300,
|
|
"refresh_expires_in": 0,
|
|
"token_type": "Bearer",
|
|
"not-before-policy": 0,
|
|
"scope": "profile email"
|
|
}
|
|
----
|
|
|
|
NOTE: While the service account functionality is helpful to test that the setup is working, disabled this feature after the test if it is not needed for the client to follow the least-privileges security best practice.
|
|
|
|
endif::[]
|