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