Mondoo Platform
Publish xgrep code findings and dependency vulnerabilities to Mondoo Platform, where they attach to the scanned repository as an asset and join your security posture.
Reporting to Mondoo Platform
xgrep emits findings locally in several formats — text, JSON, SARIF, and GitLab SAST. When a Mondoo service account is configured, it additionally publishes those findings to Mondoo Platform, where they attach to the scanned repository as an asset and join the rest of your organization's security posture (alongside cnspec policy results, vulnerability data, and findings from other tools).
xgrep scan . # reports automatically when logged in (default branch only)
xgrep scan --incognito . # local only; nothing is uploadedReporting is automatic when credentials are present (after xgrep login or a configured service account), matching
cnspec. There is no flag to turn it on; pass --incognito to turn it off for a
local-only scan. It never replaces or changes local output — the same
text/JSON/SARIF you would get otherwise still prints. The upload is purely
additive.
Both kinds of finding a scan produces are published: code (SAST) findings and dependency vulnerabilities. They land on the same repository asset, so a repo's SAST and SCA results sit together on the platform.
How findings map to the platform
- One asset per repository. All findings from a scan land on a single asset identified by the repository's git remote (host / owner / repository / URL), with branch and revision as context. This reuses the same provenance xgrep derives for SARIF and GitLab reports, so a repo scanned by xgrep dedupes against the same asset the GitHub/GitLab integrations already track.
- Stable finding identity. Each finding is keyed by xgrep's fingerprint (rule + path + line + matched code), so re-scanning the same code updates the existing finding rather than creating duplicates.
- Severity, CWE/OWASP, and remediation ride along. A finding's severity maps to Mondoo's rating using the same vocabulary as the SARIF/GitLab renderers (CRITICAL/ERROR → HIGH, WARNING → MEDIUM, INFO → LOW), and its CWE/OWASP metadata and fix hint become references and remediation on the platform.
- Suppressed findings are not uploaded. A finding muted with
nosemgrepis excluded from the upload, matching how it is dropped from the GitLab report. - At most 100 findings per scan. To keep uploads bounded, a scan publishes up
to 100 code findings; when there are more, the highest-severity ones are
kept (ties broken by a stable per-finding key, so the selection is the same
across runs). The full set always renders locally — only the upload is capped.
xgrep notes when this happens, e.g.
Reported 100 of 17623 findings (highest severity).
Dependency vulnerabilities
When the scan also finds
dependency vulnerabilities,
those are uploaded too — as VEX (Vulnerability Exchange) documents rather than
code-finding FEX, re-homed onto the same repository asset. You get a separate
stderr note, e.g. reported 3 dependency vulnerability finding(s) to Mondoo Platform. The vulnerability scan itself is always ephemeral — nothing is stored
server-side; when reporting is enabled, xgrep uploads the resulting VEX from the
client and attaches it to the repository asset.
Credentials
Uploading requires Mondoo credentials — a service-account config (the same
mondoo.yml format cnspec uses). The easiest way to get one is xgrep login;
in CI you provide an existing config via environment variable.
xgrep login (interactive)
xgrep login --token <registration-token>Generate a registration token in the Mondoo Console under
Space → Settings → Registration Token, then run xgrep login. It exchanges
the token for a service account and writes the standard config (default
~/.config/mondoo/mondoo.yml), after which xgrep scan reports automatically
with no further flags. You stay logged in until the config is removed.
| Flag | Purpose |
|---|---|
--token <token> | The registration token (required). |
--api-endpoint <url> | Target a private / self-hosted deployment not reachable at the default SaaS endpoint. Defaults to the endpoint encoded in the token. |
--mondoo-config <path> | Where to write the config (default: $MONDOO_CONFIG_PATH or ~/.config/mondoo/mondoo.yml). |
--name <name> | Client name to register (default: hostname). |
--annotation key=value | Client annotations as key=value pairs (repeatable). |
xgrep login authenticates identically to cnspec login, so a host already
logged in with cnspec needs no separate xgrep login — the same mondoo.yml
works.
Providing a config directly (CI/CD)
Don't run login in CI. Instead provide an existing service-account config
through the environment. xgrep resolves credentials in this order:
-
MONDOO_CONFIG_BASE64— the entiremondoo.yml, base64-encoded. This takes precedence over everything and is the most convenient way to pass a service account as a single CI secret (no file to write):export MONDOO_CONFIG_BASE64="$(base64 < mondoo.yml | tr -d '\n')" # or a CI secret xgrep scan . # reports automatically — the config is detected -
--mondoo-config <path>— an explicit config file path. -
MONDOO_CONFIG_PATH— a config file path from the environment. -
~/.config/mondoo/mondoo.yml— the default location.
By default findings go to the space encoded in the service account; pass
--scope-mrn <mrn> to target a different space or organization.
# Explicit service-account config and target space.
xgrep scan \
--mondoo-config ./mondoo-svc.yml \
--scope-mrn //captain.api.mondoo.app/spaces/keen-shockley-123456 \
.Workload Identity Federation (keyless CI)
To avoid storing a long-lived service account at all, a mondoo.yml can use
Workload Identity Federation (WIF): the platform exchanges a short-lived OIDC
token from the CI provider (e.g. GitHub Actions) for temporary credentials. This
needs a matching WIF auth binding configured in the Mondoo space. The config
selects the wif auth method and the federated issuer:
api_endpoint: https://us.api.mondoo.com
auth:
method: wif
audience: <audience configured on the WIF binding>
issuerUri: https://token.actions.githubusercontent.comProvide the runner's OIDC token via the JWT_TOKEN environment variable (or
jwtToken in the config). xgrep resolves this implicitly through the shared
Mondoo config loader, so xgrep scan reports automatically with no static
secret. See the Mondoo Platform docs for setting up the WIF binding.
Automatic and best-effort
Reporting is designed to be safe to leave in a command that also runs in IDEs, local dev, and CI:
- Automatic, opt-out. xgrep reports whenever a Mondoo service account is
configured. There is no flag to enable it; pass
--incognitofor a local-only scan that uploads nothing. With no service account configured, reporting is silently skipped — so xgrep stays quiet for users who don't use the platform. - Default branch only. Reporting happens only when the scan runs against the repository's default branch, so feature branches and pull requests don't overwrite the canonical per-repo asset state. The branch is read from CI environment variables when present (GitHub Actions, GitLab, Azure DevOps) and from git otherwise; when it can't be determined, reporting is skipped. The ephemeral dependency-vulnerability scan still runs on any branch (so CVEs render locally) — only the upload is branch-gated.
- Best-effort, never fails the scan. If an upload errors, xgrep logs a warning and continues. This never changes the exit code or the local output — a broken or unauthenticated upload can't break a scan or a CI gate.
On success xgrep prints a short note to stderr (kept off the stdout report), e.g.
reported 5 finding(s) to Mondoo Platform.
In CI
Reporting works the same in CI as locally: configure a service account and every
xgrep ci / xgrep scan publishes to the platform in the same step it gates the
build. MONDOO_CONFIG_BASE64 is the simplest way to supply the account (one
secret, no file to write); keep --error / --max-findings for the local gate,
since the upload runs independently of the exit code:
# GitHub Actions
- run: npm install -g @mondoohq/xgrep
- run: xgrep ci --error
env:
MONDOO_CONFIG_BASE64: ${{ secrets.MONDOO_CONFIG_BASE64 }}Store the secret by base64-encoding a service-account mondoo.yml
(base64 < mondoo.yml | tr -d '\n'). For keyless pipelines, use a WIF config
instead (see above).
Because the upload is best-effort, a credential or network hiccup in CI surfaces as a warning rather than a failed job; the scan's own findings still gate the build via the exit code.
Flags
| Flag | Purpose |
|---|---|
--incognito | Local-only scan: do not upload anything to Mondoo Platform (reporting is otherwise automatic when a service account is configured). |
--mondoo-config <path> | Path to the Mondoo service-account config (default: MONDOO_CONFIG_PATH, then ~/.config/mondoo/mondoo.yml). Named to avoid colliding with -c/--config, the rules alias. |
--scope-mrn <mrn> | Target Mondoo space/org MRN (defaults to the scope in the service-account config). |
The legacy
--report mondooflag is deprecated and no longer required — reporting is automatic. It is still accepted (hidden) so existing pipelines don't break.