Keycloak and Vault Integration with Client Role - keycloak

I am trying to integrate Keycloak with Vault. I have 2 Vault policies (Admin, Dev). I want to use a path 'keycloak', and have done $ vault auth enable -path=keycloak oidc.
The problem I want to solve, is to map Vault Policy with the Keycloak Client Role.
$ vault write auth/keycloak/config \
oidc_discovery_url="https://$KEYCLOAK_ADDRESS/auth/realms/master" \
oidc_client_id="vault" \
oidc_client_secret=${CLIENT_SECRET} \
default_role="admin" type="oidc"
$ vault write auth/keycloak/role/admin \
bound_audiences="vault" \
allowed_redirect_uris="https://$VAULT_ADDRESS/ui/vault/auth/oidc/oidc/callback" \
allowed_redirect_uris="https://localhost:8250/oidc/callback" \
user_claim="sub" \
policies="admin" \
ttl=4h \
role_type="oidc" \
oidc_scopes="openid"
$ vault write auth/keycloak/role/dev \
bound_audiences="vault" \
allowed_redirect_uris="https://$VAULT_ADDRESS/ui/vault/auth/oidc/oidc/callback" \
allowed_redirect_uris="https://localhost:8250/oidc/callback" \
user_claim="sub" \
policies="dev" \
ttl=4h \
role_type="oidc" \
oidc_scopes="openid"
I want admin and dev roles in Vault bound to "vault" client in Keycloak. However, according to the group that the user is bounded to, I want the user to have different policy. (Both login via console with vault login -method=oidc keycloak)
Have any ideas? The solution I have in mind is to make 2 different client. However, I want only 1 client 'vault'. Can this be achieved?

Go to your client, then go to Mappers tab, then press Add Builtin
Then find groups in search and add it
After this in your jwt token payload will appear groups section
Then configure groups_claim in your vault oidc configuration
$ vault write auth/keycloak/role/admin \
bound_audiences="vault" \
allowed_redirect_uris="https://$VAULT_ADDRESS/ui/vault/auth/oidc/oidc/callback" \
allowed_redirect_uris="https://localhost:8250/oidc/callback" \
user_claim="sub" \
policies="admin" \
ttl=4h \
role_type="oidc" \
oidc_scopes="openid" \
groups_claim="groups"
$ vault write auth/keycloak/role/dev \
bound_audiences="vault" \
allowed_redirect_uris="https://$VAULT_ADDRESS/ui/vault/auth/oidc/oidc/callback" \
allowed_redirect_uris="https://localhost:8250/oidc/callback" \
user_claim="sub" \
policies="dev" \
ttl=4h \
role_type="oidc" \
oidc_scopes="openid" \
groups_claim="groups"

Related

Keycloak admin CLI operations inside a new realm as the superadmin returns "Unauthorized"

I'd like to automate keycloak (20.0.1) in order to create what I need for a project. The problem is that kcadm.sh returns "Unauthorized" whenever I do some operation (let's say, add a user) inside a newly created realm as the keycloak admin.
The script looks like this:
./kcadm.sh config credentials \
--server "http://localhost:8080" \
--realm master \
--user USER \
--password PASSWORD
./kcadm.sh create realms \
--set "realm=demo-realm" \
--set "enabled=true"
./kcadm.sh create users \
--realm "demo-realm" \
--set "username=someuser" \
--set "enabled=true" \
--set "emailVerified=true"
and what I get is this:
(the realm is not the error, it is intended)
For what I understood, I need to be connected into the realm, thus executing config credentials with the demo-realm realm. So I tried to connect with the admin-cli and the realm-management clients, both with their respective clientId and using the super admin account. None works and I'm stuck unable to automate these simple tasks.
Is there something I've done wrong or something I missed somehow ?
Instead of
./kcadm.sh create users --realm "demo-realm" --set "username=someuser" --set "enabled=true"
do either
./kcadm.sh create users --target-realm "demo-realm" --set "username=someuser" --set "enabled=true"
or
./kcadm.sh create users -r "demo-realm" --set "username=someuser" --set "enabled=true"
From the command specific options one can read:
-r, --target-realm REALM Target realm to issue requests against if not the one authenticated against
Since you have authenticated first against the master realm:
./kcadm.sh config credentials \
--server "http://localhost:8080" \
--realm master \
--user USER \
--password PASSWORD
and you want to create a resource in a different realm (i.e., demo-realm) you need to pass the flag --target-realm (or -r).

Creating an AKS Cluster using C#?

I have not found a way to do so using C# K8s SDK: https://github.com/kubernetes-client/csharp
How to create a AKS Cluster in C#? Basically, the following command:
az aks create -g $RESOURCE_GROUP -n $AKS_CLUSTER \
--enable-addons azure-keyvault-secrets-provider \
--enable-managed-identity \
--node-count $AKS_NODE_COUNT \
--generate-ssh-keys \
--enable-pod-identity \
--network-plugin azure
Sending a PUT request with payload (JSON body) to ARM.
See this: https://learn.microsoft.com/en-us/rest/api/aks/managed-clusters/create-or-update?tabs=HTTP

Assigning IP addresses to multiple nightly k8s clusters

Background:
We run Analytics pipelines on dedicated clusters once a day. All clusters are created at the same time, have once pod deployed, run their pipeline and are deleted once complete, use the default VPC network in the same region and are created with a command like this:
gcloud beta container clusters create <CLUSTER_NAME> \
--zone "europe-west1-b" \
--machine-type "n1-standard-2" \
--num-nodes=1 \
--scopes=https://www.googleapis.com/auth/cloud-platform \
--service-account=<SA_EMAIL> \
--disk-size 10GB \
--network default \
--subnetwork <SUB_NETWORK> \
--enable-master-global-access \
--enable-private-nodes \
--enable-private-endpoint \
--enable-ip-alias \
--enable-intra-node-visibility \
--enable-master-authorized-networks \
--master-ipv4-cidr=<MASTER_IP>/28 \
--cluster-ipv4-cidr <CLUSTER_IP>/14 \
--services-ipv4-cidr <SERVICES_IP/20 \
--enable-network-policy \
--enable-shielded-nodes
When we add a new cluster for a new pipeline we have encountered issues where the IP addresses collide, overlap and are unavailable. As we expect to continually add more pipelines and thus more clusters we want an automated way of avoiding this issue.
We have explored creating a dedicated network (and subnetwork) for each cluster so each cluster can have the same IP addresses (albeit in different networks) but are unsure if this is best practice.
Question:
Is it possible to create kubernetes clusters in Google Cloud so as the master, cluster and service IP addresses are auto-assigned?

Expose Hue with Component Gateway for Dataproc

Is it possible to expose Hue with Component Gateway for Dataproc? I went through the docs and didn't find any option to add service to it. I am creating Dataproc cluster with below command.
gcloud beta dataproc clusters create hive-cluster \
--scopes sql-admin,bigquery \
--image-version 1.5 \
--master-machine-type n1-standard-4 \
--num-masters 1 \
--worker-machine-type n1-standard-1 \
--num-workers 2 \
--region $REGION \
--zone $ZONE \
--optional-components=ANACONDA,JUPYTER \
--initialization-actions gs://bucket/init-scripts/cloud-sql-proxy.sh,gs://bucket/init-scripts/hue.sh \
--properties hive:hive.metastore.warehouse.dir=gs://$PROJECT-warehouse/datasets,dataproc:jupyter.notebook.gcs.dir=gs://bucket/notebooks/jupyter \
--metadata "hive-metastore-instance=$PROJECT:$REGION:hive-metastore" \
--enable-component-gateway
Hue is not an optional component of Dataproc, hence not accessible from component gateway. For now, you have to use Dataproc web interfaces:
Once the cluster has been created, Hue is configured to run on port 8888 on the master node in a Dataproc cluster. To connect to the Hue web interface, you will need to create an SSH tunnel and use a SOCKS 5 Proxy with your web browser as described in the dataproc web interfaces documentation. In the opened web browser go to 'localhost:8888' and you should see the Hue UI.

Obtaining JWT of a user in Keycloak

As admin of a Keycloak server, how can I obtain access-token of a particular user without knowing his password? Unfortunately impersonation doesn't help me because it does not contain neither his id nor his username.
There's a feature starting from keycloak 3.4.0 called token exchange wich allows you to exchange an access token from a user with impersonation permission to get other token on behalf of the other user. You can use the token endpoint this way:
curl -X POST \
-d "client_id=starting-client" \
-d "client_secret=geheim" \
--data-urlencode "grant_type=urn:ietf:params:oauth:grant-type:token-exchange" \
-d "subject_token=...." \
--data-urlencode "requested_token_type=urn:ietf:params:oauth:token-type:access_token" \
-d "audience=target-client" \
-d "requested_subject=wburke" \
http://localhost:8080/auth/realms/myrealm/protocol/openid-connect/token
You might find this post useful too.