Arnau
Arnau3mo ago

Zitadel TypeScript login: Issues Enabling HTTP/2 for gRPC with Zitadel in K8S (ALB Ingress)

Hi everyone, We’re onboarding the Zitadel TypeScript project in our Kubernetes setup (zitadel-typescript-login), but we’ve run into an issue with enabling HTTP/2 support while keeping compatibility with other services. Our Setup - Zitadel is deployed in an EKS cluster using the official Helm Chart. - We use an ALB ingress (via Helm) with the domain pattern *.staging.company.com. - Zitadel’s ingress is auth.staging.company.com. - Other company applications (e.g., foo-backend and foo-frontend deployed under foo.staging.company.com ingress) use Zitadel for authentication via OAuth2/OIDC (the backend using /oauth/v2/introspect and the frontend using oidc-client-ts with PKCE). - These applications interact with Zitadel using HTTP/1.1, which has been working fine. Problem - We onboarded the Zitadel TypeScript (Next.js) app under https://login.staging.company.com, which uses gRPC to communicate with Zitadel. - Initially, gRPC requests failed due to our ALB using HTTP/1.1. - We enabled HTTP/2 for Zitadel by adding: - ALB annotation: alb.ingress.kubernetes.io/backend-protocol-version: HTTP2 - Zitadel Ingress annotation: nginx.ingress.kubernetes.io/backend-protocol: "GRPC" This fixed Zitadel TypeScript’s gRPC calls but broke other applications: - foo-backend OAuth token introspection fails with 464 Incompatible protocol. - foo-frontend Cypress tests started failing (Cypress has known issues with HTTP/2). - Other company apps in other domains calling https://auth.staging.company.com/oidc/v1/userinfo also fail. Question How can we enable HTTP/2 for zitadel-typescript-login without breaking our existing applications that require HTTP/1.1? Any best practices or recommendations would be greatly appreciated. Thank you!
2 Replies
Arnau
ArnauOP3mo ago
For reference, our Zitadel HelmRelease with GRPC enabled looks like this:
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: zitadel
namespace: auth
spec:
interval: 1m
chart:
spec:
chart: zitadel
version: 8.12.0
sourceRef:
kind: HelmRepository
name: zitadel-charts
namespace: auth
valuesFrom:
- kind: Secret
name: zitadel-values
valuesKey: values.yml
values:
replicaCount: 1
initJob:
enabled: false
zitadel:
configmapConfig:
# not relevant properties ommited for breveity
ExternalSecure: true
ExternalDomain: auth.staging.company.com
ExternalPort: 443
TLS:
Enabled: false
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
hosts:
- host: auth.staging.company.com
paths:
- path: /
pathType: Prefix
apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
name: zitadel
namespace: auth
spec:
interval: 1m
chart:
spec:
chart: zitadel
version: 8.12.0
sourceRef:
kind: HelmRepository
name: zitadel-charts
namespace: auth
valuesFrom:
- kind: Secret
name: zitadel-values
valuesKey: values.yml
values:
replicaCount: 1
initJob:
enabled: false
zitadel:
configmapConfig:
# not relevant properties ommited for breveity
ExternalSecure: true
ExternalDomain: auth.staging.company.com
ExternalPort: 443
TLS:
Enabled: false
ingress:
enabled: true
className: nginx
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "GRPC"
hosts:
- host: auth.staging.company.com
paths:
- path: /
pathType: Prefix
For the record: we solved it creating two different target groups for our ALB, routing explicitly the Zitadel traffic towards the Zitadel K8S service with 2 listeners: 1 for HTTP/1 and another one for HTTP/2 on /zitadel* (gRPC) endpoints.
Gigi the Giraffe (Zitadel)
@Arnau, you cannot mark your own questions as solved.

Did you find this page helpful?