Azure API Management
For Azure, the canonical managed-gateway pattern is APIM inbound policy calling Fairvisor decision endpoint before backend forwarding.
Architecture
Client -> Azure APIM inbound policy -> Fairvisor /v1/decision
| allow -> backend service
| reject -> 429 response
APIM policy sketch
Use inbound policy to call Fairvisor and branch on status:
<policies>
<inbound>
<base />
<send-request mode="new" response-variable-name="fvDecision" timeout="0.3" ignore-error="false">
<set-url>{{fairvisor-edge-url}}/v1/decision</set-url>
<set-method>POST</set-method>
<set-header name="X-Original-Method" exists-action="override">
<value>@(context.Request.Method)</value>
</set-header>
<set-header name="X-Original-URI" exists-action="override">
<value>@(context.Request.OriginalUrl.Path + context.Request.OriginalUrl.QueryString)</value>
</set-header>
<set-header name="Authorization" exists-action="override">
<value>@(context.Request.Headers.GetValueOrDefault("Authorization", ""))</value>
</set-header>
<set-header name="X-Forwarded-For" exists-action="override">
<value>@(context.Request.IpAddress)</value>
</set-header>
</send-request>
<choose>
<when condition="@( ((IResponse)context.Variables[\"fvDecision\"]).StatusCode == 429 )">
<return-response>
<set-status code="429" reason="Too Many Requests" />
<set-header name="Retry-After" exists-action="override">
<value>@(((IResponse)context.Variables["fvDecision"]).Headers.GetValueOrDefault("Retry-After", "1"))</value>
</set-header>
<set-header name="X-Fairvisor-Reason" exists-action="override">
<value>@(((IResponse)context.Variables["fvDecision"]).Headers.GetValueOrDefault("X-Fairvisor-Reason", "rate_limited"))</value>
</set-header>
</return-response>
</when>
</choose>
</inbound>
<backend><base /></backend>
<outbound><base /></outbound>
<on-error><base /></on-error>
</policies>
Adjust policy syntax for your APIM tier/runtime version.
Failure policy
Decide behavior when Fairvisor is unavailable:
- fail-closed: return 503/deny from policy
- fail-open: skip deny and continue to backend
Use route-based split from Gateway Failure Policy.
Timeout guidance
- keep decision timeout low (200-500 ms budget)
- avoid retries in inbound policy hot path
- alert on timeout spikes and downstream dependency errors
Security notes
- Keep Fairvisor on private network path (VNet/private endpoint where possible)
- Limit callers to APIM boundary only
- Do not trust external
X-Original-*headers from clients
Verification checklist
- Allowed request reaches backend
- Limited request returns
429withRetry-After X-Fairvisor-Reasonvisible in logs and response- Outage drill validates chosen fail-open/closed behavior
See Decision API for canonical header contract.