Governance Specification Language (GSL)
CloudGuard Governance Specification Language (GSL) is a syntax to define posture management rules, which can be included in rulesets in the CloudGuard Posture Management. GSL has a core language augmented by a set of functions that add domain-specific functionality for different cloud providers (AWS Amazon® Web Services. Public cloud platform that offers global compute, storage, database, application and other cloud services., Azure
Collection of integrated cloud services that developers and IT professionals use to build, deploy, and manage applications through a global network of data centers managed by Microsoft®., GCP
Google® Cloud Platform - a suite of cloud computing services that runs on the same infrastructure that Google uses internally for its end-user products, such as Google Search, Gmail, Google Drive, and YouTube., Alibaba Cloud, and Kubernetes
Kubernetes, often abbreviated as “K8s”, orchestrates containerized applications to run on a cluster of hosts.). These functions include IP addresses and networking, cloud entities such as instances, strings matching, date & time, etc.
Use Case
GSL is used to create compliance rules and Intelligence queries that you can run on your cloud environments to assess them. CloudGuard provides a graphical interface called GSL Builder or GSL Editor that helps you build the rule in the applicable context. For more information, see GSL Builder.
Rule Syntax
GSL rules have the form:
|
The Target is the cloud entity type that the rule checks, for example, instance or SecurityGroup. Each rule can check only one target.
You can qualify the target to match a smaller set of entities that you add with the where keyword.
The formal definition of the target is:
|
Where:
-
entity_type - The pivot cloud entity type that CloudGuard checks, for example, Instance, SecurityGroup, ELB.
-
expression - Can be any complex GSL expression to match the target entity type.
Examples:
|
|
The Condition is the actual essence of the rule. It contains the attributes of the target that CloudGuard examines. The condition can be a complex GSL expression that tests some attributes related to the target.
Context Travel
When you use a command that references an array (with, contain, contain-any, contain-all, contain-none, groupBy
, and so on), you execute an action that searches in the array's internal objects.
Each time you use array commands, you create a new context and delve deeper into the array. In a sense, you travel deeper into the child objects of the array which themselves can also be arrays. This is called child context travel.
You can use commands to refer back to the parent context and return to the parent array.
To do this, you can use some types of commands. Each command has a text representation and a symbol representation.
Command Symbol |
Command Text |
Description |
---|---|---|
$ |
this() |
Reference the current array context level. The current array you have reached in the GSL query |
~ |
root() |
Reference the topmost level of the array context. The root level of any GSL query is the asset itself. |
^ |
parent(n) |
Reference the n level above the current array context. |
To travel more than one context level, type more than one symbol (^^ or ^^^) or use its text equivalents, such as parent(2) or parent(3).
Expressions

The % wildcard indicates zero or more characters.
For example, like '%er' matches the strings 'smarter', 'lover', 'her', etc.
The % wildcard can appear a number of times in an expression. For example, like '%DB%' matches 'MongoDB', 'DB123' and 'prodDB_111'.
Wildcards are used with Like and Unlike.

These expressions are of the form:
|
Where:
-
property_name - The applicable property of the entity being tested.
-
comparison_operator - One of the operators: = , < , >, !=, <=, >= , like.
-
expected_value - An expression you want to test with (can be a string, number, a different property, or a function result).
Examples:
|
|
|
The 'Like' Comparison Operator
The GSL like operator is almost the same as to 'like' syntax in SQL. It allows you to match text with wildcards (%). You can like on string values.
The like comparisons are case-insensitive, meaning that 'a' like 'A' is true.
Example:
|
The 'Unlike' Comparison Operator
The unlike operator is the opposite of like.

The keyword have is not mandatory. It makes a rule more readable. The GSL parser removes it when processing the rule.
This means the second example can be:
|
It is useful when you write rules that are also human-/auditor- readable.

The 'in' built-in function verifies that a given object's property value is found in a list of user-defined values.
Syntax:
|
Examples:
|
|
|

This rule makes that a property of the type 'list' contains a specific item. The syntax allows you to build complex expressions to find or match an item.
Syntax:
|
Where:
-
property_name - The property of the entity being tested.
-
containment-operator - Is one of the following:
-
contain or contain-any - Are syntactically the same and return a Boolean True or False result.
These options allow you to build rules that look correct in English. If any of the collection elements satisfies the query expression, then the full 'contain' statement is considered dsatisfying.
-
contain-all - Requires all elements in the collection to satisfy the expression and returns a Boolean True or False result.
-
contain-none - Requires none of the elements in the collection to satisfy the expression, and returns a Boolean True or False result.
-
with - Is almost the same as contain, but returns a list of elements matching the expression (where the number of items in the list can be counted).
-
-
Expression - In the square brackets block
[ ]
can be any complex GSL expression. It defines the query to test each collection item with.If the list is blank, the expression returns as False.
Examples:
-
Iterate each rule in the SecurityGroups' inboundRules collection. Each rule is matched with the properties of port and scope:
SecurityGroup should have inboundRules with [port=22 and scope='0.0.0.0/0']
-
This example is a nested expression - the outer 'with' iterates each nic in the nics collection, and the inner 'contain-any' iterates each security group:
Instance should not have nics with [securityGroups contain-any [name='default']]

These expressions make sure that a property exists and that it is not empty.
CloudGuard can identify if a property type is empty, including empty collections, empty objects, null, 0, or empty strings.
Syntax:
|
Examples:
-
These are equivalent:
Instance should have vpc
Instance should vpc
Instance should have not vpc isEmpty()
-
These are equivalent:
SecurityGroup where outboundRules...
SecurityGroup where outboundRules.length >0

These are regular expressions that match the text in an entity name or element.
Syntax:
|
Example:
|

You can make complex expressions from multiple simple ones with the operators and, or, not, (<expr>)
AND
Make sure that the two sides of the and keyword are true.
Syntax:
|
Examples:
-
The instance should satisfy the existence of property (name), and the existence of an element in a collection (tags). It could also be written as two separate rules.
Instance should have name and tags with [key='owner']
-
A rule that cannot be logically split as each element is validated considering the two conditions:
SecurityGroup should not have inboundRules with [port=22 and scope='0.0.0.0/0']
OR
Make sure that the each side of the or keyword is a true expression.
Syntax:
|
Example:
|
NOT
Satisfies (return true) if the following expression is false, and vice versa.
Syntax:
|
Example:
|
Parenthesis
Use parenthesis "(", ")" for complex expressions that contain multiple and and or expressions, to remove ambiguities.
Syntax:
|
Example:
|
|
Note - Without the parenthesis, this rule is ambiguous:
Because it is not understandable if you mean:
The parser uses one of the options, but it is recommended not to rely on an undocumented default implementation, and as an alternative, use '( )' to make the expression unambiguous. |

This expression enumerates a list of items (defined by the following clauses in the GSL rule). The expression can be used with the items and with keywords, after which additional expressions can then be added. The target of the operation is the full list of items. If one or more items in a list fail a rule condition, the result of the rule evaluation is 'fail'. But, in an assessment, this is considered as one failure.
List expressions can also be used with the groupBy keyword to evaluate the number of items in an enumerated list. Grouping aggregates items (in a list-type data entity) by a specific attribute, which can then be used in logical expressions.
Syntax:
|
Example:
-
This enumerates a list of instances, and checks that their number is less than a limit.
List<Instance> should have items length() < 50
-
The with keyword is used to filter the list for a specific name before it is enumerated, and then the result is checked with a condition.
List<Instance> should have items with [name like 'db'] length() < LIMIT
-
This enumerates the Security Groups in each VPC, and checks that there are less than 100 in each (the AWS limit).
List<SecurityGroup> should have items groupBy [vpc.id] contain-all [values length() < 100]
Data Types
GSL has different syntax for strings (textual values) and numeric values.

Strings are surrounded by single quotation marks. For example, 'my string value'.

Numbers are written without quotes.
Example:
|

List entities have a length property (entity.length). For example, inboundRules, in the example above. As an alternative, use the length() function.
Examples:
|
|
Functions
The core GSL syntax is enriched by internal functions that provide domain-specific functionality in multiple areas such as IP addresses, dates, and string matching.
Syntax:
|
Where:
-
property_name is the property/object we wish to operate on (equivalent to functions in object-oriented languages)
-
function_name is the name of the functions from the above list params the required parameters based on the type of the function, separated by
General Functions

Checks if the object/property is empty based on the property type. It returns 'false' for empty collections and empty objects (and as null values, 0 empty strings)
Parameters:
None
Example:
These are equivalent:
|
|

Returns the length of a list. Follow this function with a comparator: >, <, =, >=, <=, !=.
Parameters:
None
Example:
|

Returns 'true' if the attribute value is contained in the provided list of values.
Parameters:
List of values to match.
Example:
|

Splits a string based on a provided separator and converts it into an array
Parameters:
Position |
Description |
Values |
---|---|---|
1 |
Separator |
The separator to use when splitting the string |
Example:
Make sure that the instance name format is x-y-z (more tests could be applied on x, y and z)
|

Concatenates multiple strings into one string. This function can be useful to dynamically concatenate entity attributes.
Parameters:
Position |
Description |
Values |
---|---|---|
1 |
Separator |
The separator to use when concatenating the strings |
... |
Strings |
The strings to concatenate |
Example:
Make sure that the instance name is in the format "PROD-<Instance ID>
" (for example, PROD-i-a0b01c01
).
|

Returns true if the attribute value contains the environment ID or is equal to it.
Parameters:
None
Example:
|

Returns 'true' if a target property has values identified as secrets. The function works with entities, inner object, arrays, and single-string properties.
Parameters:
None
Examples:
-
All the instance fields and subfields should not have secrets.
Instance should not containSecrets()
-
EcsTask should not have an inner vpc object that has fields containing secrets.
EcsTask should not have vpc containSecrets()
-
None of the tags of the instance should contain secrets.
Instance should not have tags containSecrets()
-
IAM
Identity and Access Management (IAM) - A web service that customers can use to manage users and user permissions within their organizations. role should not have external findings with resource names that contain exposed secrets.
Iam should not have externalFindings.findings with [ resourceName containSecrets() ]
Networking Functions - General

Checks for the existence of publicly routable (for example, non-RFC 1918 [1]) IPv4 addresses.
This function is context-dependent.
When isPublicCIDR refers directly to a cloud "workload" resource (for example, virtual devices, entities such as EC2 Amazon EC2 - A web service for launching and managing Linux/UNIX and Windows Server instances in Amazon data centers., that are commonly associated with a NIC), isPublicCIDR=true indicates that the workload resource has one or more NICs that are currently associated with one or more publicly routable IPv4 addresses. In this context, the function should be referenced without parenthesis (isPublicCIDR, and not isPublicCIDR()).
Example:
This Compliance rule is applied only to EC2 Instances that have one or more NICs that are currently associated with one or more publicly routable IPv4 addresses.
|
When isPublicCIDR refers directly to anything other than a cloud "workload" resource for example, then any list-like set of access rules (such as an SG, NSG, NACL, and more), or to a specific access rule (SG Rule, NACL Rule, RouteTable Route, and more), isPublicCIDR()=true indicates that the rule's scope or source (as in, the external endpoint) is a publicly routable (non-RFC1918) IPv4 address or CIDR prefix. In this context, the function should be referenced with parenthesis (isPublicCIDR(), and not isPublicCIDR).
Note that public cloud identifiers (for example, a Security Group A set of access control rules that acts as a virtual firewall for your virtual machine instances to control incoming and outgoing traffic. ID in AWS) are always interpreted as isPrivateCIDR, even if the identified public cloud resource is indirectly related to or in use by public cloud resources that themselves have public IP addresses. For example, the rule below always returns a "Compliance" finding for Security Group access rules with a SG-ID source. This is regardless of the source SG-ID is used by cloud resources that have public IP addresses.
|
Example:
This Compliance rule applies only to EC2 Instances currently configured with a minimum of one Security Group that contains at minimum one Inbound access rule that permits ingress on any Protocol/Port combination from a publicly routable IPv4 address or CIDR prefix.
|
|
Note - When applied directly to workload resources (EC2s, and more), the value of isPublicCIDR is not affected by any Security Group or access rule-related conditions. When applied directly to access rule-related structures (SGs, NACLs, and more), the value of isPublicCIDR() is not affected by any NIC-to-IP address associations. |
Parameters:
None

Counts the number of possible IP addresses in the provided CIDR. It removes the broadcast address
Parameters:
None
Example:
|

Operating on an IP address or a CIDR network and testing if it is fully contained in any of the provided networks.
Parameters:
List of CIDRs representing networks to test
Example:
This rule checks that there is no SSH connection from non-local or 'friendly' networks: '1.2.3.4/10','5.6.7.8/24'
|

Operating on an IP address or a CIDR network and testing if it has some overlap with any of the provided networks.
Parameters:
List of CIDRs representing networks to test
Example:
In this example, '10.1.2.0/24','192.168.100.0/24' (internal) networks belong to a third party peered with our VPC. Make sure that you do not allow these networks to SSH into the servers.
|

Check if a field is in CIDR format.
Parameters:
None
Example:
|

Checks if the attribute references a Security Group.
Some attributes can contain multiple types of objects (that is, a Security Group or a CIDR). This function determines if the value is a Security Group.
Parameters:
None
Example:
This example makes sure that security groups should only allow traffic from a different security group, and not a CIDR
|
Networking Functions for AWS NACL and MS Azure NSG
AWS NACL and MS Azure NSGs have different firewall semantics.
The firewall rules are in an order and may contain explicit 'DROP'. This makes the order of the rules very important.
These functions operate on a list of rules.

Returns the number of IP addresses (hosts) that can be connected to the applicable port protected by this firewall.
Parameters
Position |
Description |
Values |
---|---|---|
1 |
Port number(mandatory) |
any valid port number, such as 22, 80, and so on |
Example:
This rule prevents having overly permissive port 22 (that is allowed to more than 256 addresses). This is a rule for Azure Virtual Machines.
|

Returns the number of public IP addresses (hosts) that can be connected to the applicable port protected by this firewall.
Parameters:
Position |
Description |
Values |
---|---|---|
1 |
Port number(mandatory) |
any valid port number, such as 22, 80, and so on |
Example:
This rule prevents having overly permissive port 22 (that is allowed to more than 256 addresses). This is a rule for Azure Virtual Machines.
|

Returns 'true' if the provided IP addresses / CIDRs are allowed to connect to the specified port.
This method returns 'true' if one or some of the addresses in the provided CIDRs are allowed to connect.
Parameters:
Position |
Description |
Values |
---|---|---|
1 |
Port number (mandatory) |
a valid port number, such as 22, 80, and so on |
2 |
CIDR to test (a minimum of 1 is mandatory) |
CIDR syntax like 1.2.3.4/24 |
... |
other optional CIDRs |
CIDR syntax like 1.2.3.4/24 |
Example:
This rule prevents SSH access from not approved third-party networks such as 1.2.3.0/24', '5.5.6.7/32
.
|

Returns 'true' if the specified port can only be accessed by internal IP addresses
This method returns 'true' if one or some of the addresses in the provided CIDRs are allowed to connect.
Parameters:
Position |
Description |
Values |
---|---|---|
1 |
Port number (mandatory) |
Any valid port number, such as 22, 80 and more |
... |
Additional CIDR to mark as private (optional) |
CIDR syntax like 1.2.3.4/24 |
Example:
This rule prevents SSH access from public IP addresses.
|
Resource Functions
These functions return values for properties of assets. Especially, they can return secondary values for assets (for example, the value of a rule address for an SG assigned to an EC2 instance).

-
Returns the first instance of a resource, based on a field and value.
Parameters:
Position
Description
Value
1
resourceType
An asset property, for example, 'subnet', or 'vpc'
2
resourceFieldValue
The value of a resource property
3
resourceFieldName
The name of the resource property
Example:
Instance should have getResource('Subnet', subnet_name, 'name') with [cidr = '172.31.32.0/20']
-
Returns the first instance of a resource, given the type and an id.
This is almost the same as the instance above, only the field is assumed to be the ID of the specified asset type.
Parameters:
Position
Description
Value
1
resourceType
An asset property, for example, 'subnet', or 'vpc'
2
resourceId
The resource id to be returned, for example, subnet_id
Example:
Instance should have getResource('Subnet', subnet_id) with [cidr = '172.31.32.0/20']
SecurityGroup should have getResource('VPC', property_with_the_vpc_id) getValue(property_in_VPC_entity) = true -
For AWS KMS
AWS Key Management Service (AWS KMS) - A managed service that simplifies the creation and control of encryption keys that are used to encrypt data. entities only, returns the last instance that matches one of the resources below and an ID.
Parameters:
Position
Description
Value
1
resourceType
A constant value: KMS
2
KMSId
The resource id to be returned, whatever of these matches:
-
arn
-
id
-
aliases.arn
-
multiRegionConfiguration.primaryKey.arn
-
multiRegionConfiguration.replicaKeys.arn
Example:
SecretManager should have getResource('KMS', kmsKeyId) getValue('isCustomerManaged') = true
-

This function returns a list of instances of a resource, based on a field and a value. This is almost the same as getResource above but returns a list of all instances matching the field and value.
Parameters:
Position |
Description |
Value |
---|---|---|
1 |
resourceType |
An asset property, for example, 'subnet', or 'vpc' |
2 |
resourceFieldValue |
The value of a resource property (optional value) |
3 |
resourceFieldName |
The name of the resource property (optional value) |
Example:
|

Returns the value of an object, given its path.
Parameters:
Position |
Description |
Value |
---|---|---|
1 |
path |
The path to a resource, for example, 'vpc.cidr' |
Example:
|

Returns an array of values that matches the provided path parameter.
Parameters:
Position |
Description |
Value |
---|---|---|
1 |
path |
The path to a resource, for example, 'vpc.cidr' |
Example:
|

Supports AWS NACL, AWS Security Group, MS Azure Network Security Group, and GCP Security Group assets.
Verifies that a minimum of one port, which is part of the port list, also exists in the application configuration range.
Parameters:
Position |
Description |
Value |
---|---|---|
1 |
Port number or GenericList |
GenericList or any valid port number, such as 22, 80 etc... |
Examples:
|
|
Time Functions

Test if the date property in the UNIX time format is before, that is, smaller than the desired relative time.
Time is relative to real-time evaluation time rather than the date of rule authorship and can be defined with each of the supported time units.
Parameters:
Name |
Description |
Values |
---|---|---|
count |
The number of the units; negative numbers resolve into past dates |
Any positive or negative number such as -5, 10, ... |
unit |
The measurement unit |
A string - 'minutes', 'hours', 'days', 'months' |
Example:
This verifies that no instance was launched more than three months ago
|

Test if the date property in the UNIX time format is equal to or is greater than the desired relative time.
Time is relative to real-time / evaluation time rather than the date of writing the rule and can be defined with each of the supported time units.
|
Note - Unlike before(), this function also includes the desired time. |
Parameters:
Name |
Description |
Values |
---|---|---|
count |
The number of the units; negative numbers resolve into past dates |
Any positive or negative number such as -5,10, and so on |
unit |
The measurement unit |
A string - 'minutes', 'hours', 'days', 'months' |
Example:
Do an action for the instances that were launched in the last two weeks.
|
|
Best Practice - To use fixed (non-relative) time, you can use a standard numeric comparison with the UNIX date/time format. For example, to do something with all instances that were created before 1/1/2016 (which translates into the UNIX time 1451606400), use:
|

Returns the time difference between two dates, in time units of your selection (outputUnit).
Parameters:
Position |
Description |
Values |
---|---|---|
secondDate |
The other date to compare to |
date (string) |
outputUnit |
The desired time unit of the output |
'seconds', 'minutes', 'hours', 'days', 'months', 'years' (string) |
Date formats:
-
Unix time (time in seconds)
-
YYYY-MM-DDTHH:mm:ss.SSSZ
-
YYYY-MM-DDTHH:mm:ss.SSSSSSSZ
-
YYYY-MM-DDTHH:mm
-
YYYY-MM-DD
-
MM-DD-YYYY
-
MM/DD/YYYY HH:mm:ss
-
Month (as string) DD, YYYY HH:mm:ss
Tip:
To create a date in local time, include the time explicitly as in '2019-06-11T00:00'.
When you create a date without specifying the time, you get the date set in UTC.
Examples:
Check if the creation date (createDate) of a user (IamUser) is equal to or less than 90 days from the input date ('2022-01-17T11:09:00.000Z').
|
Check if the time difference between the time of creation (createdDateTime) of a user (User) and the input date is equal to 10 minutes.
|
Check if the updateDate of a RamUser is equal to or less than 20 days from the input date.
|