Write Custom Policies
Policies are the specifications that cnspec uses when it scans an asset. cnspec compares your asset's configuration against the standards set in policies, and calculates a score based on the comparison. Scores tell you how secure your different assets are.
Mondoo provides dozens of free policy bundles (collections of policies) with cnspec that cover the most common types of assets—and Mondoo Platform has even more. If your organization has unique needs that these policy bundles don't meet, you can create custom policy bundles.
A very simple policy bundle
All cnspec policies are stored in YAML files. These files are called bundles because they bundle policies together. Their filename ends in .mql.yaml
. To learn more about policies and policy bundles, read About Policies.
Here's a very simple example of a policy bundle. It contains only one policy, Simple example policy 1
:
policies:
- uid: simple-example1
name: Simple example policy 1
version: "1.0.0"
scoring_system: highest impact
authors:
- name: Lunalectric
email: security@lunalectric.com
groups:
- checks:
- uid: sshd-01
title: Ensure the port is set to 22
mql: sshd.config.params["Port"] == 22
impact: 30
- uid: sshd-02
title: Prevent weaker CBC ciphers from being used
mql: sshd.config.ciphers.none( /cbc/ )
impact: 60
queries:
- uid: sshd-d-1
title: Gather SSH config params
mql: sshd.config.params
We'll use this simple policy bundle example to explore how to write a policy.
Basic policy attributes
The attribute... | On line... | Defines... |
---|---|---|
uid | 2 | A unique identifier for the policy |
name | 3 | A descriptive name for the policy |
version | 4 | The current version of the policy. We recommend using semantic versioning to keep track of major and minor policy changes. |
scoring_system | 5 | How Mondoo calculates the score for an asset. To learn more, read Scoring. |
authors | 6-7 | The person or entity to credit for writing the policy, and email where they can be reached |
The groups
section of the policy defines the checks and queries that define how to assess and report on asset security.
Queries
A query is an MQL inquiry that requests information about an asset. For example, a query can ask what version of an OS is running on a container or request the UIDs, names, and statuses are of all users in an application.
Queries in a policy add helpful insights to scan report output. (They're also the bases for checks, which are described below.)
The simple example policy bundle above contains one query (on lines 11-13). It requests the configuration values of the SSH server scanned. This information is included in the scan report output.
The attribute... | On line... | Defines... |
---|---|---|
uid | 20 | A unique identifier for the query |
title | 21 | A descriptive name for the query |
mql | 22 | The MQL query that requests information, such as the number of root accounts or the state of a port |
To learn how to create MQL queries, read Write Effective MQL.
Checks
An MQL query that also makes an assertion and produces a score is called a check. Checks retrieve a value just like any query. For example, a check can ask What OS version is running? How they differ from other queries is that they compare the retrieved value to a desired value and create a score based on that comparison. For example, a check can assert that the value should be 8.3.1 or higher. All checks return a Boolean true
or false
. In our example, if the current OS version on the scanned asset is 8.2, the check returns false
. If the current OS version is 8.3.1 or 8.3.5, the check returns true
.
Checks are the building blocks of policies. A typical policy identifies a number of desired configurations (such as MFA is enabled and no ports are publicly accessible) and instructs Mondoo to compare that to the actual configuration on the scan target. This is a collection of checks.
The simple example policy bundle above contains two checks:
The check defined in lines 11-14 ensures the SSH port is set to 22.
The check defined in lines 15-18 ensures that SSH uses a strong cipher.
Each check has its own attributes:
The attribute... | On line... | Defines... |
---|---|---|
uid | 11 | A unique identifier for the check |
title | 12 | A descriptive name for the check that's useful in report output |
mql | 13 | The MQL assertion that identifies the desired condition or configuration, such as logging is enabled or encryption is required |
impact | 14 | How important (on a scale from 0 to 100) the check is in the scope of the entire policy. The impact and result of each check determine the asset's score on the policy. To learn more, read Scoring. |
To learn how to create MQL queries and checks, read Write Effective MQL.
Scoring
Each target scanned receives a graded score that summarizes its overall success:
80 .. 100 A (100 A+ 95 A 85 A- 80)
60 .. 79 B ( 79 B+ 75 B 65 B- 60)
30 .. 59 C ( 59 C+ 50 C 40 C- 30)
10 .. 29 D ( 29 D+ 25 D 15 D- 10)
0 .. 9 F
The score is based on the number of checks that return a true
value (pass) compared to how many return a false
value (fail).
When assessing the overall security of an asset, some checks may be more important than others. For example, suppose a strong cipher is more important to your organization than SSH using port 22. You can use the impact
attribute to give more importance to one check and less importance to another check. Our simple example query does just that: It gives the Ensure the port is set to 22
check an impact of 30
(on line 14) and the Prevent weaker CBC ciphers from being used
check an impact of 60
(on line 18).
How Mondoo uses these values to calculate an asset's score depends on the scoring_system
setting (on line 5). You can choose from these possible scoring systems:
Average scoring system
The average
scoring system considers impact before averaging check scores. Failed checks with higher impact lower an overall score more than checks with lower impact. This is how the average
scoring system calculates the overall score:
If a check passes (returns
true
), the asset receives a 100 for that check.If a check fails (returns
false
), the asset receives (100-impact) for that check. For example, if an asset fails a check with an impact of 10, it receives a 90 for that check.
Here are possible results of our simple example query, which has a port check and a cipher check:
Port (impact 30) | Cipher (impact 60) | Overall score |
---|---|---|
Pass (100) | Pass (100) | (100 + 100) / 2 = 100 or A+ |
Pass (100) | Fail (100 - 60 = 40) | (100 + 40) / 2 = 70 or B |
Fail (100 - 30 = 70) | Pass (100) | (100 + 70) / 2 = 85 or A |
Fail (100 - 30 = 70) | Fail (100 - 60 = 40) | (70 + 40) / 2 = 55 or C |
Highest (failed) impact scoring system
The highest impact
scoring system only considers the highest impact check in the policy. It relies on the same method of subtraction as the average
scoring system: It subtracts the impact
value from 100 if a check fails. However, unlike the average
scoring system, it doesn't average all the check scores to calculate the overall score. Instead, it just takes the score of the highest-impact failed check and makes that the overall score.
Here are possible results of our simple example query, which has a port check and a cipher check:
Port (impact 30) | Cipher (impact 60) | Overall score |
---|---|---|
True (100) | True (100) | 100 or A+ |
True (100) | False (100 - 60 = 40) | 40 or C |
False (100 - 30 = 70) | True (100) | 70 or B |
False (100 - 30 = 70) | False (100 - 60 = 40) | 40 or C |
Next steps
To learn how to write more powerful policies, read Reuse Queries and Checks.
If you're ready to create your own policy: To learn how to set up, validate, and store policy bundles, read Manage Policies.