Explorer security model

View as Markdown

runZero Explorers run network scans, sample traffic for passive discovery, and execute integrations inside the environment where you deploy them. This page describes how runZero secures them, from development through uninstallation.

Development

runZero Explorers are written in Go, which gives them cross-platform compatibility and memory safety by default. The runZero engineering team updates the Explorer code and its dependencies continuously so that dependency-level vulnerabilities are resolved quickly. Every engineer must use MFA to access our Git repository. Each code change is reviewed manually before it merges to our development branch and deploys to a test environment, then reviewed again before it merges to our staging branch and deploys to a staging environment. During the build, runZero signs each Explorer binary with a private Ed25519 key and stamps the signature into the end of the binary. Windows binaries also get an Authenticode signature from an extended-validation certificate stored in a cloud-based HSM. Once all automated tests pass and any behavior changes are confirmed, the staging binaries are tagged for release and moved to the production deployment location in AWS S3.

Deployment

You provision an Explorer by hand the first time: download it directly from the runZero Console (cloud or self-hosted). Installing an Explorer covers the steps. The download stamps the link token and organization ID into the binary while preserving the code signatures. On the deployed system, the binary connects back to its stamped Console URL, validates TLS, and registers. Registration starts with the Explorer generating a unique host ID from the operating system’s random source. The Explorer stores the ID with limited permissions in its file system (non-Windows) or the registry (Windows) and uses it to confirm its identity on future connections.

On a new Explorer’s first connection, the Console records the Explorer-generated host ID and creates a database record for that instance. No other Explorer, even one on the same system, can claim that record without possessing and verifying the host ID. By default, a new Explorer receives no data from the Console and no tasks (including tasks with credentials) until a user selects it manually. As a result, registered but untrusted Explorers are relatively safe, as long as you don’t use them for tasks that include sensitive data (typically integrations with credentials).

Once an Explorer has the Organization ID, it no longer needs the link token (Download Token) to connect and register. runZero plans to require the current Download Token in the near future. It is not a requirement yet, because unauthorized Explorer registrations expose few if any security risks. Once registration requires the current Download Token, older Explorers won’t be able to reconnect after the Download Token is rotated. Active Explorers should always receive the latest Download Token as part of the upgrade request.

Commands

The runZero Console sends Explorers new tasks and a few specific requests. Tasks are limited to active scans, passive traffic sampling, and integrations. Integrations can run custom code written in the Starlark language; that code has access to the network but no access to the Explorer host machine or its file system. Outside of tasks, Explorers accept requests to uninstall, update, and post diagnostics (limited to stack traces and Explorer attributes like operating system and hardware specifications). Explorers implement no commands for network tunneling or host access to the Explorer’s machine.

The Console sends credentials to an Explorer only for an integration task, and only when the task scope matches the CIDR or other configuration for those credentials. It never sends credentials to runZero-hosted External Explorers, regardless of the task configuration. Credential parameters travel in the same TLS connection as the request and are also encrypted to a unique per-process AGE encryption key. Even if runZero traffic is logged through a TLS proxy with a pinned CA, the credentials cannot be recovered without also extracting the private, in-process-only, temporary AGE key.

Updates

Before scheduling a task (scan, passive, or integration), the runZero Console checks that the Explorer is running the latest version. An out-of-date Explorer is updated first, and the task is scheduled once the update completes. If the update takes longer than an internal threshold, or fails for a reason like a read-only filesystem on the Explorer, the task is scheduled anyway once that threshold passes.

The update request carries a URL for the new binary. The Explorer connects to that URL, verifies the TLS parameters, and downloads the binary to a temporary directory. It then checks that the binary carries a valid embedded code signature and rejects the update if the check fails. If the signature is valid, the Explorer launches the new binary in update mode, which typically replaces the running service with the new executable.

An update can also change the Explorer service’s Organization or even its Console; this is how Explorers move between installations and organizations. In either case, the TLS connection must be valid and the binary must carry a valid code signature. The same verification rejects version downgrades by comparing the signed version metadata in the binary against the running version.

Uninstallation

Deleting a runZero Organization automatically uninstalls its Explorers. You can also uninstall an Explorer from the runZero Console or with the “uninstall” CLI option of the Explorer binary. During uninstallation the Explorer removes as many artifacts as it can. You can remove any leftovers by hand (common on Windows systems, where the OS locks the program files and directory while the Explorer is running).

Defense in depth

runZero layers multiple defenses into its architecture to protect customer data:

  • An attacker who can push code to our internal repository still needs to pass review before it can merge into our protected staging branch.

  • An attacker who compromises our binary distribution point (AWS S3) still needs a valid signing key to affect any customer update. The Explorer also compares authenticated, signed version metadata, which prevents downgrade attacks.

  • An attacker who obtains a customer’s download link can register new Explorers but gets no data from the Console unless a user specifically chooses those Explorers for a task.

  • An attacker who can send commands to an Explorer (by compromising a Console) is limited to a few relatively safe commands and cannot force downgrades or arbitrary code execution on the Explorer host.

  • An attacker who can MiTM the TLS communication with the Console cannot decrypt the credentials used in integration tasks.

  • An attacker who can schedule a custom integration task with a malicious Starlark script can reach the network from the Explorer’s perspective but cannot access the Explorer host.

In every one of these situations, runZero also runs extensive logging and alerting, so we can investigate any malicious action and assess the impact of any issue.

Updated