Enabling SAML in a Kubernetes installation

Enabling the SAML integration requires:

  1. A Kubernetes secret containing a PKCS12 keystore for the authentication server to use. This can be the same deephaven-tls secret used by Envoy. Note that the SAML ACS is hosted behind Envoy, so the certificate from the PKCS12 keystore is only seen by Envoy itself -- the TLS connection from clients will terminate at Envoy, as with the UI.
  2. Container images built to contain the SAML plugin jars.
  3. Updating the Deephaven configuration to use SAML.

Steps 1 & 2 must be performed manually. Step 3 is handled by setting the appropriate Helm values.

Creating PKCS12 Keystore

The PKCS12 keystore and its base64-encoded passphrase must be loaded from Kubernetes secrets.

First, create a secret containing the keystore passphrase. In this case, the secret will include both the plaintext and base64-encoded passphrase. The authentication server requires the base64-encoded version, but the plaintext version can be used (e.g., by cert-manager) when creating the keystore.

The example below adds a keystore passphrase to a Kubernetes secret.

TEMP_DIR=$(mktemp -d)
KEYSTORE_PW_FILE="$TEMP_DIR/keystore-password"
echo -n "some-password" > "$KEYSTORE_PW_FILE"
cat "$KEYSTORE_PW_FILE" | base64 > "$KEYSTORE_PW_FILE.base64"
# Create a k8s secret with the password from the file.
# The password will be stored under the key "passphrase" in the secret (and can be mounted as a file in a container).
kubectl create secret generic saml-pkcs12-pw-secret --from-file=passphrase="$KEYSTORE_PW_FILE" --from-file=passphrase_base64="$KEYSTORE_PW_FILE.base64" --dry-run=server
rm -v "$KEYSTORE_PW_FILE" "$KEYSTORE_PW_FILE.base64"

Next, add a secret containing the PKCS12 keystore. If using cert-manager, this can be done automatically by adding YAML for a certificate from cert-manager. Below is an example that requests a certificate from cert-manager called cert-dhe-k8s-test. The actual certificate files (PEM-encoded tls.key and tls.crt files) will be stored in the deephaven-tls secret. A PKCS12 keystore will also be created, which will take its passphrase from the passphrase field of the saml-pkcs12-pw-secret created above. This certificate has multiple dnsNames so that it can be used by both Envoy (for connections to the DH UI) and the authentication server (for the SAML ACS).

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: cert-dhe-k8s-test
spec:
  secretName: deephaven-tls
  privateKey:
    algorithm: ECDSA
    size: 256
  issuerRef:
    name: letsencrypt-prod
    kind: ClusterIssuer
  dnsNames:
    - 'dhe-k8s-test.devrel.deephaven.io'
  keystores:
    pkcs12:
      create: true
      passwordSecretRef: # Password used to encrypt the keystore
        key: passphrase
        name: saml-pkcs12-pw-secret

The certificate YAML can be added with kubectl apply:

kubectl apply -f deephaven-tls-cert.yaml

Once the certificate has been generated, the deephaven-tls secret will contain tls.crt, tls.key and keystore.p12 files:

> kubectl describe secrets/deephaven-tls
Type:  kubernetes.io/tls

Data
====
keystore.p12:  4520 bytes
tls.crt:       5473 bytes
tls.key:       227 bytes

Alternatively, you can manually create a Kubernetes secret containing an appropriate keystore.p12 file.

Building images with the SAML plugin

To include the plugin jars in the image, put the plugin tar file in the deephaven_base image directory and update the Dockerfile to include the plugin:

COPY "$saml_plugin_tar" "/tmp/plugins/"
ARG saml_plugin_tar
RUN cd /tmp/plugins && \
    tar -vxf "$saml_plugin_tar" && \
    cp -v */*.jar /usr/illumon/latest/java_lib

Be sure to set the saml_plugin_tar argument in your docker build/podman build command, e.g.:

---build-arg "saml_plugin_tar=SamlAuth-1.4.0-Manual.tgz"

SAML Helm values

The following Helm values are used to configure SAML:

ValueDefaultDescription
saml.providerNameSAMLOptional. Provider name to display in the UI (e.g., "Okta").
saml.authServerSecretNameN/AName of the Kubernetes secret that contains the PKCS12 keystore for the ACS.
saml.pkcsPassphraseSecretNameN/AName of the Kubernetes secret containing the passphrase for the PKCS12 keystore.
saml.idpEntityIdN/ASAML IdP's entity ID.
saml.idpSsoUrlN/ASAML IdP's URL.
saml.idpCertN/ASAML IdP's certificate.

To enable SAML in the config, set the following values when installing the Helm release:

saml:
  # Provider name displayed in UI:
  providerName: 'Okta'

  # Name of secret with a 'keystore.p12' file with a key/cert for saml.authServerHostname:
  authServerSecretName: 'deephaven-tls'

  # Name of secret with password for the keystore.p12 file (under the 'passphrase' key of the secret):
  pkcsPassphraseSecretName: 'saml-pkcs12-pw-secret'

  # Parameters from IdP:
  idpEntityId: 'http://www.okta.com/exk85yotnys6vgNdm5d7'
  idpSsoUrl: 'https://dev-62524573.okta.com/app/dev-62524573_rbdhtest_1/exk85yotnys6vgNdm5d7/sso/saml'
  ## IdP certificate (remember toe escape newlines):
  idpCert: "-----BEGIN CERTIFICATE-----\\nMIIDqDCC...TCnXJJ\\nzO21KV7oTpH8pqUAUaj6o6BapmQcTnCln6V6pQ==\\n-----END CERTIFICATE-----"