How to install ziti Browzer in kubernetes?

How can I install Ziti BrowZer on Kubernetes? I couldn't find any documentation for setting up BrowZer on Kubernetes. Can someone assist me with the setup?

Here's my scenario: I need to add Keycloak authentication in front of my application without making significant changes to the app itself.

I need assistance with:

  • Installing BrowZer and verifying it through the UI.
  • Configuring Keycloak OpenID authentication in the Ziti console.
  • Enabling authentication for specific services mapped in the Ziti console.

Are these configurations possible with Ziti?

Another community member contributed a BrowZer chart and I'm finishing up the tweaks and acceptance testing in BrowZer Bootstrapper by qrkourier · Pull Request #240 · openziti/helm-charts · GitHub

hi thanks @qrkourier Let me take a look, I have a question on browzer, is it an independent deployment of controller and router? or do i need update something controller and router to enable browzer bootstrap?

Please check the upgrade topic and give me suggestion to enable browzer while upgrade controller and router?

The controller and router charts do not yet support BrowZer. I'm working on those requirements in tandem with the first BrowZer chart release and so they'll be tested at the same time in the near future.

The future BrowZer bootstrapper chart will deploy only the BrowZer bootstrapper: GitHub - openziti/ziti-browzer-bootstrapper

It is a web server that facilitates OpenID Connect and bootstrapping (delivering a configured runtime) with the Ziti BrowZer Runtime (ZBR) as Javascript to the authenticated web browser.

To use the BrowZer bootstrapper, a Ziti controller and router with special configuration are required. Any controller and router can be configured to work with BrowZer, so you do not need an independent instance of Ziti to use BrowZer. The main limitation in this case is lack of support for special BrowZer configuration in the controller and router charts that I mentioned.

Got it. So, if I need multiple BrowZer bootstrappers, do I have to deploy each one individually in the Ziti controller, or can I enable BrowZer once in the controller and deploy a separate bootstrapper for each SaaS BrowZer setup?

I have a use case where access to a SaaS product must be granted only after authentication via OIDC with Keycloak.

  • I’m considering using BrowZer to redirect users to the SaaS URL after authenticating with our users through Keycloak.
  • I’m also thinking about using SAML in Keycloak, allowing BrowZer to initiate authentication via SAML with the SaaS, and then redirect users to the SaaS after successful authentication.

In essence, I’m exploring how to use BrowZer to enable zero trust access to any SaaS.

You will need at least one BrowZer bootstrapper. You may wish to have two for redundancy. You may configure a single bootstrapper instance to handle many Ziti services. Each Ziti service is a "target" with a "vhost." The vhost is the address your web app users will enter in the regular web browser's address bar. Each target may have a unique OIDC tenant and client ID.

You may wish to configure a wildcard DNS record like "*.browzer.example.com" for the public IP where you are hosting the bootstrapper. Then, you can invent vhosts in this zone, e.g. "app1.browzer.example.com" without additional DNS records.

{
  "targetArray": [
    {
      "vhost": "${ZITI_BROWZER_VHOST}",
      "service": "${ZITI_BROWZER_SERVICE}",
      "path": "/",
      "scheme": "http",
      "idp_issuer_base_url": "${ZITI_BROWZER_OIDC_URL}",
      "idp_client_id": "${ZITI_BROWZER_CLIENT_ID}"
    }
  ]
}

The Client ID would be different for each redirection URL, correct? For example, I could have one entry point for the vhost and service like:

vhost --> *.browzer.example.com "service": "example_service", "sample_service"

But the Client ID would vary, right? Since I'm using Keycloak, I assume that each redirection to a SaaS endpoint would need its own Client ID, such as:

clientID A --> app.example.com clientID B --> app.sample.com

Is my understanding correct?

You can decide which is best for your needs. One OIDC IdP may be configured to allow multiple callback, login, logout, etc. HTTP URLs for various vhosts.

Alternatively, you may configure a separate IdP for each vhost.

Here's the Keycloak guide: Keycloak for OpenZiti BrowZer

@qrkourier Hi When can i start testing Browzer deployment? I would like to try browzer for internet faced applications.

Very soon. I released the prerequisite router features last week and will release the controller update and the new browzer chart this week, hopefully, today.

The initial release of OpenZiti BrowZer Bootstrapper for Kubernetes is available from our Helm Charts repository.

Doc: helm-charts/charts/ziti-browzer-bootstrapper at main · openziti/helm-charts · GitHub

@qrkourier Hi, im planning to install browzer, before updating just wanted to confirm will it break exitisng identies or anything.
To make browzer to work i need to update in Controller deployment and Router Deployment.
by adding alt server cert will it impact anyof the exiostign identities?
this is my current controller file


# /tmp/controller-values.yml
trustDomain: ziti-ctrl.aly.ai
ctrlPlane:
    advertisedHost: ziti-ctrl.xxx.xxx
    advertisedPort: 443
    service:
        type: ClusterIP
    ingress:
        enabled: true
        ingressClassName: nginx
        annotations:
            kubernetes.io/ingress.allow-http: "false"
            nginx.ingress.kubernetes.io/ssl-passthrough: "true"
            nginx.ingress.kubernetes.io/secure-backends: "true"
clientApi:
    advertisedHost: ziti-controller.xxx.xxx
    advertisedPort: 443
    service:
        type: ClusterIP
    ingress:
        enabled: true
        ingressClassName: nginx
        annotations:
            kubernetes.io/ingress.allow-http: "false"
            nginx.ingress.kubernetes.io/ssl-passthrough: "true"
            nginx.ingress.kubernetes.io/secure-backends: "true"

to


# /tmp/controller-values.yml
trustDomain: ziti-ctrl.aly.ai
ctrlPlane:
    advertisedHost: ziti-ctrl.xxx.xxx
    advertisedPort: 443
    service:
        type: ClusterIP
    ingress:
        enabled: true
        ingressClassName: nginx
        annotations:
            kubernetes.io/ingress.allow-http: "false"
            nginx.ingress.kubernetes.io/ssl-passthrough: "true"
            nginx.ingress.kubernetes.io/secure-backends: "true"
clientApi:
    advertisedHost: ziti-controller.xxx.xxx
    advertisedPort: 443
    service:
        type: ClusterIP
    ingress:
        enabled: true
        ingressClassName: nginx
        annotations:
            kubernetes.io/ingress.allow-http: "false"
            nginx.ingress.kubernetes.io/ssl-passthrough: "true"
            nginx.ingress.kubernetes.io/secure-backends: "true"
  altIngress:
        enabled: true
        ingressClassName: nginx
        advertisedHost: edge.xxx.xxx  # this must be different from clientApi.advertisedHost and must match one of the dnsNames in the altServerCert
        annotations:
            kubernetes.io/ingress.allow-http: "false"
            nginx.ingress.kubernetes.io/ssl-passthrough: "tru
webBindingPki:
    enabled: true
    altServerCerts:
        - mode: certManager
            secretName: my-alt-server-cert
            dnsNames:
                - "{{ .Values.clientApi.altIngress.advertisedHost }}"
            issuerRef:
                group: cert-manager.io
                kind: ClusterIssuer
                name: cloudflare-dns01-issuer
            mountPath: /etc/ziti/alt-server-cert

just adding altIngress and webBindingPki is it fine?
altIngress advertisedHost should not be same as client api correct?
Same way for router. adding below should be needed right?

additionalListeners:
    - name: router1-edge-wss
      protocol: wss
      containerPort: 3023                           # must be unique
      advertisedHost: router1-wss.ziti.example.com  # must be distinct from edge.advertisedHost
      advertisedPort: 443
      addHostToSan: false                           # must be false to avoid colliding DNS SANs between listeners
      service:
        enabled: true
        type: ClusterIP
      ingress:
        enabled: true
        annotations:
          kubernetes.io/ingress.allow-http: "false"
          nginx.ingress.kubernetes.io/ssl-passthrough: "true"
        ingressClassName: nginx

identity:
  altServerCerts:
    - name: alt-server-cert-1
      mode: certManager
      secretName: ziti-router1-alt-server-certs1
      additionalListenerName: router1-edge-wss
      mountPath: /etc/ziti/alt-server-cert-1
      issuerRef:
        group: cert-manager.io
        kind: ClusterIssuer
        name: cloudflare-dns01-issuer-staging

Just to making sure existign stuff should not break.

Correct. The alternative certs and additional router edge listener are additive.

Your routers will continue to connect to the ctrlPlane advertisedHost, and endpoint (dialing clients and binding hosts) identities will continue using the clientApi advertisedHost.