> ## Documentation Index
> Fetch the complete documentation index at: https://ngrok.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Ingress to apps secured by Microsoft Entra ID in Kubernetes

> Use ngrok to add ingress to Kubernetes apps and authenticate users with Microsoft Entra ID.

This guide explains how to add ingress to any app running in Kubernetes and restrict access to users authorized through Microsoft Entra ID (formerly Azure Active Directory), using the ngrok Kubernetes Operator.
It walks you through (optionally) creating a Kubernetes cluster and example deployment, installing the Operator to expose your app through ngrok, and using the ngrok Kubernetes Operator's Traffic Policy to enable SAML with Microsoft Entra ID as your identity provider for single sign-on.

The [ngrok Kubernetes Operator](/k8s) is ngrok's official controller for adding secure public ingress and middleware execution to your Kubernetes apps with ngrok.
Microsoft Entra ID is an identity and access management platform that helps administrators and DevOps engineers safeguard their organization's multicloud environment with strong authentication and unified identity management.
The Operator and Microsoft Entra ID integrate so you can route public traffic to an app on a Kubernetes cluster and restrict access to users you authorize through Microsoft Entra ID.

## What you'll need

* An ngrok account.
* A Microsoft Azure account with access to an existing Microsoft Entra ID tenant or the ability to create a new tenant with a Microsoft Entra ID P1 or P2 license.
* A Kubernetes cluster (local or in a public cloud) with an app you want to make publicly accessible to specific users.
* kubectl and Helm 3.0.0+ installed on your local workstation.
* The [ngrok Kubernetes Operator](/k8s/) installed on your cluster.
* A reserved domain from the ngrok [dashboard](https://dashboard.ngrok.com/domains) or [API](/api-reference/reserveddomains/list); this guide refers to it as `<NGROK_DOMAIN>`.

## 1. Create a cluster and deploy an example app

This guide requires an app on a Kubernetes cluster (local or in a public cloud) to provide an endpoint for ngrok's secure tunnel.
For demonstration, this guide creates a local cluster with minikube and deploys the Online Boutique example.

If you already have a cluster and app, skip to [2. Add the ngrok Kubernetes Operator](#2-add-the-ngrok-kubernetes-operator).

* Download the `GoogleCloudPlatform/microservices-demo` project to your local workstation and navigate into the new directory.

  ```bash theme={null}
  git clone https://github.com/GoogleCloudPlatform/microservices-demo
  cd microservices-demo
  ```

* Create a new minikube cluster.

  ```bash theme={null}
  minikube start -p online-boutique
  ```

* Apply the manifests for the Online Boutique.

  ```bash theme={null}
  kubectl apply -f ./release/kubernetes-manifests.yaml
  ```

## 2. Add the ngrok Kubernetes Operator

Configure and deploy the [ngrok Kubernetes Operator](https://github.com/ngrok/ngrok-operator) to expose your app to the public internet through ngrok.

* Add the ngrok Helm repository if you haven't already.

  ```bash theme={null}
  helm repo add ngrok https://charts.ngrok.com
  ```

* Create a static ngrok subdomain for ingress if you don't have one already.
  Go to the [**Domains** section](https://dashboard.ngrok.com/domains) of the ngrok dashboard and click **Create Domain** or **New Domain**.
  This static subdomain will be your `NGROK_DOMAIN` for the remainder of this guide.
  Creating a subdomain on the ngrok network provides a public route to accept HTTP, HTTPS, and TLS traffic.

* Set up the `AUTHTOKEN` and `API_KEY` exports so Helm can install the Operator using your ngrok credentials.
  Find your authtoken under [**Your Authtoken**](https://dashboard.ngrok.com/get-started/your-authtoken) in the [ngrok dashboard](https://dashboard.ngrok.com/).
  To create a new API key, go to the [**API Keys** section](https://dashboard.ngrok.com/api-keys) of the ngrok dashboard, click **New API Key**, set the description or owner, and click **Add API Key**.
  Copy the API key token from the modal before closing it; the dashboard won't show the token again.

  ```bash theme={null}
  export NGROK_AUTHTOKEN=[YOUR-AUTHTOKEN]
  export NGROK_API_KEY=[YOUR-API-KEY]
  ```

* Install the ngrok Kubernetes Operator with Helm.

  ```bash theme={null}
  helm install ngrok-ingress-controller ngrok/kubernetes-ingress-controller \
    --namespace ngrok-ingress-controller \
    --create-namespace \
    --set credentials.apiKey=$NGROK_API_KEY \
    --set credentials.authtoken=$NGROK_AUTHTOKEN
  ```

* Verify the health of your new Operator pod.

  ```bash theme={null}
  kubectl get pods -l 'app.kubernetes.io/name=kubernetes-ingress-controller'

  NAME                                                              READY   STATUS    RESTARTS   AGE
  ngrok-ingress-controller-kubernetes-ingress-controller-man2fg5p   1/1     Running   0          2m23s
  ```

* Create a new `boutique-ingress.yaml` file that defines how the ngrok Kubernetes Operator routes traffic on your `NGROK_DOMAIN` to your Online Boutique app.

  <Tip>
    Edit line `9` of the manifest below (the `NGROK_DOMAIN` variable) with the ngrok subdomain you created (for example, `one-two-three.ngrok.app`).
    If you're adding the Operator to a different deployment, change `metadata.name`, `service.name`, and `service.port.number` to match your app.
    See the [controller docs](https://github.com/ngrok/ngrok-operator/tree/main/docs) for `spec` settings and common overrides.
  </Tip>

  ```yaml theme={null}
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: boutique-ingress
    namespace: default
  spec:
    ingressClassName: ngrok
    rules:
      - host: NGROK_DOMAIN
        http:
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: frontend
                  port:
                    number: 80
  ```

* Apply the `boutique-ingress.yaml` manifest you just created.

  ```bash theme={null}
  kubectl apply -f boutique-ingress.yaml
  ```

  Give your cluster a few moments to launch the necessary resources and for ngrok to pick up the new tunnel.

  <Tip>
    If you see an error when applying the manifest, double-check that you've updated the `NGROK_DOMAIN` value and re-apply.
  </Tip>

* Access your app (ingress now handled by ngrok) by navigating to your ngrok domain (for example, `https://one-two-three.ngrok.app`) in your browser.

## 3. Enable SAML with a Traffic Policy

<Warning>
  The SAML Traffic Policy action is currently in [developer preview](/traffic-policy/actions/saml/). [Request access](https://dashboard.ngrok.com/developer-preview) to configure SAML via Traffic Policy.
</Warning>

Your Kubernetes-based app is now publicly accessible through ngrok.
To restrict access to authorized users with Microsoft Entra ID credentials, create a `NgrokTrafficPolicy` custom resource with the SAML action and apply it to your Ingress.

* Create a file named `saml-policy.yaml` with the following content:

  ```yaml theme={null}
  apiVersion: ngrok.k8s.ngrok.com/v1alpha1
  kind: NgrokTrafficPolicy
  metadata:
    name: saml
    namespace: default
  spec:
    policy:
      on_http_request:
        - actions:
            - type: saml
              config:
                idp_metadata: 'YOUR_IDP_METADATA_XML'
  ```

* Apply the Traffic Policy CR:

  ```bash theme={null}
  kubectl apply -f saml-policy.yaml
  ```

* Update your `boutique-ingress.yaml` to reference this policy with an annotation:

  ```yaml theme={null}
  apiVersion: networking.k8s.io/v1
  kind: Ingress
  metadata:
    name: boutique-ingress
    namespace: default
    annotations:
      k8s.ngrok.com/traffic-policy: saml
  spec:
    ingressClassName: ngrok
    rules:
      - host: NGROK_DOMAIN
        http:
          paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: frontend
                  port:
                    number: 80
  ```

* Re-apply the Ingress manifest:

  ```bash theme={null}
  kubectl apply -f boutique-ingress.yaml
  ```

* Refer to the [SAML action documentation](/traffic-policy/actions/saml/) to retrieve your SP Entity ID and ACS URL values, which you'll need in the next step.

## 4. Create an enterprise app in Microsoft Entra ID

With a SAML Traffic Policy applied to your Ingress, configure Microsoft Entra ID to operate as your identity provider (IdP).

* Open your Microsoft Entra ID tenant in the Azure console.

* Click **Enterprise applications** in the left-hand sidebar, then **+ New application**, then **+ Create your own application**.
  Give your app a name (for example, `online-boutique`) and select **Integrate any other application you don't find in the gallery (Non-gallery)**.

* Click **Create** to create your enterprise app; you'll be taken to its Overview dashboard.

* To give specific users or groups access to your app, click **Assign users and groups** and follow the steps, then go back to **Overview**.

* Click **Set up single sign on** so users can sign in with their Microsoft Entra credentials, then choose **SAML** as the single sign-on protocol.

* Click **Edit** in the **Basic SAML Configuration** box.
  Refer to the [SAML action documentation](/traffic-policy/actions/saml/) to retrieve your SP Entity ID and ACS URL, then copy them into the **Identifier (Entity ID)** and **Reply URL (Assertion Consumer Service URL)** fields respectively.
  Click **Save** before closing the modal.

* In the **SAML Certificates** box, download the **Federation Metadata XML**.

## 5. Update the Traffic Policy with the IdP metadata

With Microsoft Entra ID configured as your identity provider, update your Traffic Policy with the real IdP metadata.

* Open your `saml-policy.yaml` and replace `YOUR_IDP_METADATA_XML` with the contents of the Federation Metadata XML file you downloaded.

* Re-apply the updated Traffic Policy:

  ```bash theme={null}
  kubectl apply -f saml-policy.yaml
  ```

## 6. Test authorization to your app using Microsoft Entra ID

You've finished integrating the ngrok Kubernetes Operator and Microsoft Entra ID.
Your app (the Online Boutique or a custom deployment) is now publicly accessible only to users authorized with their Microsoft Entra ID credentials.

* Open an incognito or private browser window (or a different browser) and go to your `NGROK_DOMAIN`.
  You should see a single sign-on screen from Microsoft.

* Enter credentials for a Microsoft account you assigned to your enterprise application in Microsoft Entra ID in [step 4](#4-create-an-enterprise-app-in-microsoft-entra-id).

  Behind the scenes, ngrok requests your identity provider, Microsoft Entra ID, for authentication.
  Once you sign in, or are already logged in, Microsoft Entra ID then returns a SAML assertion to ngrok, telling ngrok your authentication is confirmed and you have authorization to access the app.

  Microsoft Entra ID will then redirect you back to your app.

## What's next?

You've now integrated the ngrok Kubernetes Operator with Microsoft Entra ID to restrict access to your app to only authenticated users.
With ngrok operating as middleware, handling both ingress to your Kubernetes cluster and the handshake with Microsoft Entra ID as an identity provider, you can deploy and secure new apps in a multi-cloud environment using your existing Microsoft/Azure identity and access management settings.

From an end user perspective, they only need to sign in once, using their Microsoft credentials, to authenticate themselves and access any number of applications you manage using Microsoft Entra ID.

From here, you have a few options:

### Clean up

If you created a local cluster with Minikube for the Online Boutique demo app, delete the cluster:

```bash theme={null}
minikube delete -p online-boutique
```

ngrok will delete your endpoint automatically.

To restore your previous authorization settings, open your Microsoft Entra ID tenant and delete your enterprise application.

### Extend your ngrok Kubernetes Operator and Microsoft Entra ID integration

ngrok's [Traffic Policy system](/traffic-policy/) can secure multiple apps with single sign-on.

You can configure [name-based virtual hosting](https://github.com/ngrok/ngrok-operator/blob/main/docs/user-guide/ingress-to-edge-relationship.md#name-based-virtual-hosting) and use [`NgrokTrafficPolicy` resources](/k8s/guides/using-ingresses/#using-ngroktrafficpolicy-with-ingress) to secure multiple apps with single sign-on.

[Custom domains](https://github.com/ngrok/ngrok-operator/blob/main/docs/user-guide/custom-domain.md) and a [circuit breaker](/traffic-policy/actions/circuit-breaker/) are good next steps for production.

See the [ngrok Kubernetes Operator GitHub repository](https://github.com/ngrok/ngrok-operator) and [project documentation](https://github.com/ngrok/ngrok-operator/tree/main/docs) for more details.
