Mondoo 8.0 is out!
π₯³ Mondoo 8.0 is out! This release includes a whole new policy experience, new SaaS integrations, and much more!β
Get this release: Installation Docs | Package Downloads | Docker Container
We are excited to announce Mondoo v8, the new major release of cnspec, cnquery, and Mondoo Platform.
π NEW POLICY EXPERIENCEβ
This release significantly improves policies and query packs by simplifying their structure and adding major new features like properties, variants, and embedded queries. We continue to keep the Mondoo upgrade process incredibly simple, so you donβt have to worry about moving to v8.
Policies and query packsβ
Problem: Some of our old fields were confusing to use. For example: query
defined the MQL query inside of the query with metadata. (Why use it twice?) The scoring_queries
and data_queries
inside policies were unnecessarily convoluted. And what were specs
?
policies
- specs:
- scoring_queries:
sshd-01:
- data_queries:
sshd-02:
queries:
- uid: sshd-01:
query: sshd.config.params["StrictModes"] == "yes"
- uid: sshd-02:
query: sshd.config.params
Solution: We have overhauled a lot of commonly used terms in policies and query packs. Queries now contain an mql
field to store the MQL snippet. Policies are now built around groups
that can generate chapters and contain checks
(which are scored) and queries
(which are not scored). Additionally, we have removed all instances of key-value maps (see sshd-01:
above) and replaced them with named fields (see - uid: sshd-01
below).
policies:
- groups:
- checks:
- uid: sshd-01
- queries:
- uid: sshd-02
queries:
- uid: sshd-01
mql: sshd.config.params["StrictModes"] == "yes"
- uid: sshd-02
mql: sshd.config.params
Problem: The old YAML files we used in cnspec and cnquery required users to create references for queries and checks to use them. This forced people to write policies and separately reference all queries they wanted to use. See the example above.
Solution: We have introduced embedded queries. Itβs now much easier to write policies that stand on their own. You donβt have to explicitly reference queries and checks anymore. Instead, you can embed queries and checks directly into the policy that describes them.
policies:
- groups:
- checks: # embedded query vv
- uid: sshd-01
mql: sshd.config.params["StrictModes"] == "yes"
- queries:
- uid: sshd-02
mql: sshd.config.params
If you want to re-use queries, you can continue to use them globally as well, as seen above. If you prefer not to set a uid
for any of these embedded queries and checks, cnspec generates one for you: Just run cnspec bundle format FILENAME
. Stable UIDs (and, in turn, MRNs) are still important for anyone who uses your policy and defines overrides, exceptions, or processes policy results.
Problem: The ability to override queries and checks was very limiting. You could only affect a limited number of fields and had to understand how these were referenced. (We will skip the example to avoid even more confusion.)
Solution: Making changes to individual queries is now simple and intuitive. For example, here is a globally shared query that is modified in a policy:
policies:
- groups:
- checks:
# reference the shared query and change its title and impact
- uid: sshd-01
title: Make sure to enforce StrictMode
impact: 80
queries:
- uid: sshd-01
mql: sshd.config.params["StrictModes"] == "yes"
impact: 50
Problem: Policies containing a lot of queries flooded users with an unstructured list of all of their contents. However, most policy documents arenβt written this way. Instead, they contain chapters and sections that group together checks and controls.
Solution: Policy groups now have a type
to specify their function. For example, the most common type in a policy is a chapter
:
policies:
- uid: policy1
groups:
- type: chapter
title: Kernel checks
docs:
desc: |
Long description about what kernel checks do...
checks:
- uid: kernel-check-01
...
Other types include import
(for referencing imported policies) and override
(for making changes to any policies, queries, and checks).
Propertiesβ
Properties are a way to make adjustments to existing queries in pre-defined ways. For example, you can change the list of allowed TLS ciphers to include ciphers you need or you can change the location of files that are tested.
Properties existed before v8, but werenβt exposed to users. With this release we make properties configurable in the CLI, with configuration in the UI to follow in the coming weeks.
Configuration
Policy authors can add properties to their queries in YAML using props
:
- uid: home-info
mql: file(props.home) { * }
title: Gather info about the user's home
props:
- uid: home
mql: |
"/home"
The uid
is required. It provides the name for accessing properties in MQL. These follow standards for identifiers (such as no spaces or control characters allowed).
CLI usage
By default, the query uses the configured property. If you want to adjust it, such as for the above example, you can use the --props
CLI argument:
cnspec scan -f examples/example.mql.yaml --props "home='/home/zero'"
Note: This example overwrites a string property. Doing this properly requires escaping the CLI arguments so they retain the quotation (β
) characters in MQL. Properties can be any MQL snippet, but must adhere to the expected type. For example: You can't overwrite a string property into a number.
Deprecationsβ
All deprecations will be supported throughout the lifetime of Mondoo v8. We will remove them when we release Mondoo v9.
-
With the new policy format established in this release, we are deprecating the old policy format. If you only use existing policies created and maintained by Mondoo, you donβt need to take any action. We are serving both v7 and v8 clients and will keep things compatible.
-
If you have written your own policies, these will automatically work with v7 and v8 clients after you upload them to the Policy Hub. To take advantage of the many simplifications and features we have added, we encourage you to convert your policies to v8 with this simple command:
cnspec bundle format FILE
The formatter in cnspec always store files in the latest format.
-
All public policies in our community repo will remain in the v7 format for a little longer. This is to support users who are still using v7 and manually downloading policy files. We will transition these policies throughout the v8 lifespan to allow some new capabilities, like configurable properties, context, and variants.
π OTHER NEW FEATURESβ
Continuous scanning of Google Workspace and Oktaβ
You can now continuously scan your Google Workspace and Okta SaaS environments directly from the Mondoo Console. There's nothing to download or install in order to get started. Set up integrations with service accounts or tokens for these SaaS services, and they will securely scan every 8 hours.
Scan GCP orgs, projects, and foldersβ
No matter what you want to inspect in your GCP infrastructure, Mondoo has your back with new scanning support from your whole organizationβdown to a single folder:
cnquery scan gcp org 342423 # <-- scan GCP organization
cnquery scan gcp project mondoo-dev # <-- scan GCP project
cnquery scan gcp folder 3421423 # <-- scan GCP folder
Secure your GKE control planeβ
There's more to Cloud Kubernetes security than just the kubelet and cluster workloads, so we've added new data-gathering capabilities for the GKE control plan. Use this new data to take inventory of your GKE configuration or to write custom security policies for your organization.
- addonsConfig
- nodePools management
- Cluster networkConfig
- Cluster workloadIdentityConfig
- ipAllocationPolicy
- binaryAuthorization
- legacyAbac
- masterAuth
Cluster addonsConfigβ
cnquery> gcp.project.gke.clusters{ addonsConfig{*} }
gcp.project.gke.clusters: [
0: {
addonsConfig: {
horizontalPodAutoscaling: {
disabled: false
}
id: "gcp.project.gkeService.cluster/12345/addonsConfig"
gkeBackupAgentConfig: {}
gcePersistentDiskCsiDriverConfig: {
enabled: true
}
networkPolicyConfig: {
disabled: false
}
gcpFilestoreCsiDriverConfig: {
enabled: false
}
dnsCacheConfig: {
enabled: false
}
httpLoadBalancing: {
disabled: false
}
kubernetesDashboard: {
disabled: true
}
configConnectorConfig: {}
cloudRunConfig: {}
}
}
]
Cluster nodePools managementβ
cnquery> gcp.project.gke.clusters{ nodePools{ management } }
gcp.project.gke.clusters: [
0: {
nodePools: [
0: {
management: {
autoRepair: true
autoUpgrade: true
upgradeOptions: {}
}
}
1: {
management: {
autoRepair: true
autoUpgrade: true
upgradeOptions: {}
}
}
]
}
]
Cluster networkConfigβ
cnquery> gcp.project.gke.clusters{ networkConfig{*} }
gcp.project.gke.clusters: [
0: {
networkConfig: {
enableL4IlbSubsetting: false
id: "gcp.project.gkeService.cluster/12345/networkConfig"
dnsConfig: {}
serviceExternalIpsConfig: {
enabled: false
}
subnetworkPath: "projects/project-1/regions/us-central1/subnetworks/mondoo-gke-cluster-2-subnet"
privateIpv6GoogleAccess: "PRIVATE_IPV6_GOOGLE_ACCESS_UNSPECIFIED"
datapathProvider: "DATAPATH_PROVIDER_UNSPECIFIED"
networkPath: "projects/project-1/global/networks/mondoo-gke-cluster-2"
subnetwork: gcp.project.computeService.subnetwork name="mondoo-gke-cluster-2-subnet"
enableIntraNodeVisibility: false
defaultSnatStatus: {
disabled: false
}
network: gcp.project.computeService.network name="mondoo-gke-cluster-2"
}
}
]
Cluster workloadIdentityConfigβ
cnquery> gcp.project.gke.clusters{ workloadIdentityConfig }
gcp.project.gke.clusters: [
0: {
workloadIdentityConfig: {
workloadPool: "mondoo-edge.svc.id.goog"
}
}
]
Cluster ipAllocationPolicyβ
cnquery> gcp.project.gke.clusters{ ipAllocationPolicy{*} }
gcp.project.gke.clusters: [
0: {
ipAllocationPolicy: {
id: "gcp.project.gkeService.cluster/12345/ipAllocationPolicy"
stackType: "IPV4"
tpuIpv4CidrBlock: ""
useRoutes: false
createSubnetwork: false
nodeIpv4CidrBlock: ""
subnetworkName: ""
servicesSecondaryRangeName: "cluster-2-ip-range-svc"
useIpAliases: true
clusterSecondaryRangeName: "cluster-ip-range-pods"
clusterIpv4CidrBlock: "10.20.0.0/16"
ipv6AccessType: "IPV6_ACCESS_TYPE_UNSPECIFIED"
servicesIpv4CidrBlock: "10.30.0.0/16"
}
}
]
Cluster binaryAuthorizationβ
cnquery> gcp.project.gke.clusters{ binaryAuthorization }
gcp.project.gke.clusters: [
0: {
binaryAuthorization: {
enabled: false
evaluationMode: "EVALUATION_MODE_UNSPECIFIED"
}
}
]
Cluster legacyAbacβ
cnquery> gcp.project.gke.clusters{ legacyAbac }
gcp.project.gke.clusters: [
0: {
legacyAbac: {
enabled: false
}
}
]
Cluster masterAuthβ
cnquery> gcp.project.gke.clusters{ masterAuth }
gcp.project.gke.clusters: [
0: {
masterAuth: {
clientCertificate: ""
clientCertificateConfig: {}
clientKey: ""
clusterCaCertificate: "***"
password: ""
username: ""
}
}
]
Identify public IPs in Azureβ
Identifying publicly exposed assets is critical to securing your cloud infrastructure. Use the new publicIpAddresses
data available in the azure.subscription.computeservice.vm
and azure.subscription.networkservice
to quickly identify assets that may be incorrectly publicly exposed.
Identify all public IP addresses in a subscription:
cnquery> azure.subscription.network.publicIpAddresses{*}
azure.subscription.network.publicIpAddresses: [
0: {
name: "super-cool-public-ip"
id: "/subscriptions/<redacted>/resourceGroups/<redacted>/providers/Microsoft.Network/publicIPAddresses/<redacted>"
location: "uksouth"
tags: {}
ipAddress: "255.255.255.255"
}
]
Identify public IP addresses on specific VMs:
cnquery> azure.subscription.compute.vms{publicIpAddresses{*}}
azure.subscription.compute.vms: [
0: {
publicIpAddresses: [
0: {
name: "super-cool-public-ip"
id: "/subscriptions/<redacted>/resourceGroups/<redacted>/providers/Microsoft.Network/publicIPAddresses/<redacted>"
location: "uksouth"
tags: {}
ipAddress: "255.255.255.255"
}
]
name: "vm-name"
}
]
Query Google Workspace connected appsβ
You can now fetch Google Workspace connected apps with a new googleworkspace.connectedApps
MQL resource:
googleworkspace.connectedApps { name clientid }
googleworkspace.connectedApps: [
0: {
clientId: "11234434534-abcdefg.apps.googleusercontent.com"
name: "Slack"
}
...
]
You can also filter this data to return specific connected apps:
googleworkspace.connectedApps.where( name == /Slack/) { * }
googleworkspace.connectedApps.where: [
0: {
users: [
0: googleworkspace.user primaryEmail="user1@example.com"
]
tokens: [
0: googleworkspace.token displayText="Slack"
]
scopes: [
0: "https://www.googleapis.com/auth/activity"
1: "https://www.googleapis.com/auth/drive.activity"
2: "https://www.googleapis.com/auth/userinfo.profile"
3: "https://www.googleapis.com/auth/userinfo.email"
4: "openid"
5: "https://www.googleapis.com/auth/calendar.readonly"
6: "https://www.googleapis.com/auth/drive"
7: "https://www.googleapis.com/auth/calendar.events"
]
name: "Slack"
clientId: "11234434534-abcdefg.apps.googleusercontent.com"
}
1: {
users: [
0: googleworkspace.user primaryEmail="user1@example.com"
1: googleworkspace.user primaryEmail="user2@example.com"
2: googleworkspace.user primaryEmail="user3@example.com"
3: googleworkspace.user primaryEmail="user4@example.com"
]
tokens: [
0: googleworkspace.token displayText="Slack"
1: googleworkspace.token displayText="Slack"
2: googleworkspace.token displayText="Slack"
3: googleworkspace.token displayText="Slack"
]
scopes: [
0: "https://www.googleapis.com/auth/userinfo.profile"
1: "https://www.googleapis.com/auth/userinfo.email"
2: "openid"
]
name: "Slack"
clientId: "3321342421-abcdefg.apps.googleusercontent.com"
}
2: {
users: [
0: googleworkspace.user primaryEmail="user1@example.com"
1: googleworkspace.user primaryEmail="user2@example.com"
2: googleworkspace.user primaryEmail="user3@example.com"
3: googleworkspace.user primaryEmail="user4@example.com"
]
tokens: [
0: googleworkspace.token displayText="Slack"
1: googleworkspace.token displayText="Slack"
2: googleworkspace.token displayText="Slack"
3: googleworkspace.token displayText="Slack"
]
scopes: [
0: "https://www.googleapis.com/auth/userinfo.profile"
1: "https://www.googleapis.com/auth/userinfo.email"
2: "openid"
]
name: "Slack"
clientId: "6060606090-abcdefg.apps.googleusercontent.com"
}
]
Python packages inspectionβ
Outdated packages don't end at the operating system, so we've introduced our first application package resource with the python.packages
MQL resource. This new resource discovers packages automatically on macOS, Windows, and Linux in the following locations:
- /usr/local/lib/python/*
- /usr/local/lib64/python/*
- /usr/lib/python/*
- /usr/lib64/python/*
- /opt/homebrew/lib/python/*
- C:/Python/*
- /System/Library/Frameworks/Python.framework/Versions
- /Library/Developer/CommandLineTools/Library/Frameworks/Python3.framework/Versions
Each package returns data similar to this pytz
package:
cnquery> python.packages[0]{ * }
python.packages[0]: {
author: "Armin Ronacher"
name: "Babel"
dependencies: [
0: python.package name="pytz" version="2022.7.1"
]
summary: "Internationalization utilities"
id: "/usr/lib/python3.11/site-packages/Babel-2.10.3-py3.11.egg-info/PKG-INFO"
file: file path="/usr/lib/python3.11/site-packages/Babel-2.10.3-py3.11.egg-info/PKG-INFO" size=1283 permissions.string="-rw-r--r--"
license: "BSD"
version: "2.10.3"
}
To query a specific package on disk you can provide the path to the METADATA file:
cnquery> python.package("/home/jdiaz/.local/lib/python3.11/site-packages/python_ftp_server-1.3.17.dist-info/METADATA"){ * }
python.package: {
version: "1.3.17"
summary: "Command line FTP server tool designed for performance and ease of use."
file: file path="/home/jdiaz/.local/lib/python3.11/site-packages/python_ftp_server-1.3.17.dist-info/METADATA" size=1186 permissions.string="-rw-r--r--"
author: "Vadym Stupakov"
dependencies: data is not a map to auto-expand
id: "/home/jdiaz/.local/lib/python3.11/site-packages/python_ftp_server-1.3.17.dist-info/METADATA"
license: "MIT"
name: "python-ftp-server"
}
This is the first of many new application package resources we plan to introduce, allowing you to audit and secure your application dependencies. If you have particular application packaging systems you want to see in cnquery and cnspec, be sure to let us know on our GitHub Discussions page.
π§Ή IMPROVEMENTSβ
Support for connecting to IPv6 hostsβ
Some day we'll all take the leap and migrate to IPv6. When you do, Mondoo will be there for you. We've updated both cnquery and cnspec to connect to IPv6 hosts directly over SSH or using Ansible inventory files.
cnquery shell ssh chris@fd00::20c:30ff:fe8a:9da0 --ask-pass
Enter password:
β discover related assets for 1 asset(s)
β resolved assets resolved-assets=1
___ _ __ __ _ _ _ ___ _ __ _ _
/ __| '_ \ / _` | | | |/ _ \ '__| | | |
| (__| | | | (_| | |_| | __/ | | |_| |
\___|_| |_|\__, |\__,_|\___|_| \__, |
mondooβ’ |_| |___/ interactive shell
cnquery>
Expanded support for AWS ECS in MQLβ
In this release we've greatly expanded MQL's AWS ECS support with new data and resources:
aws.ecs.task
now includesplatformVersion
data.aws.ecs.container
now includesplatformVersion
,runtimeId
, andcontainerName
data.aws.ecs.cluster
now includescontainerInstances
data.aws.ecs.image
now includesuri
data exposing the URI of the image repository.- New
aws.ecs.instance
resource.
New and improved policiesβ
-
New Microsoft 365 Security by Mondoo
This all-new policy by Mondoo helps you to secure your Microsoft 365 configuration.
-
New Microsoft Vulnerability Policy by Mondoo
This all-new policy helps you find critical vulnerabilities in Microsoft Office and SharePoint.
-
New VMware vCenter Incident Response Pack
Gather critical information on your vSphere and ESXi systems in the event of a security incident with this new incident response pack.
-
Updated CIS Microsoft 365 Foundations Benchmark from 1.2 to 1.5
This updated policy is nearly entirely rewritten with dozens of new controls, more reliable queries, and updated remediation steps.
-
Updated CIS Google Kubernetes Engine (GKE) Benchmark to 1.3.0
This updated policy includes new policies for securing not just the Kubelets, but now also the Kubernetes control plane.
-
Updated CIS Google Cloud Platform Foundation Benchmark policy
Ten updated controls in the CIS Google Cloud Platform Foundation Benchmark policy improve the reliability of results.
-
Updated Microsoft Azure Security
We added nine new queries to the Microsoft Azure Security to help you better secure the base directory configuration.
-
Updated Linux Workstation Security
We expanded boot loader security to include permissions on
/boot/loader/loader.conf
so you can rest assured your boot sequence hasn't been tampered with. -
Updated Linux Security Policy
We improved the reliability of auditd package checks on some SUSE releases.
Specify GCP and Google Workspace credential pathβ
You can now specify the path to your GCP or Google Workspace credentials using a new --credentials-path
flag. Shell environmental variables will continue to take precedence when defining the path, but this is a great method of setting the path if you don't have shell ENV vars set.
With env var:
GOOGLE_APPLICATION_CREDENTIALS=~/mondoo-dev-1111111.json cnquery shell gcp
With --credentials-path:
cnquery shell gcp --credentials-path ~/mondoo-dev-1111111.json
Find spaces more easily in large organizationsβ
It was hard to find a particular asset when you had a large number of organizations or spaces. We've made things easier to track down with new links to open individual organizations and alphabetical sorting of all spaces.
Login with a splashβ
Our old login page didn't feel fancy enough, so we redesigned it with splashes of Mondoo purple and orange to spruce up your login experience.
Red Hat Universal Base Image cnspec containers on Docker Hubβ
We are now publishing Red Hat Universal Base Image-based cnspec and cnquery containers to Docker Hub. These containers are perfect for running cnspec and cnquery in OpenShift clusters. You can find these images along with our standard Alpine-based images in our cnspec and cnquery repositories.
Improved scan error outputβ
Gone are cryptic asset connection error messages when scanning multiple assets! In their place you now see better formatted and parsed error messages that make it easier to track down exactly why assets can't be scanned.
π BUG FIXES AND UPDATESβ
- We now correctly detect services on Kali Linux.
- Mondoo EOL policy now executes on FreeBSD hosts.
cnquery run
andcnspec run
now properly load Mondoo Platform config to support EOL and package vulnerability queries.- Fix parsing of timestamps in Google Workspace.
- Fix setup instructions for Windows on the Integrations page to copy/paste correctly.
- Add missing breadcrumbs to the Vulnerabilities page.
- Add form validation to the GCP and Okta Integration setup pages.
- Don't report successful vulnerability scanning on an asset when zero packages were discovered.
- Fix incorrect quoting in the GitLab Docker scanning example
- Don't show the hour when reporting an EOL date for an asset.
- Fix incorrect GCP project ID validation in the GCP integration setup page.
- If an integration has never scanned, then display
Never
instead ofJan 01, 0001
. - Update links on integration pages to go to specific documentation.
- Use the latest Microsoft 365 logo on the integrations page.
- Improve performance of container image scanning in the Mondoo Kubernetes Operator.
- Update tabs on asset pages to match the new navigation UX.
- Add the missing Okta token field to the Okta integration setup page.
- Link to new CloudShell documentation in the AWS integration setup wizard.
- Fix GCP console links in the GCP integration setup page to load properly when logged out of GCP.
- Specify UDP or TCP in the
ports.listening
resource so specific protocols can be queried instead of justipv4
/ipv6
. - Resolve failures scanning container registries.
- Label container image assets with all discovered tags when scanning container registries.