2

How to implement rate limiting for an AppSync API

 2 years ago
source link: https://advancedweb.hu/how-to-implement-rate-limiting-for-an-appsync-api/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

AppSync rate limiting

Rate limiting is an effective mitigation strategy for some types of attacks. For example, when a single source does an enumeration attack to try to guess a valid ID, or downloading data en masse. And, of course, against denial-of-service attacks when an adversary tries to overload the service to deny access to legitimate traffic.

AppSync supports control over the incoming traffic with authorizers, resolvers, and directives in the schema, none of them capable of implementing rate limiting. But it supports WAF, the AWS-managed firewall solution, that has rules for denying access based on IP addresses, geolocation, and request rate.

Note that rate limiting is per-source, so it won’t help against a distributed DoS attack, where the attack is coming from a lot of sources at once.

WAF config

Recommended book
How to design, implement, and deploy GraphQL-based APIs on the AWS cloud
Book, 2022

To add a rate limiter to an AppSync API, first create a WAF Web ACL and configure a rule for it.

waf_acl@1.25-22f30c30221bc976b696e88c9a85bf2ca4ed8ab8a1aca88c3cbb32cbb2d01843.png

Then the rate-limiter rule:

waf_rule@1.25-b06573cf677756ad1428fc6b38430a141bdd62a0d6640b90320a29decf4ec31a.png

WAF rules are JSON documents, so you can configure them by text:

{
	"Name": "rate-limit",
	"Priority": 1,
	"Statement": {
		"RateBasedStatement": {
			"Limit": 6000,
			"AggregateKeyType": "IP"
		}
	},
	"Action": {
		"Block": {}
	},
	"VisibilityConfig": {
		"SampledRequestsEnabled": false,
		"CloudWatchMetricsEnabled": false,
		"MetricName": "friendly-rule-metric-name"
	}
}

And to deploy this rule using Terraform:

resource "aws_wafv2_web_acl" "rate-limit" {
	rule {
		name     = "rate-limit"
		priority = 1

		action {
			block {}
		}

		statement {
			rate_based_statement {
				limit              = 6000
			}
		}

		visibility_config {
			cloudwatch_metrics_enabled = false
			metric_name                = "friendly-rule-metric-name"
			sampled_requests_enabled   = false
		}
	}
}

WAF rate limiting is based on a 5-minute window, so the number you specify is the number of allowed requests from a single source in any 5 minutes. Also, WAF supports combining different rules, so you can rate limit based on IP address or geolocation too. For example, you can have a “base country” where you define a higher rate limit and a lower one for everywhere else.

Associate with the API

The assocation is on AppSync’s side:

waf_associate@1.25-853cad268dd482eb2bed1da1970321d20b7022c519799a0006e86a9b3dbe99c2.png

With Terraform, you can use the aws_wafv2_web_acl_association resource to link the Web ACL and the API:

resource "aws_wafv2_web_acl_association" "appsync" {
	resource_arn = aws_appsync_graphql_api.appsync.arn
	web_acl_arn  = aws_wafv2_web_acl.rate-limit.arn
}

Having a “linking resource” comes with a nice property that any of the two resources can reference the other without creating a circular dependency.

Costs

WAF comes with its own pricing that is a combination of per-resource and per-request cost tags. Having Web ACLs and rules inside incur fixed costs even if nobody uses the API. Then the variable price tag adds to every request.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK