Pull-mode fetch

Pull mode lets the Xygeni scanner call a third-party tool's API directly, fetch the findings, and route them through the same loader+converter pipeline that processes file uploads. No intermediate report file on disk; credentials read from environment variables; resolved auth headers and tokens redacted from logs.

When you'd use it over convert+upload:

  • The tool exposes a documented findings API and your pipeline doesn't already collect a report file.

  • You'd rather not stage credentials inside a CI artifact or a checked-in JSON.

  • You want one CLI invocation to drive both the fetch and the conversion.

When not to use it:

  • The tool only writes to disk — keep using convert+upload.

  • The tool actively pushes to consumers — see the push (webhook) mode; the per-adapter setup guide will be added to this section as each webhook integration ships.

How to invoke

xygeni report-upload --pull --format <id> \
  --selector key=value [--selector ...] \
  --filter  key=value [--filter ...] \
  [--name <project>] [--no-upload] [--output <path>]
  • --pull switches the command from reading --report files to fetching from the API.

  • --format (exactly one) selects the registry entry; the entry must declare a pull: block (i.e. one of the formats listed below).

  • --selector carries per-scan identifiers the tool needs — project key, branch, application name, organization, scan id, tenant. Always required for tools that scope findings to a project.

  • --filter carries tool-specific findings filters — severity, status, time window, cloud platform. Optional; each fetcher documents its own filter keys.

  • --no-upload runs the fetch + conversion but skips the upload to Xygeni. Pair with --output <file> to inspect the converted payload before wiring the command into CI.

Credentials and environment variables

Each tool reads its credentials from environment variables. The scanner refuses to start if a referenced variable is unset (fail-closed); it never embeds the resolved secret into the converted output; and it registers the resolved value with the log redactor so any subsequent log line that would print it shows *** instead.

The naming convention is <TOOL>_URL, <TOOL>_TOKEN / <TOOL>_CLIENT_ID / <TOOL>_CLIENT_SECRET, etc. — the exact set is listed per-tool below.

You can also pass -Dname=value on the Java command line as a fall-through when an environment variable can't be exported (e.g. some containerised runners). The framework checks env vars first, then Java system properties.

Worked examples per tool

SonarQube / SonarCloud

Two registry entries — sast-sonarcloud (bearer-token auth) and sast-sonarqube (basic auth with the API token as the username and an empty password, per SonarQube Server's traditional auth scheme).

SonarCloud

SonarQube Server

Both invocations pull security issues from /api/issues/search and security hotspots from /api/hotspots/search, merge and deduplicate, and write a single document in the same shape the existing sast-sonarqube / sast-sonarcloud loaders consume for file uploads. Pagination, retry/backoff and log redaction are handled by the framework.

Selector
Required
Notes

project_key

yes

SonarQube / SonarCloud project key

branch

no

Branch analysis to query

pullRequest

no

PR analysis id

organization

no

SonarCloud only

Filter
Notes

severity

Comma-separated severities (e.g. HIGH,CRITICAL). Applied to issues; hotspots use a different vulnerability-probability filter that isn't currently forwarded.

status

Comma-separated for issues. Hotspots accept only TO_REVIEW / REVIEWED — when multiple values are supplied, only the first is forwarded to that endpoint.

Kiuwan

Two registry entries:

  • sast-kiuwanfile upload of the XML report produced by the Kiuwan Local Analyzer custom ExportRule. Documented in the Report upload for Kiuwan page; recommended only if you already have that pipeline set up.

  • sast-kiuwan-apipull mode, calling Kiuwan's native REST API. Recommended for new integrations: no Kiuwan-side install, no Local Analyzer custom rule, no quality-model edits. Carries source/sink data-flow detail that SARIF / CSV exports drop.

With an explicit analysis + filters:

Selector
Required
Notes

application

yes

Kiuwan application name

analysisCode

no

Specific scan to fetch. Default: result of /applications/last_analysis.

Filter
Notes

priority

Comma-separated. Very low,Low,Normal,High,Very high.

characteristic

Comma-separated. Defaults to Security (SAST scope); pass to widen, e.g. Security,Reliability.

language

Comma-separated tool-defined language list (e.g. java,javascript).

muted

true / false.

Auth is HTTP Basic with the Kiuwan API user code as the username and the token as the password.

Checkmarx One — SAST + SCA + IaC

Pull mode is wired on three registry entries — sast-checkmarx-one, sca-checkmarx-one, iac-checkmarx-one. They share a single fetcher; Checkmarx One's /api/results endpoint returns all three engines' findings in one document and each entry's converter slices its own engine out.

With an explicit scan + filters:

Selector
Required
Notes

tenant

yes

Checkmarx One tenant name; interpolated into the OAuth2 token endpoint URL

project_id

one of

UUID of the Checkmarx One project

project_name

one of

Human-readable name; resolved to project_id via /api/projects?name=…

scan_id

no

Specific scan to fetch. Default: latest scan for the project.

Filter
Notes

severity

Comma-separated HIGH,MEDIUM,LOW,INFO

state

Result state enum (TO_VERIFY, NOT_EXPLOITABLE, CONFIRMED, …)

status

NEW, RECURRENT, FIXED

Auth: OAuth2 client credentials. The framework caches the access token by its declared expires_in and refreshes it automatically.

Prisma Cloud — CSPM alerts + asset inventory

Two registry entries — iac-prisma-cloud (CSPM security alerts / policy violations) and inventory-prisma-cloud (cloud asset inventory). One fetcher drives both; each entry picks its endpoint internally.

With filters:

Filter
Applies to
Notes

time_range_days

both

Window length. Default 30 for alerts, 1 for inventory.

cloud

both

Comma-separated cloud providers (aws, azure, gcp, alibaba_cloud, oci).

status

alerts

Single value: open, dismissed, resolved, snoozed. Default open.

severity

alerts

Comma-separated critical,high,medium,low,informational.

resource_type

inventory

Comma-separated resource types (e.g. aws_ec2_instance,gcp_compute_instance).

rql

inventory

Raw RQL query used verbatim (escape hatch — disables the cloud / resource_type composition). Example: --filter rql="config from cloud.resource where finding.type = 'CVE'".

with_resource_json

inventory

true (default) embeds the full provider-specific resource JSON in each item; set to false for a leaner payload.

Inventory uses Prisma Cloud's RQL (Resource Query Language). Auth is handled by the fetcher (POST /login for an x-redlock-auth token; transparent re-auth on 401); the registry declares auth.type: basic only to flow the access key + secret key through env-var resolution and log redaction.

Wiz CNAPP

Four registry entries — iac-wiz-issues, sca-wiz-cnapp, iac-wiz-config, inventory-wiz-cnapp. A single fetcher drives all four via per-entry selectorDefaults.mode. Wiz is the first GraphQL fetcher in the pull framework; the GraphQL endpoint and OAuth2 token URL are both configurable so any region (US / EU / Gov) works without code changes.

Filter
Applies to
Notes

status

issues / vulnerabilities / config_findings

Filtering the resolution state

severity

issues / vulnerabilities / config_findings

Wiz severity enum. The fetcher remaps the filter key to vendorSeverity for the vulnerabilities mode (Wiz schema quirk)

type

issues / cloud_resources

Issue category for issues; Wiz resource type for inventory

result

config_findings

FAIL, ERROR

cloud_platform

cloud_resources

AWS, AZURE, GCP, …

page_size

all

Page size — clamped to Wiz's documented 500 max

Auth: OAuth2 client credentials with the audience=wiz-api claim. The framework caches the access token by expires_in and refreshes it automatically; the token URL is configurable so the same registry entry works against both Cognito-backed and legacy Auth0-backed Wiz tenants.

Dry-run and inspecting the converted payload

Before wiring the command into CI, run it once with --no-upload --output <path> to inspect the converted JSON:

The output file holds the same payload that would have been uploaded — useful for verifying severity mapping, project name inference, or filter coverage.

Troubleshooting

"No value for ${env:X} — set the Java system property -DX=… or export the env var X" The scanner refuses to run with an unresolved secret. Export the variable in the same shell that invokes xygeni, or pass -DX=value on the Java command line if your runner can't export environment variables.

"Format '' has no pull: block configured" The format you passed to -f exists as a convert+upload entry but doesn't yet support pull mode. Either drop --pull and supply --report, or pick a format from the supported list above.

"--pull requires exactly one --format" Pull mode takes one format per invocation. If you need to fetch from multiple tools, issue multiple commands.

HTTP 401 / 403 The token doesn't have permission for the resource you asked for. The error message includes the path that failed — verify the project key / scan id / tenant against the tool's UI, and check the token's scope.

Retries exhausted The fetcher retries transient failures (HTTP 5xx, network errors) with exponential backoff. If retries exhaust, the tool's API is likely down — check the tool's status page and rerun. Pull mode is idempotent; re-invoking after a transient failure is safe.

Last updated