Skip to content
CAMPUX Cloud Bootcamp Phase Four · Class 38 · Part D
Phase Four — Operate, Secure & AI
4 drills · 2 situations · Part IV of VIII
API Management
Class Thirty-Eight · Part D

Policies

Policies tell API Management what to check or change as a request passes through. Learn where each rule runs, then test that it protects the service you meant to protect.

Phase Four · Operate, Secure, AI · Class 38 · Part D · 13 min · Assumes Class 38 Part C

After this you can write inbound, backend and outbound policies that rate-limit, rewrite and cache.

New to this? Read Class 38 Part C first. Already done it, or know the material? Carry on.

§1

What a policy adds to the gateway

Part C gave the gateway an API model and a route to the backend. A policy is a rule APIM applies while handling a call. Policy statements use XML: one can check a token, another can limit calls, and another can remove a response header. You choose both the rule and where it runs. A gateway also has built-in behavior, such as routing, so a policy is not the only thing it does.

Policy
A rule in APIM's XML policy language. It can apply at the service-wide, workspace, product, API, or operation scope, depending on the gateway and feature. A narrower policy section uses <base /> to include policies inherited from broader scopes. Check every section when you add a narrow rule: omitting <base /> can prevent an intended broader rule from running there.

Scope means how widely the rule applies. A product-scope policy can apply to APIs in that product; an operation-scope policy can target one method and path. The scope is not the identity of the rate-limit counter: rate-limit-by-key counts by its configured key. Two callers sharing that key share the counter.

One policy first

Read a rate limit before you read anything else

<inbound>
  <base />
  <rate-limit-by-key calls="10" renewal-period="60"
      counter-key="@(context.Subscription.Id)" />
</inbound>
  • <inbound>: this runs before the request reaches the backend.
  • <base />: run whatever the wider scope already defines first.
  • calls="10" renewal-period="60": ten calls per sixty seconds.
  • counter-key: count per subscription, so each partner has its own ten.

Predict: the warehouse sends its eleventh call inside the minute. What does it get back, and does the backend see it? (A 429 Too Many Requests, from the gateway; the backend never sees it.) Rewrite, cache and token policies in §3 follow the same shape; add them one at a time.

§2

The pipeline — four stages, one red rail

Policies run in a pipeline, an ordered path through a request. Inbound runs before forwarding; use it to validate a token, check a rate limit, or change the request. Backend controls forwarding to the service. Outbound runs on the response; use it to remove a response header or store a cacheable answer. On-error runs when APIM encounters an error during processing. Each policy also has its own allowed sections: moving a policy to a different section is not always valid.

The API Management policy pipeline: a request passes through inbound, backend, and outbound policy stages, with an on-error path drawn in red pen catching failures from every stage. Caller Inbound Backend Outbound auth · limit · shape forward · retry cache · strip Response Backend service on-error Every stage can fail into the same red rail — and the rail decides what the caller learns.
Figure 1 A request passes through inbound and backend processing; a normal response then passes through outbound. If an APIM processing error occurs, execution jumps to on-error. A deliberate policy response, such as throttling, has its own documented status and headers; do not assume on-error creates it.
§3

The policies you will actually write

Start with a few common policies. Rate-limit-by-key caps calls over a short window using a key you choose; quota-by-key counts a longer allowance and is unavailable in v2 tiers.1 A subscription ID is one possible key when subscriptions are required. Validate-jwt can check a signed token, including its intended audience when configured. Cache-lookup checks inbound for an existing answer; cache-store stores a GET response outbound. CORS tells browsers which web origins may read a response. Some browser requests first send a preflight OPTIONS check. CORS does not authenticate a caller or block non-browser clients.

Here is an illustrative inbound section for the protected partner API. Replace the example tenant and audience with your own values, test token claims, and confirm the subscription requirement before using the subscription ID as a counter key:

<!-- inbound: applies before the backend is touched -->
<inbound>
  <base />
  <cors>
    <allowed-origins><origin>https://shop.campux.co</origin></allowed-origins>
    <allowed-methods><method>GET</method></allowed-methods>
    <allowed-headers><header>authorization</header></allowed-headers>
  </cors>
  <validate-jwt header-name="Authorization" require-scheme="Bearer"
    failed-validation-httpcode="401">
    <openid-config url="https://login.microsoftonline.com/11111111-1111-1111-1111-111111111111/v2.0/.well-known/openid-configuration" />
    <audiences><audience>api://22222222-2222-2222-2222-222222222222</audience></audiences>
  </validate-jwt>
  <rate-limit-by-key calls="100" renewal-period="60"
    counter-key="@(context.Subscription.Id)" />
</inbound>

Read the section top to bottom: inherit broader rules, handle allowed browser origins, validate a Bearer token for this API's audience, then limit calls by subscription. APIM returns 429 when the rate limit is exceeded, but distributed counters are approximate; do not promise exactly the 101st call is rejected. The example is a section inside a larger <policies> document, not a complete deployable file.

Play

Play it through

Place a response-header rule and a per-partner rate limit in their supported sections. Watch which calls stop before the backend and which still reach it.

§4

Two disciplines that keep policy from becoming a liability

First, policies are code. A rate limit is production behaviour; a JWT check is a security control. So the XML lives in the repository, is deployed by the Class Twenty-Two pipeline, and is reviewed like everything else — because portal-edited policy is the Class Twenty click-drift problem reborn, a production change with no diff, no review, and no way to reproduce. The moment someone "just tweaks a policy in the portal," you have an environment whose behaviour no file describes.

Second, policies stay traffic-shaped. Authentication, limiting, caching, transformation, header hygiene — the gateway's proper work is about how requests flow. The moment business logic creeps into policy XML — a discount calculation, a pricing rule, an entitlement decision — you have hidden part of the application in a place no debugger visits, outside the test suite, outside the code review path most teams wire for application code. Six months later a pricing bug hunt ends somewhere nobody thought to look. The boundary is the track's spine, stated once more: the gateway decides whether and how a request travels; the backend decides what it means.

Business logic in policy is a bug hunt in a place no debugger visits.

Case File · Campux Retail

The feral sync, caught as a 429

a per-partner limit before the shared backend

In this Standard v2 example, Campux places rate-limit-by-key in inbound, with a 100-call-per-minute target keyed by the required partner subscription ID.2 It commits the policy to the repo, deploys it through the pipeline, and tests how each partner key is counted. quota-by-key is not available in this tier, so a daily allowance would need a different supported design.

When one marketplace's sync enters a retry loop, calls beyond its approximate rate limit receive 429 responses before reaching the backend. That reduces the excess load; it does not guarantee every other partner is unaffected. Campux checks backend capacity, retries, logs and partner-specific counters before calling the incident contained.

§5

Behaviour, but not yet identity

The example rate limit counts on context.Subscription.Id. That assumes the partner API requires subscriptions and each partner uses its own key. Part E explains subscriptions; Part F covers token validation and backend access; Part G covers network placement. A rate limit alone is not an identity or security design.

This part carries no lab. There is no cloud resource to stand up for policy itself — the gateway already exists from 38b and the API from 38c, so writing and reasoning about policy XML is the whole exercise, and the game above is where you do it with your hands.

On the job

Protect the shared backend from retry storms

You · Cloud Engineer · a caller keeps taking the service down

One consumer's runaway job has saturated a shared backend. On the Standard v2 gateway, you add an inbound rate limit keyed to that consumer's subscription, review it in the repo and test it with separate partner keys. Excess calls receive 429 responses before forwarding. You still monitor backend load and retry behavior: limits reduce one source of pressure but do not prove the incident cannot recur.

Guided continuation

Continue with a supplied build

Follow the same fictional catalogue through this track. The supplied contract and worked checks let you practise without an Azure estate; the optional import/mock path makes real gateway requests. Each step states what it proves and what it does not.

Open the step-by-step practice →

Class 38 · Part D

Examination

Four drills, then two situations. The situations have no marking scheme — write your answer before you reveal the reasoning, or the exercise is worthless. Nothing is stored; this is between you and the page.

Drill 01Recall · pipeline
You want unauthenticated requests rejected before they ever reach the backend. In which stage does the validate-jwt policy belong, and why there?
Marked

A — inbound, because the whole point is to stop a bad request before it costs anything. Inbound runs first; a failed token check there returns a 401 and the backend never hears the request, which is both cheaper and safer. B misunderstands the front desk: the backend may also check (defence in depth, 38f), but relying on it alone means unauthenticated traffic reaches it, which is exactly what the gateway exists to prevent. C is too late — outbound runs after the backend already answered, so you would have served the request before deciding it was unauthorised. D confuses a control with error handling: on-error decides what a caller learns when something breaks, not whether they were allowed in. The pipeline order is not trivia; it is what lets a gateway reject cheaply.

Drill 02Recall · CORS
A single-page app served from shop.campux.co calls your API and the browser blocks it with a CORS error, even though the same call works fine from curl. What is going on?
Marked

B — browsers enforce CORS. A page on one origin can read a cross-origin response only when the API permits that origin. Some requests first send a preflight OPTIONS call; simple requests do not. curl does not enforce this browser rule. Check the browser's network trace and configure the cors policy for https://shop.campux.co, the needed methods and headers. CORS is not authentication or a firewall: a non-browser client can still call the endpoint unless other controls stop it.

Drill 03Select three
Which three belong in gateway policy — the traffic-shaped work APIM should be doing?
Marked

Limit, validate and handle suitable responses. These are gateway concerns, though each policy needs the right section, scope and tier. On Standard v2, use rate-limit-by-key for this example; quota-by-key is unavailable. Keep discount calculations in application code, and do not expose internal exception details to callers.

Drill 04Spot the error
A team lists what they plan to put in the catalog API's policy. One item is in the wrong section, and will not do what they expect. Which?
# catalog API — policy plan
1.  On inbound, validate-jwt; reject bad tokens 401
    before the backend is touched.
2.  On inbound, rate-limit-by-key at 100 calls/min,
    keyed on the subscription.
3.  On inbound, cache-store the response for 30
    seconds, so repeat GETs skip the backend.
4.  On outbound, strip the internal headers before
    the response leaves.
Marked

Line three. Microsoft lists cache-store for the outbound section, after a response exists. Pair it with cache-lookup inbound. Putting it inbound is an invalid placement to correct before deployment, not a silent cache miss. The other lines use the intended sections: token validation and rate limiting before forwarding, response-header removal after the backend responds.

Situation 01Write before you reveal
A developer, mid-incident, edits a rate-limit policy directly in the portal to unblock a partner, and says: "I'll put it in the repo later — right now I just need it live." How do you respond, in the moment and after?
Don't fight the emergency fix. Fight the "later" that never comes.
Reasoning

In the moment, check the blast radius. An emergency portal edit may be justified, but increasing a limit can expose the shared backend and other partners to the same flood. Confirm capacity, set a temporary value and owner, monitor load and 429s, and record the live change. The incident does not require pretending the repository already matches production.

After, capture the live change. The repository no longer describes the gateway. A later deployment may overwrite the portal edit, depending on how the pipeline applies policy. Record exactly what changed, test the emergency limit and reconcile it with the repository before the next deployment.

Before the next deployment, reconcile the change. Add the intended policy to the repository, review and test it, then compare the deployed policy with the live gateway. If the temporary change should be rolled back, document that decision too. The aim is a deliberate release instead of a surprise overwrite.

Situation 02Write before you reveal
An interviewer says: "Walk me through what happens to a request as it goes through an API Management policy pipeline — and tell me where teams most often get it wrong." You have two minutes.
Walk the four stages of Figure 1 in order, then land the red rail and the boundary.
Reasoning

Walk the stages in order, because the order is the point. "A request hits inbound first — that's where I authenticate it, rate-limit it, and shape it, so a bad or unauthorised call is rejected before the backend spends a cycle. If it passes, backend policies handle the forwarding — retries, timeouts. The response comes back through outbound, where I strip internal headers and cache. And underneath all three is on-error: anything that fails, at any stage, lands there." Naming inbound-first shows you understand why a gateway is cheap to say no with.

Then describe error handling accurately. "When APIM processing encounters an error, the remaining normal sections are skipped and on-error can shape what the caller sees. A rate-limit policy itself returns a 429 with a Retry-After header when its threshold is exceeded; do not credit on-error for that response. I keep sensitive diagnostics in logs and return only useful, safe details to the caller."

Close on where teams get it wrong: the boundary. "The recurring mistake isn't in the pipeline mechanics — it's people smuggling business logic into policy XML because it feels fast at the edge. Then a pricing bug lives somewhere no debugger looks. My rule is that policy stays traffic-shaped — auth, limits, caching, transforms — and anything about what the request means stays in the backend. Also: policies are code, so they live in the repo and ship through the pipeline, not the portal." Those two disciplines, said out loud, are what separate someone who has run an APIM in production from someone who has clicked through the portal once.

Examination record · first attempt
0/4
Class 38d · Complete
Retain this much

Five things worth carrying out of this part

  1. APIM policies add rules to the gateway's built-in routing. Choose the right scope and preserve intended inherited rules with <base />.
  2. Policies run in a fixed pipeline: inbound (before the backend), backend (the forwarding), outbound (the response), and on-error (any failure). Reject in inbound so a bad call costs nothing.
  3. Check each policy's supported section and tier. On Standard v2, rate-limit-by-key is available but quota-by-key is not; CORS is a browser rule, not caller authentication.
  4. Keep policy changes reviewed in the repository. If an emergency portal edit is necessary, capture and reconcile it before the next deployment.
  5. Policies stay traffic-shaped. Business logic in policy XML is a bug hunt in a place no debugger visits. The gateway decides whether and how; the backend decides what it means.
Notes
  1. Microsoft lists rate-limit-by-key for classic and v2 tiers, and quota-by-key for the classic Developer, Basic, Standard and Premium tiers. Neither is listed for Consumption. Rate limits use distributed counters, so the exact cutoff can vary. Check each policy's current usage and tier support before deployment. ↩
  2. A short-window rate limit reduces bursts. A longer allowance requires a quota or another supported design; quota-by-key is unavailable on Standard v2. A unique counter key per partner helps keep one partner's usage separate from another's. ↩