Skip to main content

HTTPS

Clients outside the cluster reach Datastrato Enterprise over HTTPS through your ingress controller. Each host the chart publishes carries its own certificate, and the ingress controller terminates TLS with it. Any standard ingress controller works: nginx, Traefik, a cloud load balancer controller or the OpenShift router. No service mesh is needed.

HTTPS matters most where requests carry credentials: OAuth tokens, local passwords, and the storage credentials the Iceberg REST service vends to engines all travel in requests and responses.

Quick start​

The example publishes the server API and the Iceberg REST service on their own HTTPS hosts, with certificates from the cert-manager issuer set up in Issue certificates with cert-manager. The UI host is already on HTTPS from the install.

  1. Add the hosts to your values file, under the existing ingress block:

    my-values.yaml
    ingress:
    api:
    enabled: true
    host: "{api_host}"
    tls:
    - secretName: api-tls
    hosts: ["{api_host}"]
    iceberg:
    enabled: true
    host: "{iceberg_host}"
    tls:
    - secretName: iceberg-tls
    hosts: ["{iceberg_host}"]

    Both hosts share the UI's Ingress and its ingress.annotations, so they use the same issuer. With the Iceberg REST host published, the server gives the Gravitino connectors for Trino and Spark https://{iceberg_host}/iceberg as the service's address; see Connectors.

  2. Apply it by running the install command from Install again, then wait for the certificates:

    Wait for the certificates
    kubectl -n "$NAMESPACE" wait certificate/iceberg-tls certificate/api-tls \
    --for=condition=Ready --timeout=180s
  3. Check both hosts.

    Check the certificates and the services
    for h in {iceberg_host} {api_host}; do
    echo | openssl s_client -connect "$h:443" -servername "$h" 2>/dev/null \
    | openssl x509 -noout -issuer -subject
    done
    curl -sS -u "admin:$ADMIN_PASSWORD" "https://{iceberg_host}/iceberg/v1/config?warehouse={catalog}"
    curl -sS -u "admin:$ADMIN_PASSWORD" -H "Accept: application/vnd.gravitino.v1+json" \
    "https://{api_host}/api/system/iceberg-rest?metalake={metalake}"

    Each certificate names its host. The config call returns the catalog's defaults, and the last call returns https://{iceberg_host}/iceberg.

Published hosts​

HostClientsValues
UI and MCPBrowsers and AI agentsingress.hosts, ingress.tls
Server APIJava and Python clients, the Gravitino connectorsingress.api.host, ingress.api.tls
Iceberg RESTIceberg enginesingress.iceberg.host, ingress.iceberg.tls
Lance RESTLance clientsingress.lance.host, ingress.lance.tls
SCIMYour identity provideringress.scim.host, ingress.scim.tls

Every host shares one Ingress, which uses the cluster's default ingress class unless ingress.className is set. Give each host its own name. The chart rejects a server API, Iceberg REST, Lance REST or SCIM host equal to the UI host: the UI host passes /api through the UI pod for the browser's session, and the Iceberg REST and Lance REST services carry their catalog prefix in the URL path.

Certificates​

  • From cert-manager. Name an issuer in the Ingress annotations and a Secret name under tls; cert-manager creates the Secret and renews the certificate. See Issue certificates with cert-manager.

  • Your own. Create a TLS Secret from your certificate and key, and name it under tls without the issuer annotation:

    Create a TLS Secret from your own certificate
    kubectl -n "$NAMESPACE" create secret tls iceberg-tls --cert=iceberg.crt --key=iceberg.key

Every client must trust the certificate. A certificate from a public authority is trusted by browsers and by the JVMs and Python environments engines run in. A certificate from an internal authority has to be added to each client's trust store: the JVM trust store for Spark, Trino and Flink, and the system or REQUESTS_CA_BUNDLE bundle for PyIceberg. The SCIM host is called from your identity provider's cloud, so its certificate must come from a public authority.

Connectors​

The Gravitino connectors for Trino and Spark connect to the server API, then route Iceberg catalogs through the Iceberg REST service at the address the server gives them. When ingress.iceberg publishes the service, that address is the published host; set gravitino.icebergRest.advertisedUri only to give a different one. Point the connector at the HTTPS API host: gravitino.uri=https://{api_host} in the Trino catalog file, or spark.sql.gravitino.uri=https://{api_host} for Spark.

Inside the cluster​

TLS ends at the ingress controller. From there to the server, and between the workloads in the release, traffic runs on the cluster network, as does traffic from engines that run in the same cluster and call the Services directly. Where your policy requires encryption on those hops as well, run the release in a service mesh with mutual TLS.