QTA-10000 - Zitadel System API Access

2 min read

QTA-10000 outlines, how primarily self-hosting clients can maintain control/access over/to their IDP (specifically Zitadel) instance where human access was granted over an Identity Provider which then for any reason broke or became invalid (e.g. an expired secret).

Statement

This procedure is neither a security leak, issue or backdoor. Granting System API Access to key-authenticated users is a core feature of Zitadel. Having this authentication in place ensures, that the deployment operator (the persona self-hosting the IDP) can always recover the instance even if the instance owners (users or the deployment operator themselves) make potentially fatal (lock-out) configuration mistakes.

Mitigation

The mitigation is actually achievable via the Zitadel Documentation. Unique outlines the high-level procedure again though as it can be critical to restore/keep the control over the instance.

Prerequisites: Clients must have full control over the deployment. Ergo you must be a deployment operator or the infrastructure provider. The procedure can’t be performed by anyone who does not control the deployment of the service.

note

By continuing with this guide you acknowledge that it's only suitable to be applied for individuals that have the necessary qualifications. Unique is not responsible and/or liable for any inaccuracies disruptions that occur from following this guide blindly without doing own research.

Unique Advisory is available pro rata for enterprise clients featuring a matching contract.

  1. Follow the Access ZITADEL System API guide to create

    1. a key pair

    2. add the key pair to the instance (deployment)

    3. assign a role to the key

      yaml
      zitadel:
        configmapConfig:
          SystemAPIUsers:
            - my-emergency-user-1:
                KeyData: <base64 encoded public key .pub>
                Memberships:
                  - MemberType: System
                    Roles:
                      - "IAM_OWNER"

      This is an example! Make sure you choose your roles carefully for the use cases you want to cover! Refer to the Access ZITADEL System API guide to learn more.

  2. You must create yourself a JWT. This part is not so trivial but Zitadel offers help here as well:

    1. https://github.com/zitadel/zitadel-toolskey2jwt

  3. It goes without saying that the private key from step 1 is stored according to your companies standards.

After the JWT for the user is acquired, it can be used as a Bearer token for calling the Zitadel APIs.

Example scenario 1 - Update clientSecret of a registered IdP

Since we try to update a clientSecret or an IdP in this procedure, depending where the IdP was added there is a two way split:

  1. The IdP was added to the Instance…

    1. https://zitadel.com/docs/apis/resources/admin/admin-service-list-providers

    2. https://zitadel.com/docs/apis/resources/admin/admin-service-update-azure-ad-provider

  2. The IdP was added to an organisation…

    1. https://zitadel.com/docs/apis/resources/admin/admin-service-list-orgs

    2. https://zitadel.com/docs/apis/resources/mgmt/management-service-list-providers

    3. https://zitadel.com/docs/apis/resources/mgmt/management-service-update-azure-ad-provider

Example scenario 2 - Recover username-password login for root user

This scenario covers the case where an accidental lock-out of the root user from the ClusterIAM instance in Zitadel was created by disabling the username-password login method on the ClusterIAM organization.

Resetting the login policy of the root organization to the instance default (where username-password login is allowed by default) is done by deleting the login policy of the organization. Here is an example request:

bash
curl -X DELETE "https://id.<base-url>/management/v1/policies/login" \
  --header "Authorization: Bearer ${token}" \
  --header "Content-Type: application/json" \
  --header "x-zitadel-orgid: <zitadel-org-id>"

Impact

There is no downtime expected when following the mitigation. Also the mitigation can be performed anytime.

Not performing the mitigation is also no issue as long as another mean of access/control is present (e.g. username/password/2FA login). 

Last updated