Skip to main content

Mondoo 8.0 is out!

Β· 15 min read
Tim Smith
Tim Smith
Mondoo Core Team

πŸ₯³ 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.

New Integrations

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.

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 includes platformVersion data.
  • aws.ecs.container now includes platformVersion, runtimeId, and containerName data.
  • aws.ecs.cluster now includes containerInstances data.
  • aws.ecs.image now includes uri 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.

New Sorting of 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.

New Login Screen

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.

Better error output

πŸ› BUG FIXES AND UPDATES​

  • We now correctly detect services on Kali Linux.
  • Mondoo EOL policy now executes on FreeBSD hosts.
  • cnquery run and cnspec 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 of Jan 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 just ipv4/ipv6.
  • Resolve failures scanning container registries.
  • Label container image assets with all discovered tags when scanning container registries.