Search code examples
google-cloud-platformgoogle-cloud-armor

Regex pattern match is not working with Google Cloud Armor Security Policy


I am trying to implement rate limiting for GET and POST for the same API call. The only difference in both the request is extra ID we are passing with POST.

GET  /rest/v1/add 
POST /rest/v1/add/some-alpha-numeric-id-001

Since these are two separate request so I am trying to implement rate limiting for both.

    #To match GET Request 
    match {
      expr {
        expression = <<EOT
request.path.matches(R"\/v1\/add$")
EOT
      }
    }

    #To match POST request
    match {
      expr {
        expression = <<EOT
request.path.matches(R"\/vi\/add\/.+")
EOT
      }
    }

Do you have any suggestions to implement the rate limiting for both GET and POST request?
If I am using only request.path.matches("/v1/add") then it will obviously apply on both the but I am trying to setup different threshold for both request.

PS: I got to know about RAW pattern matching from here.
Regex Pattern Match Reference: https://regex101.com/r/zo3W5z/1


Solution

  • First, this smells a bit

    GET  /rest/v1/add 
    POST /rest/vi/add/
    

    as your POST match rule mentions /vi/add/.+ when it seems it rather should be /v1/add/.+ if you are following a consistent versioning scheme (rest of my answer assumes this is a typo to be corrected).

    Next, to the main point - you'll need to set up separate rate limiting rules that distinguish between these requests using regexp and additional conditions to differentiate by HTTP method, like this:

    # Rate limiting for GET
    match {
      expr {
        expression = <<EOT
    request.method == "GET" && request.path.matches(R"\/v1\/add$")
    EOT
      }
    }
    
    # Rate limiting for POST
    match {
      expr {
        expression = <<EOT
    request.method == "POST" && request.path.matches(R"\/v1\/add\/[a-zA-Z0-9-]+")
    EOT
      }
    }