Not sure when it happened, but I have been binging self-hosted identity providers like Netflix shows, this season features Authentik, KeyCloak, Synology SSO and Pocket ID.
To add to my collection, I was recently asked whether Zitadel could also work as an identity provider with vCenter Server and/or VMware Cloud Foundation (VCF)?
As you can see from the screenshot above, you have your answer 😁
Step 0 (Optional) - If you do not have an existing TLS certificate, here is a quick snippet for using OpenSSL to create a self-signed TLS certificate with the following required files:
- key.pem - Private Key
- cert.crt - Certificate
- fullchain.pem - Certificate Chain
openssl req -new -key key.pem -out csr.pem -subj "/C=US/ST=CA/L=Palo Alto/O=WilliamLam/OU=R&D/CN=auth.williamlam.local" openssl x509 -req -in csr.pem -signkey key.pem -out cert.crt -days 365 cat cert.crt key.pem > fullchain.pem
Step 1 - Install Zitadel, there are a number of deployment options, I went with Docker Compose as that is the quickest. While standing up a basic non-HTTPS Zitadel solution was fairly straight forward, when needing to configure HTTPS, the documentation was not very clear and I had to hop around to multiple parts of the documentation along with some trial/error to figure it out.
To save you time, grab the docker-compose.yaml file and then make the following edits as shown in the example below:
- command - Set tlsMode to enabled
- ZITADEL_EXTERNALDOMAIN - This is the FQDN of your Zitadel endpoint
- ZITADEL_EXTERNALSECURE - Set to true for accessing your Zitadel endpoint over HTTPS
- ZITADEL_EXTERNALPORT - This is the port to access your Zitadel endpoint
- ZITADEL_PORT - This is the internal port for the Zitadel service, I kept it the same as my ZITADEL_EXTERNALPORT
- ZITADEL_TLS_ENABLED - Set to true for accessing your Zitadel endpoint over HTTPS
- ZITADEL_TLS_KEYPATH - Full path to your TLS private key
- ZITADEL_TLS_CERTPATH - Full path to your TLS certifcate
- ports - You will need to map the internal and external ports of the Zitadel service, it should match ZITADEL_PORT and ZITADEL_EXTERNALPORT
- volumes - We also need to map the local and remote path of your TLS certificate/private key
services: zitadel: restart: 'always' networks: - 'zitadel' image: 'ghcr.io/zitadel/zitadel:latest' command: 'start-from-init --masterkey "MasterkeyNeedsToHave32Characters" --tlsMode enabled' environment: ZITADEL_DATABASE_POSTGRES_HOST: db ZITADEL_DATABASE_POSTGRES_PORT: 5432 ZITADEL_DATABASE_POSTGRES_DATABASE: zitadel ZITADEL_DATABASE_POSTGRES_USER_USERNAME: zitadel ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel ZITADEL_DATABASE_POSTGRES_USER_SSL_MODE: disable ZITADEL_DATABASE_POSTGRES_ADMIN_USERNAME: postgres ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD: postgres ZITADEL_DATABASE_POSTGRES_ADMIN_SSL_MODE: disable ZITADEL_EXTERNALDOMAIN: auth.williamlam.local ZITADEL_EXTERNALSECURE: true ZITADEL_EXTERNALPORT: 443 ZITADEL_PORT: 443 ZITADEL_TLS_ENABLED: true ZITADEL_TLS_KEYPATH: /etc/tls/key.pem ZITADEL_TLS_CERTPATH: /etc/tls/cert.crt depends_on: db: condition: 'service_healthy' ports: - '443:443' volumes: - /etc/tls:/etc/tls db: restart: 'always' image: postgres:17-alpine environment: PGUSER: postgres POSTGRES_PASSWORD: postgres networks: - 'zitadel' healthcheck: test: ["CMD-SHELL", "pg_isready", "-d", "zitadel", "-U", "postgres"] interval: '10s' timeout: '30s' retries: 5 start_period: '20s' networks: zitadel:
After saving your changes, start the Zitadel service with docker compose up -d and you should now be able to access your Zitadel endpoint by opening a browser to your configured FQDN: http://auth.williamlam.local/ui/console
Note: The initial login username will be zitadel-admin[at]zitadel.[YOUR-FQDN] (e.g. zitadel-admin[at]zitadel.auth.williamlam.local) with the initial password as Password1!
Step 3 - When you first login, you will be placed in the default Zitadel organization. Go ahead and create a new organization and then switch into that organization and create a new project before proceeding to the next step.
Step 4 - Create a new Web application and provide a name and then click continue.
Step 5 - Select the Code authentication method and then click continue.
Step 6 - Login to your vCenter Server and navigate to Administration->Single Sign On->Configuration->Identity Provider and select the PingFederate option and populate the directory name and DNS domain.
Copy the vCenter Server Redirect URI and then head back to Zitadel to retrieve the rest of the required configurations.
Step 7 - Enter the redirect URL from Step 6 and then click continue to create the application. Make a note of the ClientId and ClientSecret values which we will need to complete the vCenter Server Identity Federation configuration.
Step 8 - Lastly, we need to retrieve the OpenID address. Click on URLs and copy the discovery endpoint URL.
Step 9 - Navigate back to your vCenter Server to complete the configuration and populate all fields as shown in the screenshot below along with full certificate chain.
Step 10 - Zitadel does not have support for the SCIM (System for Cross-domain Identity Management) protocol, which means we need to manually make vCenter Server Identity Broker (vIDB) aware of the users before we can assign vSphere permissions.
Click on the Users tab at the top of the Zitadel console to create a new user, make a note of the ID as shown in the screenshot as that is the ID that we will need to populate the vIDB.
Step 11 - We now need to publish the Zitadel users into vCenter Server's Identity Broker and to simplify this process, I have created a shell script that needs to be run directly within the VCSA that accepts a CSV file that contains the list of users and their configurations.
Using the information from Step 10, create a CSV file that contains list of users in the following format:
# Username, First Name, Last Name, Email, External Id lamw, William, Lam, lamw[at]williamlam.local, 314060124115173379
Note: Any entries with a "#" will be ignored by the script, so you can easily comment out entries that you do not wish to publish to vIDB.
Next, download the manual-scim-sync-users.sh script and the user CSV file to your VCSA and run the script with the following three arguments: vSphere admin username, password and the name of your CSV text file as shown in the screenshot below.
./manual-scim-sync-users.sh 'administrator[at]vsphere.local' 'VMware1!' external_users.txt
Step 12 - Login to your vCenter Server with your vSphere SSO account and you should now be able to lookup users from Zitadel and assign vSphere Permissions. Once you have assigned the desired vSphere Permission, you can open an incognito window and after authenticating with Zitadel and successfully log into vCenter Server!
If you need to remove users from vCenter Server's Identity Broker (vIDB), you can download the manual-scim-remove-users.sh script that can help with automating that process. Create a simliar CSV file with the list of users that you wish to un-publish and then run the script with the following three arguments: vSphere admin username, password and the name of your CSV text file as shown in the screenshot below.
./manual-scim-remove-users.sh 'administrator[at]vsphere.local' 'VMware1!' external_users.txt
Thanks for the comment!