Document updated on Dec 12, 2022
Security Policies language and syntax
The policies language and syntax look nearly identical to C++, Go, Java, and Typescript and is based on Google’s CEL built-in functions and advanced macros. If you have existing validation using the CEL Component, you can also port them as policies.
Basic syntax
Data types
The supported data types are:
uint
(unsigned integer)int
(integer)double
(Number, float)string
(string)bool
(boolean)null_type
bytes
(on JSON mapping a string of base64-encoded bytes)map
(Object. e.g.,{}
)list
(Array. e.g.,[]
)duration
(e.g.,1h1m
for 1 hour and 1 minute)timestamp
(e.g.,timestamp(now)
returns in RFC3339 format including timezone2023-01-01T10:00:20.021-05:00
).dyn
the union of all other types.
In addition, you can cast some types using their type name as a function, for instance: int("23")
or double("21.3")
.
Logic and arithmetic operators
The logic operators are:
!
(not)==
(equal)!=
(unequal)&&
(and)||
(or)_?_:_
(ternary)<
,<=
,>=
,>
(ordering)
The arithmetic operators are:
%
(mod)*
(multiplication)+
(sum and concatenation)-
(subtract)/
(divide)
Accessing maps
A map
(also could be named object) is traversed with the dot operator .
, or using the syntax ['field']
. For instance, the map {"foo": {"bar": 1}}
can be accessed as foo.bar
and foo['bar]
equivalently. The second method is necessary when keys use characters like -
that can be interpreted as operators. E.g., req_headers['X-Forwarded-For']
.
If you want to test if a specific field exists in a map use has('field')
.
Functions and macros
For the complete list of supported functions and macros see:
Data variables
The following data variables are available inside the policies, depending on the context you set the policy:
- Use a
req_
type variable to access request data. - Use a
resp_
type variable to access response data. - Use the
JWT
variable to access the payload of the JWT (available onendpoint
context only if the namespaceauth/validator
is correctly configured).
Variables for requests
You can use the following variables inside policies:
req_method
: Returns the method of this endpoint, e.g.:GET
req_path
: The path used to access this endpoint, e.g.:/foo
req_params
: An object with all the placeholder{parameters}
declared in the endpoint.First letter capitalizedAll
req_params
capitalize the first letter.E.g., an
"endpoint": "/users/{id_user}"
will set a variablereq_params.Id_user
containing the value of the parameter passed in the request. When you use the sequential proxy you also have underreq_params.RespX_field
the response of a previous backend call (whereX
is the sequence number andfield
the object you want to retrieve.req_headers
: A map with all the headers received in its canonical form (converts the first letter and any letter following a hyphen to upper case; the rest are converted to lowercase. For example, the canonical key foraccept-encoding
isAccept-Encoding
). The value of the map is an array, as you can have a header declared multiple times (e.g., multiple cookies withSet-Cookie
). For example, you can access headers like this:req_headers['X-Forwarded-For']
.Do not forgetinput_headers
!Thereq_headers
variable won’t contain any headers that are not declared in theinput_headers
of the endpoint.req_querystring
: An Object with all the query strings that the user passed to the endpoint (not anything you wrote on the backendurl_pattern
). Remember that no query strings pass unless they are in theinput_query_strings
list. Notice that query strings, unlikereq_params
, are NOT capitalized. Thereq_querystring.foo
will also return an array as a query string can contain multiple values (e.g.,?foo[]=1&foo[]=2
). Most of the times you might wantreq_querystring.foo[0]
.Do not forgetinput_query_strings
!Thereq_querystring
variable won’t contain any query strings that are not declared in theinput_query_strings
of the endpoint.now
: An object containing the current timestamp, e.g.,timestamp(now).getDayOfWeek()
Variables for responses
You can use the following variables inside the policies:
resp_completed
: Boolean whether all the data has been successfully retrieved. When you use multiple backends, this information makes sense in theendpoint
context.resp_metadata_status
: Returns an integer with the status code. Only available when usingno-op
encoding.resp_metadata_headers
: Returns a map with all the headers of the response. Only available when usingno-op
encoding.resp_data
: An object with all the data captured in the response. Using the dot notation, you can access its fields, e.g.:resp_data.user_id
. If you use thegroup
operator in the backend, then you need to add it to access the object, e.g.,resp_data.mygroup.user_id
. Not available when usingno-op
.now
: An object containing the current timestamp
Variables for the JWT rejecter
You can also use CEL expressions during the JWT token validation. Use the JWT
variable to access its metadata in an endpoint
context. The namespace auth/validator
must be correctly configured. For instance:
has(JWT.user_id) && has(JWT.enabled_days) && (timestamp(now).getDayOfWeek() in JWT.enabled_days)
This example checks that the JWT token contains the metadata user_id
and
enabled_days
with the macro has()
, and then checks that today’s weekday is within one of the allowed days to see the endpoint.