Customize Policies with Overlays
Import an existing cnspec policy and override selected checks or policy settings without copying the base policy
A policy overlay lets you adapt an existing policy without copying and maintaining the entire policy. The overlay is a small policy that:
- Imports a base policy.
- Overrides only the checks or policy settings that your organization needs to change.
All other content continues to come from the base policy. When the base policy gains new checks or documentation, the overlay inherits those updates.
Use an overlay when you need to enforce a stricter check, put a base check into preview, deactivate a check that does not apply to your environment, or use a different scoring system.
How an overlay works
An overlay uses two types of policy groups:
- An
importgroup adds the base policy to the overlay. - An
overridegroup references checks from the imported policy and supplies the values that should change.
cnspec resolves the import and overrides into one effective policy at scan time. It does not change the base policy itself.
Create an overlay
The following self-contained bundle defines a base SSH policy and an overlay for a more restrictive production environment:
policies:
# The policy that provides the original checks.
- uid: example-linux-baseline
name: Example Linux baseline
version: 1.0.0
scoring_system: highest impact
tags:
mondoo.com/category: security
mondoo.com/platform: linux
require:
- provider: os
groups:
- title: SSH configuration
filters:
- mql: asset.family.contains("unix")
checks:
- uid: sshd-max-auth-tries
- uid: sshd-use-pam
- uid: sshd-port
# The policy to assign for the production environment.
- uid: production-linux-baseline
name: Production Linux baseline
version: 1.0.0
scoring_system: highest impact
tags:
mondoo.com/category: security
mondoo.com/platform: linux
require:
- provider: os
groups:
# Import every check from the base policy.
- type: import
policies:
- uid: example-linux-baseline
# Change only the checks that differ in production.
- type: override
title: Production requirements
filters:
- mql: asset.family.contains("unix")
checks:
- uid: sshd-max-auth-tries
title: Limit unsuccessful SSH authentication attempts
action: modify
mql: sshd.config.params["MaxAuthTries"] <= 3
impact: 90
- uid: sshd-use-pam
action: preview
- uid: sshd-port
action: deactivate
queries:
- uid: sshd-max-auth-tries
title: Limit unsuccessful SSH authentication attempts
mql: sshd.config.params["MaxAuthTries"] <= 4
impact: 70
- uid: sshd-use-pam
title: Enable PAM for SSH
mql: sshd.config.params["UsePAM"] == "yes"
impact: 60
- uid: sshd-port
title: Use the default SSH port
mql: sshd.config.params["Port"] == 22
impact: 30The effective production-linux-baseline policy:
- Requires no more than three authentication attempts instead of four and raises the check's impact to 90.
- Runs and reports the PAM check without including it in the score.
- Does not run the SSH port check.
- Inherits every other field and any future checks from
example-linux-baseline.
Assign the overlay policy instead of separately maintaining a production copy of the base policy.
Choose an override action
Each overridden check or data query references the original item by uid or mrn and uses an action to describe the change. Put scored checks under checks and data queries under queries in the override group.
| Action | Behavior |
|---|---|
modify | Replaces the fields supplied in the override and inherits fields that are omitted. Use it to change MQL or impact. |
preview | Runs and reports the check but excludes its result from scoring. |
deactivate | Prevents the check from running. |
activate | Explicitly activates the check. |
To learn about preview behavior and remediation deadlines, read Preview Checks.
You can override check fields such as mql, impact, title, documentation, filters, properties, and variants. On a policy reference in an import group, you can override action, impact, or scoring_system:
- type: import
policies:
- uid: example-linux-baseline
scoring_system: bandedWhen an override supplies a collection such as filters, props, tags, or variants, that
collection replaces the inherited value; cnspec does not append the new entries. Include every
entry that the effective check still needs.
Reference policy content outside the bundle
The first example uses UIDs because the base policy, overlay, and checks are in the same bundle. When the base policy and checks already exist outside the overlay bundle, reference their full MRNs instead. Published Mondoo policies and checks use MRNs in this form:
groups:
- type: import
policies:
- mrn: //policy.api.mondoo.app/policies/POLICY_UID
- type: override
checks:
- mrn: //policy.api.mondoo.app/queries/CHECK_UID
action: modify
impact: 90Replace POLICY_UID and CHECK_UID with the identifiers from the base policy. Content owned by your space uses the MRNs that Mondoo Platform provides for that content. You can download the policy to inspect its policy and check MRNs.
cnspec must be able to resolve every imported policy and overridden check. For local or offline linting, keep the base content and overlay in the same bundle file. For content that is already stored in Mondoo Platform, use its full MRNs.
Limit where or how long an override applies
Add asset filters to an override group to apply it only to matching assets. Add valid.until to stop applying the override after a date:
- type: override
title: Ubuntu exception through October 2026
filters:
- mql: asset.platform == "ubuntu"
valid:
until: 2026-10-01
checks:
- uid: sshd-use-pam
action: previewUntil October 1, 2026, the PAM check is in preview for Ubuntu assets. After that date, the override no longer applies and the imported check returns to its base behavior.
Validate and scan an overlay
If the base policy and overlay are in one file, lint and scan that bundle:
cnspec policy lint production-overlay.mql.yaml
cnspec scan local --policy-bundle production-overlay.mql.yamlYou can scan a directory when a bundle is split across files:
cnspec scan local --policy-bundle ./policiescnspec policy lint validates each file independently. To lint cross-file references locally, first combine the base content and overlay into one self-contained bundle file.
Linting reports an error if an imported policy is missing or a modify action targets a check that cnspec cannot resolve.
Keep overlays maintainable
- Keep the overlay small. Override only fields that intentionally differ from the base policy.
- Use stable UIDs or MRNs. If an identifier changes in the base policy, update the overlay reference.
- Avoid multiple matching overrides for the same field. Prefer one authoritative override so the effective behavior remains clear.
- Lint and test the overlay after updating the base policy.
Next steps
- To run checks without affecting scores, read Preview Checks.
- To make thresholds configurable instead of replacing MQL, read Define Properties.
- To validate, upload, and assign an overlay policy, read Manage Policies.