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.

@qrkourier Hi, I'm installing BrowZer and planning to upgrade the existing cluster to implement it. I have a quick question: does the IDP need to be publicly accessible?

In my current architecture, even Keycloak is hosted internally and accessed via an edge tunnel. For enabling BrowZer, does Keycloak need to be publicly accessible, or can it remain accessible only internally?

No, there's no arbitrary requirement that it's public. Still, "public" is a way to express that the identity provider must be reachable by the devices participating in the authentication flow, including your Ziti identities and the Ziti controller.

OK So IDP and Ziti-controller has to be reached from internet, Identity has to be embedded with browzer bootstrap right?

With BrowZer, you'll have additional Ziti entities with special configuration in your Ziti network to enable OIDC. Here's an overview.

The Ziti identities for each web app user that will dial via BrowZer are provisioned in advance with an external ID property matching a claim from the external-jwt-signer you create for your IdP. When a user visits the BrowZer Bootstrapper URL, the ZBR is downloaded and run in their browser triggering a redirect to the identity provider. After authN, they're returned to the bootstrapper's address and a runtime session is created with the Ziti controller and router(s) for the Ziti service they're using, and subsequent web requests are handled within that secure session.

Here's the README for BrowZer Bootstrapper. This covers the rationale and configuration specifics, in case you need to dive deeper than the Helm chart's README.

@qrkourier Thanks, Currently im using
CHART APP VERSION
ziti-controller-1.0.16 1.1.9

When i added this values.yaml i didnt see any new alt server certs or issuer is created?
Do i need to upgrade the chart to enable browzer?

/tmp/controller-values.yml

trustDomain: ziti-ctrl.xx.com
ctrlPlane:
advertisedHost: ziti-ctrl.xx.com
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.xx.com
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: ziti-browzer.xx.com # 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: "true"
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

helm upgrade --install --namespace ziti-console --values controller-rd.yaml ziti-controller-rd openziti/ziti-controller

Auto-provisioning alt server certs with simplified Helm inputs was added in Release ziti-controller-1.1.0 · openziti/helm-charts · GitHub.

While planning your upgrade, ensure you have a database backup if rollback ability is important because older ziti will be unable to load an upgraded database.

Oh older ziti identity wont load after upgrade?