Hello! Welcome back to our exploration of Azure API Management.
In the last lesson, we set up the core infrastructure by creating an APIM instance and importing a backend API. You now have a working gateway that proxies requests to your App Service. This setup, however, is open to the public and lacks any controls.
Today, we'll address that by diving into one of the most powerful features of APIM: policies. This lesson focuses on applying built-in policies to secure and control access to your API. Specifically, you will learn how to implement rate limiting to prevent abuse and enforce JSON Web Token (JWT) validation to ensure that only authenticated and authorized clients can use your API.
1. The Power of the Policy Engine
Before we write any policies, it's crucial to understand their role. Policies are snippets of XML that execute in the request/response pipeline. They allow you to modify the behavior of your API at the gateway without touching a single line of your backend code. This is fundamental to the abstraction that APIM provides.
Policies are applied in different sections of the pipeline:
- inbound: Policies that execute on the incoming request before it's sent to your backend.
- backend: Policies that execute just before the request is forwarded.
- outbound: Policies that execute on the response coming back from your backend before it's sent to the client.
- on-error: Policies that execute if an error occurs.
Today, we will focus entirely on the inbound section to validate requests before they consume your backend resources.

Let's watch a brief conceptual overview of how this policy engine works.
Azure API Management Deep Dive
This clip from John Savill's Technical Training explains how the API Gateway intercepts requests and applies policies in the inbound and outbound flows.
Watch from 07:00 to 09:36. Focus on understanding how the API Gateway sits in the middle and applies policies to the request on the way in and the response on the way out. This is the core mechanism we'll be using.
2. Controlling Traffic with Rate Limiting
The first policy we'll implement is for rate limiting. This is a crucial defense against both accidental and malicious overuse of your API, ensuring it remains available and performant for all consumers.
APIM offers two primary policies for this:
rate-limit: Applies a single rate limit to all calls for a given scope (e.g., all operations in an API).rate-limit-by-key: Applies a rate limit based on a specific key, allowing you to set different limits for different users, subscription keys, or IP addresses.
Let's explore how to configure this.
How to Implement Rate Limiting in Azure API Management
This Microsoft Learn article provides a concise and clear guide on implementing rate limiting in APIM. We will use it to understand the policy structure and its effects.
Please read the introduction and the sections 'Configure rate limiting in Azure API Management' and 'Expose rate limit information on response headers'. Pay attention to: The simple XML structure of the rate-limit policy. The 429 Too Many Requests status code that is returned when the limit is exceeded. The retry-after response header, which tells the client how long to wait before trying again.
Hands-On: Apply a Rate Limit
Now, let's apply this to the API you configured in the previous lesson.
- Navigate to your APIM instance in the Azure portal.
- Select your API under the APIs blade.
- Choose an operation, for example, the
GET /WeatherForecastoperation. - In the Inbound processing section, click the
</>icon to open the policy code editor. - Within the
<inbound>element, add the following policy. This policy allows only 3 calls every 60 seconds.
<policies>
<inbound>
<base />
<rate-limit calls="3" renewal-period="60" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
- Click Save.
- Go to the Test tab for that operation and click Send four times in quick succession. The first three calls should succeed with a
200 OKstatus. The fourth call should fail with a429 Too Many Requestsstatus.
This simple exercise demonstrates how effectively you can protect your backend with just a few lines of configuration.
3. Securing Your API with JWT Validation
While subscription keys offer a basic level of security, modern applications typically rely on OAuth 2.0 and JWT bearer tokens for authentication. Given your background with REST APIs, you're likely familiar with this pattern. APIM can offload the entire token validation process from your backend service.
The validate-jwt policy is incredibly powerful. It can:
- Check for a valid token in the
Authorizationheader. - Verify the token's signature against the identity provider's public keys.
- Validate standard claims like issuer (
iss), audience (aud), and expiration time (exp). - Check for the presence of custom claims (e.g., roles or permissions).
The complete flow looks like this:

We'll use Microsoft Entra ID as our identity provider. To implement this, you'll perform two main tasks:
- In Microsoft Entra ID: Register two applications—one to represent your API and one to represent the client application that needs to access it.
- In Azure APIM: Configure the
validate-jwtpolicy to validate tokens issued for your API.
The following video provides a clear, step-by-step demonstration of this entire process. We will follow it closely.
12: Azure API Management JWT Authentication | Practical Demo | Azure APIM Tutorial
This video by Harshalkumar Jain is a practical walkthrough of setting up JWT authentication from start to finish. It covers both the Azure AD configuration and the APIM policy.
This is our main guide for this section. I recommend following along in your own Azure account. Configure App Registrations (02:36 - 07:44): Watch how to create two app registrations in Microsoft Entra ID. The first represents your API (what the video calls 'app for apim'). Pay attention to the 'Expose an API' step, where an Application ID URI (the audience) is defined. The second represents your client ('XYZ finance consultancy'). Note how it's granted permission to call the API app and how a client secret is generated. Configure the validate-jwt Policy (07:44 - 10:40): This is the most critical part. Observe how the policy is configured in APIM. The two most important fields are: openid-config URL: This points to a .well-known/openid-configuration endpoint. APIM uses this to automatically discover the token issuer and where to find the public keys needed to validate the signature. This is the standard OpenID Connect discovery mechanism. audience: This must match the Application ID URI you set up in the API's app registration. Test the Flow (10:40 - 13:45): See how to use Postman to first obtain a token from Microsoft Entra ID using the client's credentials, and then use that bearer token to successfully call the protected API.
Hands-On: Implement JWT Validation
It's time to put this all together. Follow the steps from the video to secure your own API.
-
Create App Registrations:
- In the Microsoft Entra ID section of the Azure portal, create two app registrations as shown in the video.
- For the API app registration, go to Expose an API and set the Application ID URI. Copy this URI for later.
- For the client app registration, go to API permissions, add a permission, find your API app registration under "My APIs", and grant the permission. Also, create a client secret and copy its value immediately (it won't be shown again).
-
Configure the Policy:
- Navigate back to your API in APIM and open the policy editor for the desired scope (e.g., the whole API).
- Add the
validate-jwtpolicy inside the<inbound>section. Use the following template, replacing the placeholder values with your own.
<validate-jwt header-name="Authorization" failed-validation-httpcode="401" failed-validation-error-message="Unauthorized. Access token is missing or invalid.">
<openid-config url="https://login.microsoftonline.com/{your-tenant-id}/v2.0/.well-known/openid-configuration" />
<audiences>
<audience>{your-api-application-id-uri}</audience>
</audiences>
</validate-jwt>
* You can find your **Tenant ID** on the overview page of your Microsoft Entra ID.
* The `{your-api-application-id-uri}` is the URI you copied from the API app registration.
3. Test with Postman:
* Follow the video's instructions (starting at 11:17) to configure Postman to get an access token.
* Token URL: https://login.microsoftonline.com/{your-tenant-id}/oauth2/v2.0/token
* Client ID: The Application (client) ID of your client app registration.
* Client Secret: The secret value you copied from the client app.
* Scope: {your-api-application-id-uri}/.default
* Get the token, then use it as a Bearer Token in the Authorization header to call your APIM endpoint. You should receive a 200 OK. Try calling it without the token to confirm you get a 401 Unauthorized.
For detailed documentation on all the available attributes and child elements of the validate-jwt policy, you can refer to the official Microsoft Learn page validate-jwt - Azure API Management policy reference. It's a useful resource for more advanced scenarios.
Conclusion
Excellent work! You have now used APIM policies to add two critical layers of control to your API without modifying the backend service. This demonstrates the core value of an API Gateway in a modern architecture.
Key Takeaways:
- Policies are XML snippets that execute in the APIM request/response pipeline to modify API behavior.
- The
<inbound>section is used to apply logic to incoming requests, such as validation and security checks. - The
rate-limitpolicy is a simple and effective way to protect your backend from being overwhelmed. - The
validate-jwtpolicy offloads complex token validation from your backend, enforcing authentication at the gateway using standard protocols like OAuth 2.0 and OpenID Connect.
Next Steps
Now that you can control who can call your API and how often, the next step is to control what they see and how the request is structured. In our next lesson, we will explore policies that transform requests and responses, such as modifying headers, rewriting URLs, and changing the response body. This will further enhance the abstraction between your clients and your backend services.