|
| 1 | +--- |
| 2 | +title: Azure API Management self-hosted gateway - Azure AD authentication |
| 3 | +description: Enable the Azure API Management self-hosted gateway to authenticate with its associated cloud-based API Management instance using Azure Active Directory authentication. |
| 4 | +services: api-management |
| 5 | +author: dlepow |
| 6 | + |
| 7 | +ms.service: api-management |
| 8 | +ms.topic: article |
| 9 | +ms.date: 05/22/2023 |
| 10 | +ms.author: danlep |
| 11 | +--- |
| 12 | + |
| 13 | +# Use Azure AD authentication for the self-hosted gateway |
| 14 | + |
| 15 | +The Azure API Management [self-hosted gateway](self-hosted-gateway-overview.md) needs connectivity with its associated cloud-based API Management instance for reporting status, checking for and applying configuration updates, and sending metrics and events. |
| 16 | + |
| 17 | +In addition to using a gateway access token (authentication key) to connect with its cloud-based API Management instance, you can enable the self-hosted gateway to authenticate to its associated cloud instance by using an [Azure AD app](../active-directory/develop/app-objects-and-service-principals.md). With Azure AD authentication, you can configure longer expiry times for secrets and use standard steps to manage and rotate secrets in Active Directory. |
| 18 | + |
| 19 | +## Scenario overview |
| 20 | + |
| 21 | +The self-hosted gateway configuration API can check Azure RBAC to determine who has permissions to read the gateway configuration. After you create an Azure AD app with those permissions, the self-hosted gateway can authenticate to the API Management instance using the app. |
| 22 | + |
| 23 | +To enable Azure AD authentication, complete the following steps: |
| 24 | +1. Create two custom roles to: |
| 25 | + * Let the configuration API get access to customer's RBAC information |
| 26 | + * Grant permissions to read self-hosted gateway configuration |
| 27 | +1. Grant RBAC access to the API Management instance's managed identity |
| 28 | +1. Create an Azure AD app and grant it access to read the gateway configuration |
| 29 | +1. Deploy the gateway with new configuration options |
| 30 | + |
| 31 | +## Prerequisites |
| 32 | + |
| 33 | +* An API Management instance in the Developer or Premium service tier. If needed, complete the following quickstart: [Create an Azure API Management instance](get-started-create-service-instance.md). |
| 34 | +* Provision a [gateway resource](api-management-howto-provision-self-hosted-gateway.md) on the instance. |
| 35 | +* Enable a [managed identity](api-management-howto-use-managed-service-identity.md) on the instance. |
| 36 | + |
| 37 | +## Create custom roles |
| 38 | + |
| 39 | +Create the following two [custom roles](../role-based-access-control/custom-roles.md) that are assigned in later steps. You can use the permissions listed in the following JSON templates to create the custom roles using the [Azure portal](../role-based-access-control/custom-roles-portal.md), [Azure CLI](../role-based-access-control/custom-roles-cli.md), [Azure PowerShell](../role-based-access-control/custom-roles-powershell.md), or other Azure tools. |
| 40 | + |
| 41 | +When configuring the custom roles, update the [`AssignableScopes`](../role-based-access-control/role-definitions.md#assignablescopes) property with appropriate scope values for your directory, such as a subscription in which your API Management instance is deployed. |
| 42 | + |
| 43 | +**API Management Configuration API Access Validator Service Role** |
| 44 | + |
| 45 | +```json |
| 46 | +{ |
| 47 | + "Description": "Can access RBAC permissions on the API Management resource to authorize requests in Configuration API.", |
| 48 | + "IsCustom": true, |
| 49 | + "Name": "API Management Configuration API Access Validator Service Role", |
| 50 | + "Permissions": [ |
| 51 | + { |
| 52 | + "Actions": [ |
| 53 | + "Microsoft.Authorization/denyAssignments/read", |
| 54 | + "Microsoft.Authorization/roleAssignments/read", |
| 55 | + "Microsoft.Authorization/roleDefinitions/read" |
| 56 | + ], |
| 57 | + "NotActions": [], |
| 58 | + "DataActions": [], |
| 59 | + "NotDataActions": [] |
| 60 | + } |
| 61 | + ], |
| 62 | + "NotDataActions": [], |
| 63 | + "AssignableScopes": [ |
| 64 | + "/subscriptions/{subscriptionID}" |
| 65 | + ] |
| 66 | +} |
| 67 | +``` |
| 68 | + |
| 69 | +**API Management Gateway Configuration Reader Role** |
| 70 | + |
| 71 | +```json |
| 72 | +{ |
| 73 | + "Description": "Can read self-hosted gateway configuration from Configuration API", |
| 74 | + "IsCustom": true, |
| 75 | + "Name": "API Management Gateway Configuration Reader Role", |
| 76 | + "Permissions": [ |
| 77 | + { |
| 78 | + "Actions": [], |
| 79 | + "NotActions": [], |
| 80 | + "DataActions": [ |
| 81 | + "Microsoft.ApiManagement/service/gateways/getConfiguration/action" |
| 82 | + ], |
| 83 | + "NotDataActions": [] |
| 84 | + } |
| 85 | + ], |
| 86 | + "NotDataActions": [], |
| 87 | + "AssignableScopes": [ |
| 88 | + "/subscriptions/{subscriptionID}" |
| 89 | + ] |
| 90 | +} |
| 91 | +``` |
| 92 | + |
| 93 | +## Add role assignments |
| 94 | + |
| 95 | +### Assign API Management Configuration API Access Validator Service Role |
| 96 | + |
| 97 | +Assign the API Management Configuration API Access Validator Service Role to the managed identity of the API Management instance. For detailed steps to assign a role, see [Assign Azure roles using the portal](../role-based-access-control/role-assignments-portal.md). |
| 98 | + |
| 99 | +* Scope: The resource group or subscription in which the API Management instance is deployed |
| 100 | +* Role: API Management Configuration API Access Validator Service Role |
| 101 | +* Assign access to: Managed identity of API Management instance |
| 102 | + |
| 103 | +### Assign API Management Gateway Configuration Reader Role |
| 104 | + |
| 105 | +#### Step 1. Register Azure AD app |
| 106 | + |
| 107 | +Create a new Azure AD app. For steps, see [Create an Azure Active Directory application and service principal that can access resources](../active-directory/develop/howto-create-service-principal-portal.md). This app will be used by the self-hosted gateway to authenticate to the API Management instance. |
| 108 | + |
| 109 | +* Generate a [client secret](../active-directory/develop/howto-create-service-principal-portal.md#option-3-create-a-new-application-secret) |
| 110 | +* Take note of the following application values for use in the next section when deploying the self-hosted gateway: application (client) ID, directory (tenant) ID, and client secret |
| 111 | + |
| 112 | +#### Step 2. Assign API Management Gateway Configuration Reader Service Role |
| 113 | + |
| 114 | +[Assign](../active-directory/develop/howto-create-service-principal-portal.md#assign-a-role-to-the-application) the API Management Gateway Configuration Reader Service Role to the app. |
| 115 | + |
| 116 | +* Scope: The API Management instance (or resource group or subscription in which it's deployed) |
| 117 | +* Role: API Management Gateway Configuration Reader Role |
| 118 | +* Assign access to: Azure AD app |
| 119 | + |
| 120 | +## Deploy the self-hosted gateway |
| 121 | + |
| 122 | +Deploy the self-hosted gateway to Kubernetes, adding Azure AD app registration settings to the `data` element of the gateways `ConfigMap`. In the following example YAML configuration file, the gateway is named *mygw* and the file is named `mygw.yaml`. |
| 123 | + |
| 124 | +> [!IMPORTANT] |
| 125 | +> If you're following the existing Kubernetes [deployment guidance](how-to-deploy-self-hosted-gateway-kubernetes.md): |
| 126 | +> * Make sure to omit the step to store the default authentication key using the `kubectl create secret generic` command. |
| 127 | +> * Substitute the following basic configuration file for the default YAML file that's generated for you in the Azure portal. The following file adds Azure AD configuration in place of configuration to use an authentication key. |
| 128 | + |
| 129 | +```yml |
| 130 | +--- |
| 131 | +apiVersion: v1 |
| 132 | +kind: ConfigMap |
| 133 | +metadata: |
| 134 | + name: mygw-env |
| 135 | + labels: |
| 136 | + app: mygw |
| 137 | +data: |
| 138 | + config.service.endpoint: "<service-name>.configuration.azure-api.net" |
| 139 | + config.service.auth: azureAdApp |
| 140 | + config.service.auth.azureAd.authority: "https://login.microsoftonline.com" |
| 141 | + config.service.auth.azureAd.tenantId: "<Azure AD tenant ID>" |
| 142 | + config.service.auth.azureAd.clientId: "<Azure AD client ID>" |
| 143 | + config.service.auth.azureAd.clientSecret: "<Azure AD client secret>" |
| 144 | + gateway.name: <gateway-id> |
| 145 | +--- |
| 146 | +apiVersion: apps/v1 |
| 147 | +kind: Deployment |
| 148 | +metadata: |
| 149 | + name: mygw |
| 150 | + labels: |
| 151 | + app: mygw |
| 152 | +spec: |
| 153 | + replicas: 1 |
| 154 | + selector: |
| 155 | + matchLabels: |
| 156 | + app: mygw |
| 157 | + strategy: |
| 158 | + type: RollingUpdate |
| 159 | + rollingUpdate: |
| 160 | + maxUnavailable: 0 |
| 161 | + maxSurge: 25% |
| 162 | + template: |
| 163 | + metadata: |
| 164 | + labels: |
| 165 | + app: mygw |
| 166 | + spec: |
| 167 | + terminationGracePeriodSeconds: 60 |
| 168 | + containers: |
| 169 | + - name: mygw |
| 170 | + image: mcr.microsoft.com/azure-api-management/gateway:v2 |
| 171 | + ports: |
| 172 | + - name: http |
| 173 | + containerPort: 8080 |
| 174 | + - name: https |
| 175 | + containerPort: 8081 |
| 176 | + # Container port used for rate limiting to discover instances |
| 177 | + - name: rate-limit-dc |
| 178 | + protocol: UDP |
| 179 | + containerPort: 4290 |
| 180 | + # Container port used for instances to send heartbeats to each other |
| 181 | + - name: dc-heartbeat |
| 182 | + protocol: UDP |
| 183 | + containerPort: 4291 |
| 184 | + readinessProbe: |
| 185 | + httpGet: |
| 186 | + path: /status-0123456789abcdef |
| 187 | + port: http |
| 188 | + scheme: HTTP |
| 189 | + initialDelaySeconds: 0 |
| 190 | + periodSeconds: 5 |
| 191 | + failureThreshold: 3 |
| 192 | + successThreshold: 1 |
| 193 | + envFrom: |
| 194 | + - configMapRef: |
| 195 | + name: mygw-env |
| 196 | +--- |
| 197 | +apiVersion: v1 |
| 198 | +kind: Service |
| 199 | +metadata: |
| 200 | + name: mygw-live-traffic |
| 201 | + labels: |
| 202 | + app: mygw |
| 203 | +spec: |
| 204 | + type: LoadBalancer |
| 205 | + externalTrafficPolicy: Local |
| 206 | + ports: |
| 207 | + - name: http |
| 208 | + port: 80 |
| 209 | + targetPort: 8080 |
| 210 | + - name: https |
| 211 | + port: 443 |
| 212 | + targetPort: 8081 |
| 213 | + selector: |
| 214 | + app: mygw |
| 215 | +--- |
| 216 | +apiVersion: v1 |
| 217 | +kind: Service |
| 218 | +metadata: |
| 219 | + name: mygw-instance-discovery |
| 220 | + labels: |
| 221 | + app: mygw |
| 222 | + annotations: |
| 223 | + azure.apim.kubernetes.io/notes: "Headless service being used for instance discovery of self-hosted gateway" |
| 224 | +spec: |
| 225 | + clusterIP: None |
| 226 | + type: ClusterIP |
| 227 | + ports: |
| 228 | + - name: rate-limit-discovery |
| 229 | + port: 4290 |
| 230 | + targetPort: rate-limit-dc |
| 231 | + protocol: UDP |
| 232 | + - name: discovery-heartbeat |
| 233 | + port: 4291 |
| 234 | + targetPort: dc-heartbeat |
| 235 | + protocol: UDP |
| 236 | + selector: |
| 237 | + app: mygw |
| 238 | +``` |
| 239 | +
|
| 240 | +Deploy the gateway to Kubernetes with the following command: |
| 241 | +
|
| 242 | +```Console |
| 243 | +kubectl apply -f mygw.yaml |
| 244 | +``` |
| 245 | + |
| 246 | +[!INCLUDE [api-management-self-hosted-gateway-kubernetes-services](../../includes/api-management-self-hosted-gateway-kubernetes-services.md)] |
| 247 | + |
| 248 | + |
| 249 | +## Next steps |
| 250 | + |
| 251 | +* Learn more about the API Management [self-hosted gateway overview](self-hosted-gateway-overview.md). |
| 252 | +* Learn more about guidance for [running the self-hosted gateway on Kubernetes in production](how-to-self-hosted-gateway-on-kubernetes-in-production.md). |
| 253 | +* Learn [how to deploy API Management self-hosted gateway to Azure Arc-enabled Kubernetes clusters](how-to-deploy-self-hosted-gateway-azure-arc.md). |
| 254 | + |
| 255 | +[helm]: https://helm.sh/ |
| 256 | +[helm-install]: https://helm.sh/docs/intro/install/ |
0 commit comments