Remote Scanning with Inventory Files
Scan remote systems, network devices, and cloud accounts by defining targets and credentials in a single inventory file.
cnspec can scan the machine it's installed on, but many targets, like network devices, cloud accounts, SaaS tenants, or servers where you can't install cnspec, require remote access. An inventory file lets you list those remote targets in one place, along with the credentials cnspec needs to reach them, so you can scan your entire fleet with a single command.
An inventory file is a YAML document that defines:
- What to scan: hosts, cloud accounts, Kubernetes clusters, SaaS tenants, and more
- How to connect: SSH, WinRM, cloud APIs, container runtimes, and other connection types
- How to authenticate: passwords, SSH keys, API tokens, or references to external vaults like HashiCorp Vault and AWS Secrets Manager
Pass the file to cnspec or cnquery with --inventory-file:
cnspec scan --inventory-file inventory.ymlStructure
Every inventory file follows this structure:
apiVersion: v1
kind: Inventory
metadata:
name: my-inventory
labels:
environment: production
spec:
assets:
- name: display-name
connections:
- type: ssh
host: 10.0.0.1
port: 22
credentials:
- user: ubuntu
private_key_path: ./id_rsa
credentials:
# Optional: central credential store (referenced by secret_id)
vault:
# Optional: external vault configurationTop-level fields
| Field | Description |
|---|---|
apiVersion | Always v1. |
kind | Always Inventory. |
metadata.name | A human-readable name for this inventory. |
metadata.labels | Key-value pairs for organizing assets. |
spec.assets | List of assets to scan. |
spec.credentials | Optional map of named credentials (see Credential references). |
spec.vault | Optional external vault configuration (see Vault integration). |
spec.credential_query | Optional MQL query for dynamic credential resolution. |
Asset fields
Each entry in spec.assets supports:
| Field | Description |
|---|---|
name | Display name for the asset. |
id | Optional unique identifier. |
connections | List of connection configurations. |
annotations | Key-value metadata that displays in Mondoo Console. |
labels | Key-value pairs for filtering and grouping. |
Connection fields
| Field | Description |
|---|---|
type | Connection type: ssh, winrm, aws, azure, gcp, k8s, docker, vsphere, ms365, google-workspace, local, and others. |
host | Hostname or IP address. |
port | Port number (defaults depend on connection type). |
credentials | List of credentials for this connection. |
discover | Optional discovery configuration (see Discovery). |
sudo | Optional sudo configuration for privilege escalation. |
insecure | Set to true to skip TLS verification. |
options | Provider-specific key-value options. |
Credentials
The simplest approach is to specify credentials directly on each connection. For larger inventories, you can define credentials once and reference them across assets, or pull them from an external vault.
Inline credentials
Specify credentials directly on a connection:
spec:
assets:
- name: web-server
connections:
- type: ssh
host: 192.168.1.10
credentials:
- type: password
user: admin
password: s3cretspec:
assets:
- name: web-server
connections:
- type: ssh
host: 192.168.1.10
credentials:
- user: ubuntu
private_key_path: ~/.ssh/id_rsaspec:
assets:
- name: web-server
connections:
- type: ssh
host: 192.168.1.10
credentials:
- user: ubuntu
private_key: <base64-encoded private key>To encode your key, run:
base64 -i ~/.ssh/id_rsaThe credential type is inferred automatically when you use password, private_key, or private_key_path. You don't need to set type explicitly in most cases.
SSH agent
Use the system SSH agent instead of storing keys:
credentials:
- type: ssh_agent
user: ubuntuReference credentials with secret_id
When multiple assets share the same credentials, define them once in spec.credentials and reference them by secret_id:
spec:
assets:
- name: web-01
connections:
- type: ssh
host: 10.0.0.1
credentials:
- secret_id: my-ssh-key
- name: web-02
connections:
- type: ssh
host: 10.0.0.2
credentials:
- secret_id: my-ssh-key
credentials:
my-ssh-key:
user: ubuntu
private_key_path: ~/.ssh/id_rsaEnvironment variables
Load a credential value from an environment variable:
spec:
credentials:
my-env-secret:
type: env
env: MY_SECRET_VARCredential types
| Type | Description |
|---|---|
password | Username and password. |
private_key | SSH private key (PEM-encoded, inline or from file). |
ssh_agent | System SSH agent forwarding. |
bearer | Bearer token for API authentication. |
json | JSON-encoded secret (for cloud service accounts). |
pkcs12 | Certificate-based authentication (PEM file). |
env | Load secret from an environment variable. |
aws_ec2_instance_connect | AWS EC2 Instance Connect. |
aws_ec2_ssm_session | AWS Systems Manager Session Manager. |
When you use private_key_path with a relative path, it resolves relative to the inventory file location, not your current working directory. For example, if your inventory is at /etc/mondoo/inventory.yml and contains private_key_path: ./keys/id_rsa, cnspec looks for /etc/mondoo/keys/id_rsa. Paths starting with ~/ expand to the current user's home directory. Absolute paths are used as-is.
Vault integration
Instead of storing secrets in the inventory file, you can use an external vault. Define the vault in spec.vault and reference secrets by their vault key:
spec:
assets:
- name: vsphere-env
connections:
- type: vsphere
host: 192.168.5.24
insecure: true
credentials:
- secret_id: vcenter/mondoo-read
discover:
targets:
- auto
vault:
name: my-vault
type: hashicorp-vault
options:
url: http://127.0.0.1:8200
token: XXXXXXXXSupported vault types
| Type | Description |
|---|---|
keyring | System keyring (macOS Keychain, GNOME Keyring, Windows Credential Manager). |
linux-kernel-keyring | Linux kernel keyring (persistent). |
encrypted-file | Local encrypted file. Options: path, password. |
hashicorp-vault | HashiCorp Vault server. Options: url, token. |
aws-secrets-manager | AWS Secrets Manager. Uses AWS environment credentials. |
aws-parameter-store | AWS Systems Manager Parameter Store. Uses AWS environment credentials. |
gcp-secret-manager | Google Cloud Secret Manager. Options: project-id. |
gcp-berglas | GCP Berglas. Options: project-id, kms-key-id, bucket-name. |
Configure a vault from the CLI
You can add vault configuration directly to an existing inventory file:
cnspec vault configure my-vault \
--type hashicorp-vault \
--option url=http://127.0.0.1:8200 \
--option token=XXXXXXXX \
--inventory-file inventory.ymlTo store a secret in the configured vault:
cnspec vault add-secret my-secret-id "secret-value" \
--inventory-file inventory.ymlDiscovery
Some connection types can automatically find and scan related assets, such as all EC2 instances in an AWS account or all containers on a host. Use the discover block to enable this:
spec:
assets:
- name: aws-account
connections:
- type: aws
discover:
targets:
- auto
options:
profile: productionspec:
assets:
- connections:
- type: local
discover:
targets:
- containerDiscovery targets depend on the provider. Common targets include auto, all, compute, storage, container, container-images, and host-machines. Refer to each provider's documentation for available targets.
Annotations
Add metadata to assets that appears in Mondoo Console:
spec:
assets:
- name: prod-web
connections:
- type: ssh
host: 10.0.0.1
credentials:
- type: ssh_agent
user: ubuntu
annotations:
Owner: ops-team
Environment: productionYou can also pass annotations from the CLI. They apply to all assets in the inventory:
cnspec scan --inventory-file inventory.yml --annotations Environment=stagingSudo
To run scans with elevated privileges over SSH, enable sudo on the connection:
connections:
- type: ssh
host: 10.0.0.1
credentials:
- type: ssh_agent
user: deploy
sudo:
active: true
user: rootInventory templates
Instead of hardcoding connection details, you can use templates to substitute environment variables at scan time. Use the getenv function to reference them:
spec:
assets:
- name: { { getenv "ASSET_NAME" } }
connections:
- type: ssh
host: { { getenv "TARGET_HOST" } }
credentials:
- user: { { getenv "SSH_USER" } }
private_key_path: { { getenv "SSH_KEY_PATH" } }Run the template with --inventory-template:
ASSET_NAME="web-01" TARGET_HOST="10.0.0.1" SSH_USER="ubuntu" SSH_KEY_PATH="~/.ssh/id_rsa" \
cnspec scan --inventory-template template.ymlTemplates are useful in CI/CD pipelines where connection details vary between environments.
Alternative inventory formats
Ansible inventory
cnspec can read Ansible inventory files in JSON format. Generate one with:
ansible-inventory --list > ansible-inventory.jsonThen scan using:
cnspec scan --inventory-file ansible-inventory.json --inventory-format-ansibleDomain list
A plain text file with one hostname per line:
# Production web servers
web-01.example.com
web-02.example.com
192.168.1.50:2222Scan with:
cnspec scan --inventory-file hosts.txt --inventory-format-domainlistExamples
Multi-cloud inventory
apiVersion: v1
kind: Inventory
metadata:
name: multi-cloud
spec:
assets:
- name: aws-production
connections:
- type: aws
options:
profile: prod-account
discover:
targets:
- auto
- name: gcp-project
connections:
- type: gcp
options:
project: my-gcp-project
discover:
targets:
- auto
- name: azure-tenant
connections:
- type: azure
credentials:
- type: pkcs12
private_key_path: ./azure-cert.pem
options:
client-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
tenant-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
discover:
targets:
- autoSSH fleet with shared credentials
apiVersion: v1
kind: Inventory
metadata:
name: ssh-fleet
spec:
assets:
- name: web-01
connections:
- type: ssh
host: 10.0.0.1
credentials:
- secret_id: fleet-key
- name: web-02
connections:
- type: ssh
host: 10.0.0.2
credentials:
- secret_id: fleet-key
- name: db-01
connections:
- type: ssh
host: 10.0.1.1
credentials:
- secret_id: fleet-key
credentials:
fleet-key:
user: ubuntu
private_key_path: ~/.ssh/fleet_id_rsaMicrosoft 365
apiVersion: v1
kind: Inventory
metadata:
name: m365-inventory
spec:
assets:
- connections:
- type: ms365
credentials:
- type: pkcs12
private_key_path: ./certificate.pem
options:
client-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
tenant-id: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
discover:
targets:
- autoKubernetes
apiVersion: v1
kind: Inventory
metadata:
name: k8s-inventory
spec:
assets:
- name: production-cluster
connections:
- type: k8s
options:
kubeconfig: ~/.kube/config
context: production
discover:
targets:
- autovSphere with HashiCorp Vault
apiVersion: v1
kind: Inventory
metadata:
name: vsphere-inventory
spec:
assets:
- name: vsphere
connections:
- type: vsphere
host: vcenter.example.com
insecure: true
credentials:
- secret_id: vcenter/admin
discover:
targets:
- host-machines
annotations:
Owner: infra-team
vault:
name: hcv
type: hashicorp-vault
options:
url: http://vault.internal:8200
token: s.xxxxxxxxxxxxxxxxxxxxxxxx