Custom Rules Using Netskope Governance Language
In Next Generation SaaS Security Posture Management, Netskope Governance Language (NGL) replaces the existing Domain Specific Language. Create custom rules under Policies > Security Posture > Next Gen > Rules > New Rule using NGL for the security posture of SaaS app resources.
The following syntax diagram represents the general rule to write a NGL statement. An NGL rule will have the following format:
For example,
microsoft365 remotedomain should-have autoforwardenabled = false
Salesforce ConnectedApp should-not-have oauthConfig with-attribute { scopes with-any-element [ scope = "Full" ] }
Grammar
An example of a security rule description in plain English is as follows:
Microsoft 365 should have a remote domain resource-type with attribute auto-forward enabled as false.
As you see, a security rule typically has a set of attributes (Microsoft 365
, remote domain
, auto-forward
), a set of operators (should have
, with attribute
) and a value (false
). As is clear from that breakdown of the rule description, the attributes are specific to the SaaS app under consideration (Microsoft 365 remote domain in the above example). However, the operators are generic and can be applied to any attributes belonging to any SaaS app. Values can either be the same or different between different SaaS applications, or even between different instances of the same SaaS application.
The following table provides examples of using a condition. The formats in this table are applicable to all attributes.
NGL | Description |
---|---|
| Microsoft 365 should have adminauditlogconfig resource-type with id. |
| Microsoft 365 should have a remote domain resource-type with attribute auto-forward enabled as false. |
| Microsoft 365 should not have a transport rule resource-type with attribute set SCL value as -1 and the length of the list attribute sender domain is > 0. |
| Passwords are not set to expire. |
| Enable click-jack protection for setup pages. |
| Multi-factor authentication (MFA) should be enabled for all organizations in GitHub. |
App-Suite
An app-suite refers to the application suite on which you write the rule. It can be a SaaS app. For example,
salesforce sessionsettings should-have enablelightninglogin = true
In the above example, salesforce is the app-suite.
microsoft365 sharepointtenant should-have isunmanagedsyncclientfortenantrestricted = true
In the above example, microsoft365 is the app-suite.
Resource-Type
A resource-type is the type of configuration or resource in the SaaS app. These represent the objects returned by the API and their corresponding schemas. For example,
salesforce sessionsettings should-have enablelightninglogin = true
In the above example, sessionsettings is the resource-type.
microsoft365 sharepointtenant should-have isunmanagedsyncclientfortenantrestricted = true
In the above example, sharepointtenant is the resource-type.
There can be one or more resources of a given resource-type. In an NGL rule, resource-type specifies the type of resources against which the rule should be evaluated. An NGL rule must have a resource-type specified after the app-suite. If required, an NGL rule can refer to more resource-types subsequently be part of the condition section of the rule.
There are few resource- types in certain app-suites, which do not have any metadata on it. For example, DefenderForOffice365
, Users
, or Groups
in Microsoft Azure AD. These are place-holder resource-types, as present in the app-suite under consideration. Such place-holder resources help prevent namespace conflicts as multiple services tend to use similar names for their resources in different ways. When used, this makes NGL explicit and clear on its purpose. For example, in this NGL which makes sure that there is at least one anti-phishing policy configured in Microsoft 365, microsoft365 defenderforoffice365 should-have antiphishpolicy exists
. In graphical representation, defenderforoffice365
resource-type is a namespace node which is linked to antiphishpolicy
resource-type node with properties. The rule evaluates to true only when there is at least a node for antiphishpolicy
linked to the (namespace node) defenderforoffice365
. The graphical relationship is as follows:
List of DOMs
A user can make use of the resource-type hierarchy information to aid in rule-writing. Detailed information on the hierarchy of the resource-types and how they are linked can be found at:
Expression
An expression refers to whether the condition should be matched or not against the resource types used in the rule. Keywords for this are should-have
and should-not-have
. For example,
salesforce sessionsettingssessionsettings should-have enablelightninglogin = true
In the above example, should-have is the expression.
microsoft365 sharepointtenant should-not-have isunmanagedsyncclientfortenantrestricted = false
In the above example, should-not-have is the expression.
Condition
A condition is a standard that the rule uses to check against a resource type in an app suite to narrow down the result. It uses a set of operators to achieve it. For example,
salesforce sessionsettings should-have enablelightninglogin = true
In the above example, = is the condition/operator.
microsoft365 sharepointtenant should-have isunmanagedsyncclientfortenantrestricted = true
In the above example, = is the condition/operator.
List of Operators
A list of operators are as follows:
Operator | Type | Description | Example |
---|---|---|---|
| Logical |
|
|
| Logical |
|
|
| Logical |
|
|
| Arithmetic |
|
|
| Arithmetic |
|
|
| Arithmetic |
|
|
| Arithmetic |
|
|
| Arithmetic |
|
|
| Relational |
|
|
| Relational |
|
|
| Relational |
|
|
| Relational |
|
|
| Relational |
|
|
| Relational |
|
|
| Functional |
|
|
| Functional |
|
|
| Functional |
|
|
| Hierarchical |
|
|
| Hierarchical |
|
|
| Hierarchical |
|
|
| Hierarchical |
|
|
| Hierarchical |
|
|
| Hierarchical |
|
|
| Utility |
|
Note The letter |
| Utility |
|
|
| Utility |
|
|
| Utility |
|
|
| Utility |
|
|
Operators supported in NGL follow the precedence order below:
Category | Operator | Associativity |
---|---|---|
Postfix |
| Left to right |
Unary |
| Not applicable |
Multiplicative |
| Left to right |
Additive |
| Left to right |
Relational |
| Not applicable |
Equality |
| Not applicable |
Logical AND |
| Left to right |
Logical OR |
| Left to right |
Function
Use functions in rules to identify specific information about resource types. Functions use the following syntax:
<function>(<argument>)
For example:
microsoft365 transportrule should-not-have len(senderdomainis) > 0
github repository should-have age(created_at , "days") > 1
azuread oauth2permissiongrant should-not-have textmatch(scope, "AppRoleAssignment.ReadWrite.All") = true
NGL with Multiple Resource Types
Resource types which are linked to each other can be used in NGL to validate a configuration. This helps to assess how secure are the multiple resource types working in unison. Additional information to the resources can be found here: List of DOMs. There are two variations of such NGLs with multiple resource types:
Type 1
When all the linked resources should match a condition. For example, NGL to match all conditionalaccesspolicy
linked to conditionalaccess
resource with state = "enabled" is written as:
azuread conditionalaccess should-have conditionalaccesspolicy with-attribute { state = "enabled" }
.
This NGL will evaluate to true for the ConditionalAccess
resource as all the linked ConditionalAccessPolicy
are having an attribute state =”enabled”.
Note
To view the ConditionalAccess
resource, access the Microsoft Azure AD DOM, then expand IdentityAndSignIn > ConditionalAccess. To view the ConditionalAccessPolicy
resource, access the same Microsoft Azure AD DOM, then expand IdentityAndSignIn > ConditionalAccess > ConditionalAccessPolicy
The truth table for the evaluations results of the rule will be as follows:
cp2 - state = enabled | cp2 -state = disabled | |
---|---|---|
cp1 - state = enabled | Success | Fail |
cp1 - state = disabled | Fail | Fail |
Type 2a
When any of the linked resources should match a condition. The links exist due to a hierarchical relationship between the resource types. For example, NGL to match any one conditionalaccesspolicy
linked to conditionalaccess
resource with state = "enabled" is written as:
azuread conditionalaccess should-have any conditionalaccesspolicy as c with-attribute { c.state = "enabled" }
This NGL will evaluate to true for the ConditionalAccess
resource as one of the linked ConditionalAccessPolicy
satisfies the condition.
Note
To view the ConditionalAccess
resource, access the Microsoft Azure AD DOM, then expand IdentityAndSignIn > ConditionalAccess. To view the ConditionalAccessPolicy
resource, access the same Microsoft Azure AD DOM, then expand IdentityAndSignIn > ConditionalAccess > ConditionalAccessPolicy
The truth table for the evaluations results of the rule will be as follows:
cp2 - state = enabled | cp2 - state = disabled | |
---|---|---|
cp1 - state = enabled | Success | Success |
cp1 - state = disabled | Success | Failed |
Type 2b
The resources can also be linked using the refers-to relationship. An example from the Salesforce app suite is to get DelegateGroup
(access the Salesforce DOM, then expand Metadata > DelegateGroups > DelegateGroup) which is linked to DelegateGroupMember
(access the Salesforce DOM, then expand Tooling > DelegateGroupMembers > DelegateGroupMember) which is also linked to User
(access the Salesforce DOM, then expand SObjects > Users > User)
The link between DelegateGroup
and DelegateGroupMember
exists through the DelegateGroupId
attribute in DelegateGroupMembe
r which refers toDelegateGroup
. The link between DelegateGroupMember
and User
exists through the UserOrGroupId
attribute in the DelegateGroupMember
resource type which refers toUser
.
With these three resource types in action, NGL to find DelegateGroup
if any one of the linked User
has a name “demo user1” is written as:
salesforce DelegateGroup should-have DelegateGroupMember with-attribute {any user as u with-attribute { u.Name = "demo user1" }}
The truth table for the evaluations results of the rule will be as follows:
user - name = demo user1 | user - name = demo user2 | |
---|---|---|
user - name = demo user1 | Success | Success |
user - name = demo user2 | Success | Fail |
Predefined Categories
Netskope provides a list of predefined rules bundled together in a category to check your SaaS environments' security posture compliance. For a complete list of predefined rules, log in to your Netskope tenant and navigate to Policies > Security Posture, then click the Next Gen tab followed by Rules. The Rules table lists the various categories like compliance standard, domain, MITRE ATT&CK, Netskope Best Practices and corresponding predefined rules. You can filter the result based on a specific category.
NGL Best Practices
Though NGL is not case-sensitive, lower case is preferred.
It is recommended to clone a predefined rule and create a new custom rule along the similar lines.