CLI documentation

Run the OpenCloud Security Scanner with Docker

Run OpenCloud security scans in Docker, including JSON output and private networks.

Run the scanner on your own machine with the published Docker image. It uses the same scanner as the web service, connects directly to your instance and has no website rate limit. You need Docker, but no account with the scan service.

docker run --rm --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.example.com

That is the whole thing. It prints the same line a monitoring system would get:

OK: Server is up to date. No known vulnerabilities.
OpenCloud 7.2.3 on opencloud.example.com, rating: A+, last scanned: 2026-08-25 09:41:12
Release lifecycle: 7.2 (production, track detected), current release

The exit code is the Nagios one - 0 OK, 1 WARNING, 2 CRITICAL, 3 UNKNOWN - so the same line works in a script, a pipeline or a cron job without anything else around it.

Trademark notice. This project is independent. It is not affiliated with, endorsed by or supported by OpenCloud GmbH. "OpenCloud" and all related marks belong to their respective owners and are used here only to identify the software being checked.

What the image is

okxo/opencloud-scanner is built from this repository and carries both entry points:

Entry point What it does
check-opencloud-security The Nagios/Icinga plugin: one status line, perfdata, an exit code
check-opencloud-scanner The scanner on its own: the whole result document as JSON, or an HTTP service

The image's default command starts the web application, which is why every line here passes --entrypoint. Pin a version instead of latest (okxo/opencloud-scanner:1.9) if you want the command to keep behaving the same next month.

The same scan, as JSON

Everything the web interface draws comes from this document - the rating, the release lifecycle, the advisories, every check and the remediation plan:

docker run --rm --entrypoint check-opencloud-scanner \
  okxo/opencloud-scanner:latest scan opencloud.example.com

Pipe it into jq for the parts you care about:

docker run --rm --entrypoint check-opencloud-scanner \
  okxo/opencloud-scanner:latest scan opencloud.example.com \
  | jq '{rating, version, addresses, failed: [.extraChecks[] | select(.passed | not) | .id]}'

addresses is the IPv4 and IPv6 the name resolved to when the scan ran - the same pair the result page shows under Resolved to, and worth a second look when a scan reports something you did not expect: a name pointing at an old address explains a surprising number of surprising results.

Useful variations

Explain every finding rather than only naming it:

docker run --rm --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.example.com --debug

Accept a finding you have decided to live with, exactly as the tick boxes on the website do:

docker run --rm --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.example.com \
  --ignore-hardening basicAuthDisabled

Rate the version against a particular release track rather than the one the scan infers:

docker run --rm --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.example.com \
  --release-track lts

Scan an instance that is not on the internet - a staging box on your own network, or one behind a name only your resolver knows:

docker run --rm --network host --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.internal.example.com

The hosted service refuses a private address on purpose; your own machine has no reason to.

Configure it with environment variables instead of flags, which is easier to template over a list of hosts - every option has a COS_ variable, listed in the main README:

docker run --rm -e COS_HOST=opencloud.example.com \
  --entrypoint check-opencloud-security okxo/opencloud-scanner:latest

Skip the update check when the machine has no internet access, or when you do not want the release feed contacted at all:

docker run --rm --entrypoint check-opencloud-security \
  okxo/opencloud-scanner:latest --host opencloud.example.com --no-update-check

Make it shorter

If you run this often, a shell function turns it into one word:

# ~/.bashrc or ~/.zshrc
opencloud-scan() {
  docker run --rm --entrypoint check-opencloud-security \
    okxo/opencloud-scanner:latest --host "$1" "${@:2}"
}
opencloud-scan opencloud.example.com --debug

Without Docker

The check is on PyPI and is a normal Python program, so uv or pipx will run it with no container at all:

uvx --from check-opencloud-security check-opencloud-security \
  --host opencloud.example.com
pipx run --spec check-opencloud-security check-opencloud-security \
  --host opencloud.example.com

Where to go next