API Gateway
The API Gateway is a reverse proxy that exposes several platform services through one external hostname. Instead of separate hostnames per service (registry.<customer_istari_fqdn>, and — once you add the Identity Service — an equivalent for it), clients reach both through a single API host at path prefixes: /registry and /identity. The proxy matches a prefix, strips it, and forwards the request to the matching in-cluster service; a path under no known prefix gets 404.
This page covers the three supported configurations for a cluster running no service mesh, the common case. Every service in the chart — the registry service, the frontend, the Identity Service, MCP, and the API Gateway itself — renders a Kubernetes Ingress and an Istio VirtualService, gated by independent values. Ingress is not a fallback for clusters without Istio: it is the fully supported path, and every example on this page uses it. If you do run Istio, substitute the matching virtualService.* values for the ingress.* values shown below; the chart's values.yaml documents them in the same shape.
Two chart values define the surface:
| Value | Effect |
|---|---|
apiGateway.enabled | Deploys the API Gateway itself: its Deployment, Service, and (per your values) Ingress or VirtualService. |
common.mainFqdn | The platform's domain. From chart 6.0 the chart derives the API Gateway's public URL from it, https://api.<common.mainFqdn>, or uses the host in common.apiFqdnOverride, and always gives that URL to the registry service, the frontend, MCP and the Identity Service. |
Deploying the Identity Service follows the same split, one level down:
| Value | Effect |
|---|---|
identity.enabled | Deploys the Identity Service itself. |
identity.clientIntegration.enabled | Moves the registry service, the frontend, and MCP onto the Identity Service as their authentication authority. |
Both default to false, and the chart never derives one from the other — even in a release that sets identity.enabled: true, identity.clientIntegration.enabled stays false until you also set it. Moving clients over needs both values. Setting only identity.enabled deploys a working Identity Service that nothing yet authenticates against; setting only identity.clientIntegration.enabled is refused outright (see below).
Configuration that merely references the gateway URL — the address the chart derives from common.mainFqdn, the Identity Service's derived BASE_URL — is just configuration, and can be set before the gateway serves any traffic. What must actually be live and verified before identity.clientIntegration.enabled flips is the gateway itself, because from that moment every login round trip travels through it. Verify with the Configuration 2 check (curl https://api.<customer_istari_fqdn>/registry/api/v2/health/readiness returns 200) before enabling client integration or restarting consumers.
The gateway and the identity toggle interact in one place worth understanding before you touch either: the chart emits the identity-enabled environment variable to the registry service, the frontend, and MCP together, and only when identity.clientIntegration.enabled is true; from chart 6.0 the gateway URL always resolves, from common.mainFqdn. This is not an arbitrary gate. The chart's own validation fails the Helm render if identity.clientIntegration.enabled is true while no gateway URL resolves, and independently of that guard, the registry service, the frontend, and MCP each treat identity-enabled-without-a-gateway-URL as a fatal error — at startup for the registry service and MCP, at config load for the frontend. There is no supported path that half-applies this change.
Finally: MCP is a client of the gateway, not a service it serves. It reaches the registry service through <base>/registry the same way the frontend does, and stays reachable at its own hostname (mcp.<customer_istari_fqdn>, per Istari Platform Installation) — the API Gateway has no /mcp prefix. https://api.<customer_istari_fqdn>/mcp returning 404 is correct behavior, not a misconfigured route.
Configuration 1: Neither Enabled
From chart 6.0 this configuration is not available: the chart always points the registry service, the frontend and MCP at https://api.<common.mainFqdn>, so the API Gateway must be deployed (Configuration 2 or 3). The Identity Service requires it in any case. The rest of this section describes chart 5.x.
The baseline. No prerequisites beyond your existing installation, and no values to set — apiGateway.enabled: false and identity.enabled: false are already the chart defaults. Upgrading to chart version 5.0.0 with an otherwise unchanged values file is a version bump and nothing else: no new resources render, no environment variables change, and every existing hostname keeps working exactly as before.
Order of operations: helm upgrade to chart version 5.0.0.
Verification: kubectl get pods shows no new workloads (no api-gateway or identity pods); the registry service and frontend continue answering at their existing hostnames.
Rollback: helm rollback <release> <previous-revision>.
Reference: example_values/01-baseline-no-router-no-identity.yaml.
Configuration 2: Gateway Only
Adds the API Gateway in front of the registry service, with authentication unchanged. Clients reach the registry service through <api-host>/registry instead of registry.<customer_istari_fqdn> directly; they still authenticate against Zitadel exactly as before. The API Gateway and the Identity Service are independent — this configuration does not require the Identity Service, and deploying it does not enable the Identity Service.
Prerequisites
- An Ingress controller (nginx, ALB/EKS Auto Mode, GCE, Traefik, or similar) watching the IngressClass you plan to use. The examples below assume no service mesh; on Istio, substitute the matching
virtualService.*values — see the note above. - A DNS record for your chosen API hostname (for example
api.<customer_istari_fqdn>), pointed at the Ingress controller's load balancer — the same way you already route<customer_istari_fqdn>andregistry.<customer_istari_fqdn>. - A TLS Secret for that hostname (
kubectl create secret tls ..., or one issued by cert-manager). TLS terminates at the Ingress controller; the API Gateway itself serves plain HTTP behind it.
Values to set
common:
mainFqdn: "<customer_istari_fqdn>" # the gateway's host is api.<customer_istari_fqdn>
apiGateway:
enabled: true
ingress:
enabled: true
className: "nginx" # match your controller's IngressClass
hosts:
- host: api.<customer_istari_fqdn>
paths:
- path: /
pathType: Prefix
tls:
- hosts:
- api.<customer_istari_fqdn>
secretName: api-<customer_istari_fqdn>-tls
From chart 6.0 the gateway's URL is not a value you set: the chart derives https://api.<common.mainFqdn>, or uses common.apiFqdnOverride when you need a different host. Use that same host in apiGateway.ingress.hosts and its TLS entry.
Order of operations
-
Create the TLS Secret and DNS record for the API hostname.
-
Set the values above and run
helm upgrade. -
Restart the registry service and frontend Deployments. Neither carries a config-checksum annotation, so a
helm upgradethat changes only the gateway values does not roll them on its own — they keep running with the old environment until you restart them explicitly:kubectl rollout restart deployment/istari-fileservice deployment/istari-frontendkubectl rollout status deployment/istari-fileservice deployment/istari-frontend(Add
deployment/istari-mcpto both commands if MCP is deployed.)
Verification
curl -fsS https://api.<customer_istari_fqdn>/registry/api/v2/health/readiness
should return 200. Confirm the frontend still logs in exactly as before — this configuration changes only where registry traffic travels, not how anyone authenticates. https://api.<customer_istari_fqdn>/identity returns 502 until the Identity Service is deployed (Configuration 3) — the route always exists, but nothing backs it yet; that is expected, not an API Gateway misconfiguration.
Rollback
From chart 6.0, roll back with helm rollback <release> <previous-revision>. Setting apiGateway.enabled: false alone is not a rollback: the registry service and the frontend keep the derived gateway URL and would lose their route to the registry.
If you set VITE_ISTARI_DIGITAL_API_URL in the frontend Secret yourself — or ISTARI_DIGITAL_API_URL in the registry Secret — remove that key and re-apply the Secret as part of the rollback. A key you set in your Secret overrides the chart's value, so a stale value survives the rollback.
Reference: example_values/02-router-only.yaml.
Configuration 3: Gateway and Identity
Adds the Identity Service behind the same gateway and moves the registry service, the frontend, and MCP onto it. This configuration only covers what the gateway changes — read Identity Service: Install and Configure for deploying the Identity Service itself and generating every credential it needs, and Identity Service: Clients & Tenants for how the registry service, the frontend, and MCP are registered with it, and for tenants. This page does not restate either.
Prerequisites
- Configuration 2 already applied (or applied in the same release): the API Gateway deployed (
apiGateway.enabled: true) and reachable athttps://api.<customer_istari_fqdn>. - The Identity Service installed and configured per Install and Configure, including its Secret (
identity.secretName) populated with the signing key, database URL, and the upstream identity provider credentials (for the default, Istari-managed Zitadel, delivered by the Zitadel Configurator). - The platform clients' credentials in place: generated by the chart's provisioner (
provisioner.enabled: true), or supplied by you without it. See Clients & Tenants.
Values to set
apiGateway:
enabled: true
ingress:
# ... same as Configuration 2
identity:
enabled: true
clientIntegration:
enabled: true
secretName: "istari-identity"
With the gateway in place, this pair of values is what actually moves clients over — everything else in this configuration (the Identity Service Deployment, its database migrations, the provisioner and the Zitadel import) is covered by the two linked pages. Set both together: identity.clientIntegration.enabled with identity.enabled left false deploys nothing to authenticate against.
With the gateway in place, the Identity Service needs no Ingress or DNS entry of its own: the API Gateway already serves it at <api-host>/identity, exactly as Scenario 10 of the Istari Platform Installation describes. The chart also has the Identity Service accept RFC 7523 client assertions addressed to that gateway-prefixed audience (<api-host>/identity) in addition to its canonical issuer — automatic, and not something you configure.
Order of operations
-
Complete the Identity Service prerequisites (registration with the upstream identity provider, keys, secret). Optional but recommended for first installs: apply with
identity.enabled: trueandidentity.clientIntegration.enabledstillfalse, and verify the service directly — isolating failures to one side of the switch. Setting both values together in one upgrade (as Scenario 10 does) is equally supported. -
Turn on the provisioner (
provisioner.enabled: true), or supply the platform clients' credentials yourself. -
Set
identity.clientIntegration.enabled: trueand runhelm upgrade. -
Restart the registry service, frontend, and (if deployed) MCP Deployments — the same restart caveat as Configuration 2 applies to this toggle as well:
kubectl rollout restart deployment/istari-fileservice deployment/istari-frontend deployment/istari-mcpkubectl rollout status deployment/istari-fileservice deployment/istari-frontend deployment/istari-mcp
Verification
Follow Clients & Tenants: Verify a Registration for a token-level check, then confirm the frontend login flow end to end (it now drives the full /oauth2/authorize → the upstream identity provider → /callback round trip through the gateway). Confirm https://api.<customer_istari_fqdn>/mcp still returns 404 — MCP consumes the gateway to reach the registry service and the Identity Service, but the API Gateway never serves MCP itself, so this is expected.
Rollback
Two independent steps, matching the two toggles:
- Move clients back off the Identity Service, keeping it deployed: set
identity.clientIntegration.enabled: false,helm upgrade, restart the same Deployments as above. The registry service, the frontend, and MCP fall back to Zitadel directly — their Zitadel configuration was never removed, only superseded while the toggle was on. Nothing in the Identity Service's database (tenants, registered clients) is affected, so re-enabling later needs no re-registration. - Remove the Identity Service entirely: additionally set
identity.enabled: false.
Reference: example_values/03-router-and-identity.yaml.