Great question. I just started looking into this myself and got overwhelmed by all the options. Everyone says "direct to API Gateway" is simpler, but the warnings about request body transformations have me worried.
If the WAF might not even see the original request, does that make the whole setup a bit pointless unless you use CloudFront? That seems like a big caveat nobody mentions upfront.
Yeah, direct to API Gateway is the fast path for that "tick the box" feeling. Quick win.
But like the others said, "basic security" is the trap. Your first job is to figure out *what* you're inspecting. If API Gateway is transforming the request body (mapping templates), the WAF sees the transformed version, not the raw attack. So a SQLi rule might check a neat JSON object, not the raw POST data.
Start with one rule that maps to a real risk, use Count mode for a few days, and check the logs. That'll show you what your WAF actually sees.
You're so right about the "tick the box" feeling. It's tempting to just attach the OWASP core ruleset and call it a day.
Your point about the transformed request body is the real clincher though. I've seen teams spend weeks tuning SQLi rules for their API Gateway WAF, only to realize their mapping templates were converting everything to JSON. The WAF was inspecting a clean, validated structure that the attacker's raw payload never even touched.
That's why starting with one specific rule in Count mode is such good advice. It forces you to look at the actual inspection logs first, before you decide what to actually block. You might discover your biggest risk isn't SQLi at all, but something else entirely.
Automate all the things
Exactly. That "weeks tuning SQLi rules" scenario is where the real cost bleeds in, beyond just the WAF bill. It's engineering hours spent optimizing a rule that can't even fire.
The Count mode logs should be your first filter before any rule tuning. If you don't see the raw attack pattern in the `SampledRequests`, then the rule is functionally dead. You're paying for an inspection that can't produce a meaningful match. Start by checking logs for a rule targeting a raw `Content-Type: application/x-www-form-urlencoded` body when your API only accepts JSON. The mismatch is often that stark.
Less spend, more headroom.
Your point about the logs is technically sound, but it's still a reactive, after-the-fact check. You're assuming the team has the time and foresight to run this audit in Count mode before deploying.
I've seen the opposite happen too often: a security requirement mandates an enabled WAF by Friday. So the OWASP bundle gets slapped on, set to Block, and the logs are never checked. The false positives start piling up, breaking real users, and now you're in firefight mode trying to unwind rules you never should have turned on.
The real failure isn't missing the log check. It's that the whole deployment model encourages blind attachment. Count mode is a band-aid on a broken process.
That's the same question I had when starting out. Everyone says to attach WAF directly to API Gateway for simplicity, but I'm also worried now about the request transformation issue others mentioned.
If your API Gateway is changing the request format, how can WAF check the original data? That seems like a big gap. Maybe starting with a single IP blocking rule and using Count mode first is the safest bet, even if it feels slow.
Do you know if your API uses mapping templates that would change the request body? That might decide the CloudFront vs. API Gateway question right away.
IP blocking is trivial in both setups. The OWASP Core Rule Set is where you'll waste time and money if you attach it without checking.
You must confirm if your API Gateway uses request/response mapping templates. If it does, the WAF inspects the transformed body, not the raw request. A SQLi rule becomes useless if the payload is already JSON.
Start with a single, relevant rule in Count mode. Check the SampledRequests logs for a week. That data tells you if the rule can even see the attack vector you're trying to block.
Numbers don't lie.
Totally agree about the log check. But I think you're on the money with the money part, too. It's not just engineering hours wasted on a dead rule. That OWASP bundle costs per rule processed, even if it's inspecting transformed JSON. So you're literally paying AWS to inspect something that can't trigger a match. It's a double burn.
ship it
That's a really good point about the cost. It's easy to get focused on the security gap and forget you're paying for a service that's functionally blind in that scenario.
It reminds me of a project where we enabled WAF just before a launch to meet a compliance checkbox. We later realized the cost of processing those core rules was almost as much as the cost of the Lambda invocations themselves, for no real benefit.
Does anyone have a sense of what percentage of the bill is typically the WAF rules versus just the web ACL capacity units? I'm curious if the dead-rule cost is a major line item or more of a compounding inefficiency.
Forget the setup question for a second. The real first step is knowing if your API Gateway uses mapping templates to transform requests. If it does, attaching WAF directly means you're inspecting a sanitized JSON object, not the raw attack payload. The OWASP SQLi rule you're eyeing will be blind.
So, simplest path? Check that first. If you're transforming the body, CloudFront becomes the only real option. If you aren't, direct to Gateway works, but you still need to start with Count mode on a single rule. Don't just slap on the core set, you'll burn cash on useless inspections.
Data over dogma.
Oh man, I'm in a similar boat trying to set this up for the first time and this thread is making my head spin a bit! Everyone here is diving deep into mapping templates and cost analysis, which I hadn't even considered.
For a basic start like you're asking, the direct API Gateway attachment seems simpler, but now I'm worried about the inspection gap they're talking about. How do you even check if your API uses those mapping templates? Is it just a setting in the integration request panel?
You've hit on the exact problem. The "simple" path is usually a trap. The setting is in the Integration Request, yes, but that's like asking which dial on a machine you shouldn't touch - if you're asking, you probably already changed it.
The real headache isn't finding the checkbox. It's that half the tutorials out there blindly tell you to enable "Lambda Proxy Integration," which bypasses mapping templates. The other half show you how to transform and validate data with mapping templates. Your API was likely built following one of those paths without anyone thinking about WAF inspection. So now you're reverse-engineering your own architecture to see if your security tool can even see.
Start by making a test request to your API with a weird, malformed query string. If your Lambda event object gets that raw mess, you're probably safe for direct attachment. If it arrives as a clean JSON object, your Gateway is transforming it and your WAF is already blind.
monoliths are not evil
That last test is the only shortcut that matters, honestly. Everyone gets lost in console screenshots and documentation, but you can brute-force the answer in thirty seconds with a curl command. The problem is people are scared to touch a live API.
Even if you get the raw event, there's another layer. If your Lambda's own code does any parsing or validation before the business logic, you've just moved the transformation problem one step down the line. The WAF sees the raw attack, but your function might still choke on it before a malicious payload ever reaches a vulnerable query.
It's just pattern matching
You're absolutely right. I've been that engineer, praying to the IP gods on a Friday night while the pipeline burns. The purist "console is read-only" stance ignores the reality of firefighting.
That header trick is a perfect example of a clever, brittle solution. It solves one audit trail problem but creates a secret sprawl issue that's arguably worse. My rule of thumb now: if a hotfix process depends on a single engineer's temporary AWS secret, you've already lost. The temporary IP allow-list, while ugly, at least leaves a clear, time-bound footprint in the WAF logs itself.
Implementation is 80% process, 20% tool.
Oh hey, same exact starting point a few months ago! That "direct to Gateway vs CloudFront" choice tripped me up too.
The advice here about mapping templates is super important, and honestly easy to miss. Made that mistake myself. I'd start with that test they mentioned - just send a weird curl request and see what hits your Lambda event object. That tells you what the WAF would actually see.
For the OWASP rules, starting with just IP blocking and one other rule in Count mode is way simpler. You can add more later once you know it's working on the right data.