Web API  

Azure API Management Gateway β€” ABC Inc : Full Setup Guide (step-by-step)

Goal: Publish/secure/monitor three backend APIs behind APIM for ABC Inc:

  • Billing API (App Service)

  • Meter API (Azure Functions)

  • Account API (AKS microservice)

Features included:

  • Central gateway with policies: JWT validation (Azure AD B2C), rate limit, caching, response transformation (mask PII), CORS, IP restrictions

  • Developer Portal & subscription keys

  • Diagnostics β†’ Application Insights

  • Private (VNet) + Self-hosted Gateway option

  • Auto-rotation & CI/CD friendly setup

  • .NET test client examples

1 β€” High-level architecture (textual diagram)

Clients (Mobile, Web, Partner Apps)
β†’ Azure API Management Gateway (APIM) (Public / Private + optional Self-Hosted)
β†’ Backend Services: Billing (App Service), Meter (Functions), Account (AKS)

Supporting services:

  • Azure AD B2C (identity)

  • Key Vault (certs & secrets)

  • Application Insights & Log Analytics (monitoring)

  • Event Grid / Service Bus (for change feed/events)

  • Azure Container Instance / on-prem (self-hosted gateway)

2 β€” Create APIM (Portal, CLI or Bicep)

Important choices

  • Use Premium if you need VNet + multi-region + higher throughput.

  • Use Developer for dev/test (no SLA).

  • For Private endpoints you need Premium.

Quick Azure CLI (creates APIM in basic form β€” replace placeholders)

RG="aw-rg"
LOCATION="eastus"
APIM_NAME="aw-apim-prod"
PUBLISHER_EMAIL="[email protected]"
PUBLISHER_NAME="ABC Inc"

az group create -n $RG -l $LOCATION

az apim create \
  --name $APIM_NAME \
  --resource-group $RG \
  --location $LOCATION \
  --publisher-email $PUBLISHER_EMAIL \
  --publisher-name "$PUBLISHER_NAME" \
  --sku-name Developer \
  --capacity 1

For Premium use --sku-name Premium and consider --virtual-network-type Internal to connect to VNet.

Bicep (skeleton) β€” APIM instance (useful for CI/CD)

param apimName string = 'aw-apim-prod'
param location string = resourceGroup().location
param publisherEmail string
param publisherName string

resource apim 'Microsoft.ApiManagement/service@2023-01-01' = {
  name: apimName
  location: location
  sku: {
    name: 'Premium' // or Developer/Standard
    capacity: 1
  }
  properties: {
    publisherEmail: publisherEmail
    publisherName: publisherName
    // virtualNetworkType: 'External' | 'Internal' // if Premium + VNet
  }
}

3 β€” Add APIs (Portal steps + CLI)

Portal (easiest):

  1. Open APIM β†’ APIs β†’ Add API

  2. Choose:

    • OpenAPI to import swagger of Billing API (recommended)

    • HTTP to define manually

  3. Set Frontend endpoint (path) e.g., /billing and Backend to App Service URL.

CLI (import OpenAPI)

az apim api import --resource-group $RG --service-name $APIM_NAME \
  --path billing --api-id billing-api \
  --specification-format OpenApi --specification-url "https://billing.azurewebsites.net/swagger/v1/swagger.json"

4 β€” Bind custom domain & TLS (optional but recommended)

Set up custom DNS & TLS cert (from Key Vault or App Service cert), then configure Custom domains in APIM (Management β†’ Custom domains). For production use custom domain + certificate in Key Vault and APIM with managed identity to access certificate.

5 β€” Secure APIs: Subscription keys vs OAuth2/JWT

Two common approaches:

  • Subscription Key (Ocp-Apim-Subscription-Key) β€” simple API key managed by APIM; used by client apps.

  • OAuth2 / JWT β€” recommended for user authentication (use Azure AD B2C for end-user tokens).

Configure OAuth 2.0: (Portal)

  1. APIM β†’ Security β†’ OAuth 2.0 + OpenID Connect

  2. Add an OpenID Connect provider:

    • Name: AzureADB2C

    • Metadata endpoint: https://<tenant>.b2clogin.com/<tenant>.onmicrosoft.com/<policy>/v2.0/.well-known/openid-configuration

  3. In each API operation, add an authorization requirement or apply a policy to validate JWT.

6 β€” Key APIM Policies (inbound / backend / outbound)

Policies are XML fragment attached at API, operation or product level.

Common policy snippets (copy-paste into APIM policy editor)

A. Validate JWT (Azure AD / B2C)

<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
  <openid-config url="https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/v2.0/.well-known/openid-configuration" />
  <required-claims>
    <claim name="aud">
      <value>{api-client-id}</value>
    </claim>
  </required-claims>
</validate-jwt>

Place in <inbound>.

B. Subscription key check (optional β€” APIM enforces by default when product requires subscription)

APIM will check Ocp-Apim-Subscription-Key if the product requires subscription. No explicit policy needed unless you want custom header name/logic.

C. Rate-limiting / Throttling

<rate-limit calls="100" renewal-period="60" />          <!-- 100 calls per 60 seconds globally -->
<!-- or per subscription -->
<quota calls="1000" renewal-period="3600" remaining-quota-header-name="x-remaining-quota" />

D. Caching (response caching)

<cache-lookup vary-by-developer="false">
  <vary-by-header name="Accept" />
  <vary-by-query-parameter name="month" />
</cache-lookup>

<!-- backend call -->

<cache-store duration="60" />

E. Response Transformation (mask PII)

<set-body template="liquid">
  {
    "customerId": "{{body.customerId}}",
    "name": "{{body.name}}",
    "maskedSsn": "{{body.ssn | slice:0,3 }}***-**-****",
    "balance": "{{body.balance}}"
  }
</set-body>

Or use set-header, remove-header, set-query-parameter, rewrite-uri to manipulate request/response.

F. IP restriction (allowlist)

<check-header name="X-Forwarded-For" exists-action="skip">
  <value>203.0.113.10</value>
</check-header>

<!-- Alternatively use 'validate-client-certificate' or Azure Firewall + APIM policies to block -->

G. Add Correlation ID

<set-header name="X-Correlation-ID" exists-action="override">
  <value>@(context.RequestId)</value>
</set-header>

H. Log to Event Hub (audit)

<log-to-eventhub logger-id="eventHub-logger">
  <data>Request: @(context.Request.Method) @(context.Request.Url)</data>
</log-to-eventhub>

(Requires Event Hub logger configured in APIM settings)

7 β€” Policy application locations & scoping

  • Global (All APIs): Apply cross-cutting policies like CORS, logging at the global policy (APIM designer β†’ All APIs).

  • API-level: e.g., caching specific to Billing API.

  • Operation-level: e.g., only POST /payments needs additional fraud-check policy.

8 β€” Developer Portal & Products

  1. APIM β†’ Products β†’ Create a product public or partners.

  2. Add APIs to product and require subscription.

  3. Developers can sign up in Developer Portal and get subscription keys (trial or approved).


9 β€” Self-hosted Gateway (hybrid / on-prem)

Use this when backend is on-prem or you want local routing but centralized control.

High level:

  • Configure APIM to add a self-hosted gateway instance (APIM β†’ Gateways β†’ + Add)

  • You get a gateway configuration (download a Docker image or run as Linux service).

  • Run container on a VM or Kubernetes cluster in your datacenter.

Docker run example (simplified):

docker run -d --name apim-gateway \
  -e GATEWAY_ID="<gateway-id>" \
  -e SIDECAR_URL="https://<gateway-config-url>" \
  mcr.microsoft.com/azure-api-management/gateway:latest

Self-hosted gateway uses certificates for trust and can operate without public internet access to your backend.

10 β€” VNet / Private Endpoint (secure internal APIs)

Premium tier only: configure virtualNetworkType=Internal and set up integration to a VNet. Use Private Endpoint to secure APIM to internal network; set backend (App Service) with VNet integration.

11 β€” Monitoring & Diagnostics

Enable Diagnostic settings (APIM β†’ Diagnostic settings):

  • Send Request & Operation logs to Application Insights or Log Analytics.

  • Enable Azure Monitor integration and set alerts for:

    • 5xx errors

    • High latency (e.g., >500ms)

    • 429 (throttling)

Log sampling: be mindful to avoid logging sensitive PII.

Capture RU/usage-like metrics: APIM exposes metrics for throughput, latency, bandwidth and calls.

CLI to enable Application Insights logger (example):

az resource update --ids /subscriptions/$SUBS_ID/resourceGroups/$RG/providers/Microsoft.ApiManagement/service/$APIM_NAME \
  --set properties.publisherEmail="[email protected]"
# configure diagnostics via ARM/Bicep for Application Insights (more verbose)

12 β€” CI/CD for APIM (ARM/Bicep + DevOps)

  • Export APIM configuration using az apim api or apimdevops tool (APIM DevOps Resource Kit) to generate ARM templates.

  • Use Bicep/ARM templates and GitHub Actions or Azure DevOps pipelines to deploy API changes and policy XML.

Useful tool: API Management DevOps Resource Kit (extractor + publisher) β€” turn APIM configuration into ARM templates for CI.

13 β€” Keys / Secrets / Certificate Best Practices

  • Store certificates and any sensitive credentials in Azure Key Vault and reference them in APIM or in App Service.

  • Use Managed Identity where possible β€” APIM can access Key Vault via managed identity to get certs.

14 β€” Caching & Performance tuning tips

  • Cache read-heavy endpoints (e.g., GetWaterRates, WaterUsageForecast) at gateway.

  • Use cache-lookup / cache-store policies; set appropriate TTLs and vary-by headers for personalization.

  • Use Response Caching only for idempotent GET endpoints.

  • Enable gateway-level compression via set-header or backend compression.

15 β€” Failover & Multi-region

  • Premium tier supports multi-region APIM deployments with active/passive or active-active (depends on architecture).

  • For global customers deploy APIM in multiple regions and use Traffic Manager or Front Door for global routing.

16 β€” Example production policy (Composite: JWT + RateLimit + Cache + Transform)

<policies>
  <inbound>
    <base/>
    <!-- 1. Validate JWT -->
    <validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized">
      <openid-config url="https://{tenant}.b2clogin.com/{tenant}.onmicrosoft.com/{policy}/v2.0/.well-known/openid-configuration" />
      <required-claims>
        <claim name="aud">
          <value>{api-client-id}</value>
        </claim>
      </required-claims>
    </validate-jwt>

    <!-- 2. Rate limit per-user (by subscription) -->
    <rate-limit-by-key calls="120" renewal-period="60" counter-key="@(context.Subscription?.Id ?? context.Request.IpAddress)" />

    <!-- 3. Cache GET responses for 60s -->
    <choose>
      <when condition="@(context.Request.Method == "GET")">
        <cache-lookup vary-by-developer="false" />
      </when>
    </choose>

    <!-- 4. Add Correlation ID -->
    <set-header name="X-Correlation-ID" exists-action="override">@((string)context.RequestId)</set-header>
  </inbound>

  <backend>
    <forward-request />
  </backend>

  <outbound>
    <!-- store in cache if GET -->
    <choose>
      <when condition="@(context.Request.Method == "GET")">
        <cache-store duration="60" />
      </when>
    </choose>

    <!-- mask PII using Liquid template (simplified) -->
    <set-body template="liquid">
      {
        "customerId":"{{body.customerId}}",
        "name":"{{body.name}}",
        "maskedSsn":"{{body.ssn | slice:0,3 }}***-**-****",
        "balance":"{{body.balance}}"
      }
    </set-body>
  </outbound>

  <on-error>
    <set-status code="500" reason="Internal Server Error" />
  </on-error>
</policies>

17 β€” .NET C# Test Client Examples

A β€” Call APIM using Subscription Key (simple)

using System;
using System.Net.Http;
using System.Threading.Tasks;

public static class ApimClient
{
    private static readonly HttpClient _client = new HttpClient();
    private const string APIM_BASE = "https://api.abcinc.com"; // APIM public endpoint

    public static async Task CallBillingAsync(string customerId)
    {
        var req = new HttpRequestMessage(HttpMethod.Get, $"{APIM_BASE}/billing/{customerId}");
        req.Headers.Add("Ocp-Apim-Subscription-Key", Environment.GetEnvironmentVariable("APIM_SUB_KEY") ?? "your-sub-key-here");

        var res = await _client.SendAsync(req);
        Console.WriteLine($"Status: {res.StatusCode}");
        var content = await res.Content.ReadAsStringAsync();
        Console.WriteLine(content);
    }
}

B β€” Call APIM using Azure AD (OAuth2) β€” get access token & call (recommended for user flows)

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Microsoft.Identity.Client; // or use MSAL

public static class ApimAadClient
{
    private static readonly HttpClient _http = new HttpClient();

    public static async Task CallWithAadAsync(string customerId)
    {
        // MSAL confidential client flow (server-to-server)
        var tenantId = "<tenant-id>";
        var clientId = "<client-id>";   // app registration
        var clientSecret = "<client-secret>";
        var apimScope = "https://management.azure.com/.default"; // or custom API scope

        var app = ConfidentialClientApplicationBuilder
            .Create(clientId)
            .WithClientSecret(clientSecret)
            .WithAuthority($"https://login.microsoftonline.com/{tenantId}")
            .Build();

        // Acquire token for APIM backend scope (if APIM validates issuer & audience)
        string[] scopes = new[] { "api://<apim-backend-client-id>/.default" }; // depends on API/AAD app
        var result = await app.AcquireTokenForClient(scopes).ExecuteAsync();

        var request = new HttpRequestMessage(HttpMethod.Get, $"https://api.abcinc.com/billing/{customerId}");
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);

        var resp = await _http.SendAsync(request);
        resp.EnsureSuccessStatusCode();
        Console.WriteLine(await resp.Content.ReadAsStringAsync());
    }
}

For user-login scenarios use Authorization Code flow (MSAL browser + bearer token).

18 β€” Self-hosted Gateway: quick how-to

  1. APIM β†’ Gateways β†’ Add a Gateway β†’ give it a name, assign to an APIM service.

  2. Click on the gateway β†’ Get gateway configuration (download).

  3. Provision a VM / Kubernetes node and run the gateway container with that config. Gateway then receives API definitions and policies from central APIM and performs routing locally.

Use cases:

  • On-prem backends (no public network)

  • Low latency local routing

  • Regulatory requirements for data flow

19 β€” Real Case Scenarios (ABC Inc)

Scenario A β€” Public Mobile App (High concurrency)

  • Mobile calls APIM. APIM validates JWT, rate-limits per user, caches GetWaterRates.

  • Billing API is shielded from direct traffic.
    Benefits: faster caching, easy versioning, abuse protection.

Scenario B β€” Partner Batch Upload (Data Ingest)

  • Partners push meter data via secure client certificate auth to meter-ingest endpoint.

  • Use APIM product for partners, require subscription + client-certificate validation, route to ingestion Function that writes to Cosmos DB or Event Hub.

Scenario C β€” On-prem SCADA Integration

  • SCADA systems cannot reach public internet; deploy self-hosted gateway in the on-prem network to route to cloud backend after local validation.
    Benefits: centralized policies, local connectivity.

Scenario D β€” Regulatory Audit & Masking

  • APIM policy overlays mask PII in responses for certain developer products; logs scrubbed before sending to App Insights. Use Key Vault to store masking rules/certificates.

Scenario E β€” Multi-region & Disaster Recovery

  • Deploy APIM Premium in East US & West EU. Use Front Door for geo-routing. Use replication & traffic manager for failover.

20 β€” Troubleshooting & Tips

  • 504/502 errors β€” check Backend health, Network, VNet integration, and hostname resolution.

  • 401 β€” JWT audience/issuer mismatch; ensure aud in token equals expected client id.

  • High latency β€” enable caching or move APIM closer to clients (multi-region).

  • 429 β€” increase rate limits, increase capacity or move to autoscale.

  • Policy errors β€” use Trace tool in APIM dev portal to see policy execution and context.

21 β€” Security & Governance checklist

  • Enforce TLS 1.2+ on custom domain.

  • Use managed identity & Key Vault for certs.

  • Use least privilege: products & per-API policies.

  • Enable IP restriction + WAF (Azure Front Door / Application Gateway) in front of APIM for extra layer.

  • Periodically rotate subscription keys and secrets.

22 β€” Interview Questions (Beginner β†’ Advanced)

Beginner

  1. What is Azure API Management? What components does it include?

  2. How do subscription keys work? How do you use them?

  3. What is the difference between API version and revision?

  4. When should you use APIM vs Azure Application Gateway?

Intermediate

  1. How does APIM policy engine work? Give an example policy.

  2. What approaches are available for securing APIs in APIM? (Subscription key, OAuth/JWT, client certificate)

  3. How to import an OpenAPI spec into APIM? CLI or Portal steps?

  4. Explain caching in APIM. When to cache responses and what are the caveats?

Advanced

  1. Explain how a self-hosted APIM gateway works. When would you use it?

  2. How would you integrate APIM with Azure AD or Azure AD B2C for user authentication?

  3. How to implement per-user rate limiting? (rate-limit-by-key)

  4. Explain how to do private (internal) APIs using APIM and VNet integration.

  5. How would you manage APIM configurations across environments (dev/stage/prod)?

  6. How to avoid logging PII in diagnostics while still capturing useful telemetry?

  7. How does APIM handle multi-region deployments and failover? What tier is required?

Practical Scenario Questions

  • β€œA partner is being throttled β€” they insist they’re within limits. How would you troubleshoot?”

  • β€œYou need to mask SSN before delivering to partners β€” where do you implement this and why?”

  • β€œHow would you perform zero-downtime API versioning & rolling back policies?”

23 β€” Useful Resources & Tools (short list)

  • APIM DevOps Resource Kit (export/import templates)

  • Azure Docs β€” APIM policies reference

  • Azure Portal β†’ APIM β†’ Trace tool (debug policies)

  • Application Insights (APIM logger)

  • APIM REST API (management plane automation)