Skip to content
Notifications
Clear all

Total newb: What's a good first rule to write for a public API?

4 Posts
4 Users
0 Reactions
5 Views
(@amandaj)
Reputable Member
Joined: 1 week ago
Posts: 148
Topic starter   [#3727]

As a practitioner primarily focused on analytics and user behavior, I've found that securing a public API shares a foundational principle with setting up a proper experiment: you must first establish a baseline control to filter out irrelevant noise. For a public API, this initial "control" is often a rate limiting rule. It is the most pragmatic first rule because it directly mitigates brute-force attacks, credential stuffing, and unintended resource exhaustion, which are among the most common and immediately damaging threats to an exposed endpoint.

When configuring AWS WAF as your first line of defense, I recommend starting with a rate-based rule (RBR) on what you deem your most critical POST or login endpoint. The objective is to allow legitimate user traffic while curtailing automated abuse. A methodical approach involves:

* **Initial Baseline Measurement:** Before deploying the rule, analyze 7-14 days of traffic logs (CloudWatch Logs Insights is suitable here) to establish a legitimate request-per-minute baseline for a single IP address. Look at the 95th or 99th percentile to avoid outliers.
* **Conservative Initial Threshold:** Set your first threshold slightly above this measured baseline. A common starting point for a login API might be 100 requests per 5-minute period from a single IP, but this is highly dependent on your product's usage patterns.
* **Action:** Start with a `Count` action for a monitoring period, then move to `Block`.

A basic CloudFormation snippet for such a rule might look like this:

```yaml
MyFirstRateLimitRule:
Type: AWS::WAFv2::RuleGroup
Properties:
Capacity: 100
Scope: REGIONAL
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: MyFirstRateLimitRule
Rules:
- Name: RateLimitLoginAPI
Priority: 1
Action:
Block: {}
VisibilityConfig:
SampledRequestsEnabled: true
CloudWatchMetricsEnabled: true
MetricName: RateLimitLoginAPI
Statement:
RateBasedStatement:
Limit: 100
AggregateKeyType: IP
ScopeDownStatement:
AndStatement:
Statements:
- ByteMatchStatement:
FieldToMatch:
UriPath:
MatchPattern:
Contains: "/api/v1/auth/login"
PositionalConstraint: CONTAINS
SearchString: "/api/v1/auth/login"
TextTransformations:
- Priority: 0
Type: NONE
- ByteMatchStatement:
FieldToMatch:
Method:
MatchPattern:
Contains: "POST"
PositionalConstraint: EXACTLY
SearchString: "POST"
TextTransformations:
- Priority: 0
Type: NONE
```

Key considerations for your first rule:
* **Evaluation & Iteration:** This rule must be treated as a hypothesis. You will need to monitor CloudWatch metrics for false positives (blocked legitimate users) and adjust the threshold accordingly. Consider creating a dashboard for this rule's metrics.
* **Complementary Logging:** Ensure your Web ACL is configured to log all requests to an S3 bucket or CloudWatch Logs. This log data is critical for post-incident analysis and refining your rules.
* **Next Steps:** After stabilizing this rule, your subsequent rules should likely focus on the OWASP Core Rule Set (CRS) to address common injection attacks, followed by custom rules tailored to your specific API schema and expected payload structures.

— Amanda


Data > opinions


   
Quote
(@latency_llama)
Estimable Member
Joined: 3 months ago
Posts: 83
 

Rate limiting as a first rule is sensible, but starting with a static threshold based on a 7-14 day log analysis is a fantastic way to get paged at 3 AM after your first marketing campaign or a post on Hacker News. Your "legitimate request-per-minute baseline" is a snapshot of the past, not a prediction of legitimate future traffic. I'd argue the first rule should be a *dynamic* one that looks for a spike anomaly relative to that IP's own recent history, not a global number. Otherwise you're just choosing which legitimate surge you want to block.

Also, while you're setting up CloudWatch Logs Insights to find that 99th percentile, your API is already getting credential-stuffed. Deploy the rule first with an absurdly high threshold just to get the metric flowing into your dashboard, *then* tune it. The real first rule is whatever gets you actionable, real-time data the fastest. Vanity metrics about "blocked requests" are useless if you can't correlate them to user-visible tail latency.


P99 or bust.


   
ReplyQuote
(@martech_curious)
Eminent Member
Joined: 3 months ago
Posts: 30
 

Okay, that baseline analysis makes sense for setting a starting point. But what do you do if you have a brand new API with no logs yet? Just guess a threshold and hope?



   
ReplyQuote
(@masonk)
Eminent Member
Joined: 1 week ago
Posts: 10
 

>Before deploying the rule, analyze 7-14 days of traffic logs

Great process. That's the gold standard, but you're right to highlight it as an upfront step. A lot of folks just start blasting out a rule without that baseline and shoot themselves in the foot.

My practical twist on this is to use an API monitoring tool for the analysis, even a simple one. I like to trace the actual user journeys hitting the endpoint during that 7-14 day window. It's not just about counting requests, it's about seeing if those spikes are tied to real user sessions or just random noise. That way, when you set that 99th percentile threshold, you're more confident you're not locking out someone on a bad hotel wifi who's just really enthusiastic about your product.

Helps avoid those "why is our most active customer getting blocked?" support tickets later on.


Attribution is hard, but we can get closer


   
ReplyQuote