AWS API Gateway
For AWS, the canonical pattern is API Gateway with a Lambda authorizer that calls Fairvisor POST /v1/decision.
Architecture
Client -> API Gateway -> Lambda authorizer -> Fairvisor /v1/decision
| allow
v
Backend integration
| reject
v
429 to client
Authorizer request mapping
Your authorizer should pass to Fairvisor:
X-Original-Methodfrom incoming methodX-Original-URIfrom path + queryAuthorizationfrom request headers (if present)X-Forwarded-Forfrom request context source IP
Lambda authorizer sketch (Node.js)
export const handler = async (event) => {
const method = event.requestContext?.http?.method || event.httpMethod || "GET";
const path = event.rawPath || event.path || "/";
const query = event.rawQueryString ? `?${event.rawQueryString}` : "";
const originalUri = `${path}${query}`;
const headers = {
"X-Original-Method": method,
"X-Original-URI": originalUri,
};
const auth = event.headers?.authorization || event.headers?.Authorization;
if (auth) headers.Authorization = auth;
const ip = event.requestContext?.http?.sourceIp || event.requestContext?.identity?.sourceIp;
if (ip) headers["X-Forwarded-For"] = ip;
const res = await fetch(`${process.env.FAIRVISOR_EDGE_URL}/v1/decision`, {
method: "POST",
headers,
});
if (res.status === 429) {
return {
isAuthorized: false,
context: {
fairvisor_reason: res.headers.get("x-fairvisor-reason") || "rate_limited",
retry_after: res.headers.get("retry-after") || "1",
},
};
}
if (!res.ok) {
// choose route policy: fail-open or fail-closed
return { isAuthorized: false };
}
return { isAuthorized: true };
};
Gateway response mapping
Configure API Gateway deny responses to preserve 429 semantics and surface:
Retry-AfterX-Fairvisor-Reason
If your authorizer path can only return generic deny, add integration response mapping so client still sees meaningful rate-limit metadata.
Failure policy
Decide explicitly per route class:
- write/admin routes: fail-closed
- public/read routes: fail-open only with alerting
Reference: Gateway Failure Policy.
Timeout guidance
- authorizer->Fairvisor timeout: 200-500 ms target
- avoid retries in authorizer hot path
- monitor p95/p99 authorizer latency
Security notes
- Do not expose Fairvisor publicly; keep it in private network path
- Trust
X-Original-*only from the authorizer boundary - Keep
FAIRVISOR_EDGE_URLin secure runtime config
Verification checklist
- Confirm allow path succeeds through API Gateway
- Trigger limit and verify client receives
429 - Confirm
Retry-AfterandX-Fairvisor-Reasonpropagation - Simulate Fairvisor outage and validate fail-open/closed behavior
See Decision API for contract details.