We are running GKE with workloads using workload identities. Would it be possible to use these ID tokens to authenticate as Keycloak users?
Is this the documentation under Using token exchange - Keycloak?
We are running GKE with workloads using workload identities. Would it be possible to use these ID tokens to authenticate as Keycloak users?
Is this the documentation under Using token exchange - Keycloak?
Or differently, can we use the JWTs of the Kubernetes service accounts to authenticate with Keycloak?
Regarding the token exchange, you might find other use cases discussed in this discussion.
As for the other point, Keycloak supports client authentication using signed JWTs, with the client’s public key obtained externally. Perhaps you could play with that.
You could do this with a custom authenticator.
In the AuthenticatorFactory you would configure the JWKS endpoint that is used to verify the digital signature of the JWT. In your authenticator you would validate the JWT using the keys from the keys endpoint. I have not found a a way to cache the .JWKS data based on the given call chain and instantiation patterns.
UserModel user = context.getSession().users().getUserByUsername(context.getRealm(), <usernamefromtheJWT>);
context.setUser(user);
context.success();
Actually, I got it working. Working on a write-up right now. No custom authenticator needed.
docker run --name keycloak \
-p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
quay.io/keycloak/keycloak:26.0.7 \
start-dev \
--features=token-exchange,admin-fine-grained-authz
http://localhost:8080 and login.exchange.Identity providers and add the Google default identity provider.Client ID and Client Secret by following the steps documented here: Desktop.external-to-internal.Client authentication.Clients and select the realm-management client.Authorization tab, then the Policies sub-tab and select Create client policy.Client.external-to-internal.external-to-internal.Identity providers again and select the google provider.Permissions tab and enable them.token-exchange scope name under Permission list.external-to-internal policy and save the changes.curl to be installed, though.curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token"
4.WARNING: This will also work if the pod doesn’t have a workload identity, but will return an invalid access_token.
5. You should now have a valid access_token for your workload.
external-to-internal client created in step 1.5.export REALM=exchange
export CLIENT_ID=external-to-internal
export CLIENT_SECRET=
export IDENTITY_PROVIDER_ALIAS=google
export WORKLOAD_ACCESS_TOKEN=
curl --location "http://localhost:8080/realms/$REALM/protocol/openid-connect/token" \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
--data-urlencode "client_id=$CLIENT_ID" \
--data-urlencode "client_secret=$CLIENT_SECRET" \
--data-urlencode "subject_token=$WORKLOAD_ACCESS_TOKEN" \
--data-urlencode "subject_token_type=urn:ietf:params:oauth:token-type:access_token" \
--data-urlencode "subject_issuer=$IDENTITY_PROVIDER_ALIAS" \
--data-urlencode "audience=$CLIENT_ID"
Token-Exchange Use-cases · keycloak keycloak · Discussion #26502