Advanced policy expressions using API specification
You can import unified API specifications onto the Web App Firewall imports page and then create an advanced policy expression using the API specifications. You can configure the appropriate actions for the incoming API traffic based on the expressions. An API specification contains the endpoint, schema, and parameters. The incoming API traffic can be of type gRPC or REST.
You can use the
http.req.api expression to identify the endpoints in the incoming requests defined in the API specification.
Syntax:
http.req.api (“API_Spec_Name”)
Examples:
set responder policy reject -rule "!http.req.api(\"myspec\").endpoint(\"POST"\",\"/v1/pet/\").exists"
set responder policy reject -rule q{!http.req.api("myspec").endpoint("POST","/v1/pet/").exists}
In this example, if the incoming request does not have
POST request to the /v1/pet/ endpoint, as defined in the myspec API specification, the request is rejected.
set responder policy reject -rule !"http.req.api(\"myspec\").EXISTS
In this example, if the incoming request does not match any defined endpoint in the
myspec API specification, the request is rejected.
Advanced policy expression for API schema
You can create advanced policy expressions for the API using the following operations:
Prerequisites.
Import the API specification file using the import option in the Web App Firewall.
For more information, see Imports.
Expression to match traffic by HTTP method
Use an HTTP string method to restrict matching APIs. This string can contain one or more HTTP methods separated by "|" or can contain a wild card (*). When more than one method is specified, the expression evaluates to an OR condition between the methods.
For example, GET or PUT or DELETE matches an incoming request with the HTTP method GET OR PUT OR DELETE.
Example:
-
Single HTTP method
http.req.api("petstore").method("POST").text("id").eq("1") -
Multiple Method
http.req.api("petstore").method("GET|DELETE").exists
Expression to match traffic by URL
PATH (URL string) is used to match the endpoints that include wildcards. The single asterisk (*) matches a single segment while the double asterisk (**) matches all possible segments prefixed before the double asterisk.
Example:
-
http.api("petstore").path("/v1/pets/*/find")It matches the incoming traffic only with/v1/pets/*/find -
http.api("petstore").path("/v1/pets/**")It matches all endpoints starting with/v1/pets
Expression to match traffic by API name
Use the APINAME (name string) expression to restrict the matching traffic by API name. You can also use the API name string by running the show command as shown in the following example:
show api spec gspec
Name: gspec
File: gfile
Type: OAS
-
The
operation IDserves as the endpoint name if the file type is OAS.Example: To validate the incoming traffic against the endpoint from the following OAS:operationId: adexchangebuyer.accounts.listUse the following policy expression:http.req.api("schema").apiname("adexchangebuyer.accounts.list").exists -
The
service nameandrpc nameserves as the endpoint name if the file type is proto.In the following example, EchoService.Echo is the endpoint: service EchoService { rpc Echo(EchoReq) returns (EchoResp) { option (google.api.http) = { get: "/v1/{name=messages/*}" }; } }
Access values from the API specification
You can access the fields in the API specifications by name, path, query parameters, JSON body, or gRPC body. To define the type of the parameter, use PI expressions. The following types are supported:
-
num - An integer value.
-
ulong - A long integer value.
-
bool - A boolean value.
-
double - A double value.
-
text - A string of any length.
Example: To validate the incoming traffic using numeric parameter that matches the value one, use the following expression:
http. req.api("petstore.proto"). APIName ("TestPet").NUM("test_num1").eq(1)
Access value from the repeated fields
To access repeated objects in APIs, use the second parameter as the repeating index. Accessing outside the array results in an undefined value.
Example:
To retrieve the fifth tag in the 'FindPets' endpoint use:
http.req.api("petstore.proto", "FindPets').TEXT( "tags", 5 ).contains("mytag")
To retrieve the fifth tag in the repeated tags string, use:
/v1/pets?tags=1&tags=2&tags=3&tags=4&tags=mytag&tags=6
Access values from the nested objects
Objects can be nested inside other objects. The same field name can occur in nested objects in the same document. However, the full access name must still be unique. To access nested fields, concatenate the field names with a "." (dot) as a separator.
Example: use kennel.location.state to retrieve California from the following JSON.
{ "kennel" : { "location" : { "state" : "California" } } }
Expression
http. req.api("petstore.proto", "TestPet").text( "kennel.location.state" ).contains("California")
Access value using object expression
The Object() expression is used when accessing subfields of repeated objects. If there are two or more objects configured with different values, you can create an expression to validate the object specific to one value. For example, in the following JSON body, the object “foo” has two values, which are one and none. { "foo" : }
To compare the value to none, you can configure the expression as follows:
HTTP. req.api("schema").object("foo",1).text("bar").eq("none")