Surveyor

Configuration

Two kinds of settings control a survey. Host environment variables tell the spice wrapper how to run the CLI: which image, whether to pull it, and whether to use Docker at all. Survey settings, such as thread counts and log level, live in a configuration file and can be overridden by environment variables and options.

Credentials

VariableWhat it holds
SPICE_PASSYour Spice Pass. Needed to upload surveys. Generate one in the dashboard.
SPICE_LICENSEA Spice License, for the editions that need one. See Editions and licenses.

Set only one of them. When both are set, spice stops with Both SPICE_PASS and SPICE_LICENSE are set; set only one. Neither has a configuration file setting.

Host environment variables

The wrapper reads these on your machine before the CLI starts.

VariableDefaultWhat it does
SPICE_IMAGEspicelabs/spice-labs-cliThe CLI image to run. When set, it is used exactly as written, including any tag.
SPICE_IMAGE_TAGlatestThe image tag. Used only when SPICE_IMAGE is not set.
SPICE_LABS_CLI_SKIP_PULL01 skips pulling the image and the wrapper’s update check. The image must already be on the machine.
SPICE_DOCKER_NETWORKhostThe network the CLI’s container uses. none cuts it off from the network.
SPICE_DOCKER_FLAGSnoneExtra options added to the docker run command, separated by spaces. Not applied to runtime surveys.
DOCKER_CONFIG~/.dockerThe Docker configuration folder whose registry credentials image surveys use, mounted read-only.
SPICE_LABS_JVM_ARGS-XX:MaxRAMPercentage=75Options for the JVM that runs the CLI. It is passed into the container when you set it.

The wrapper also takes a --features option before the command: --features it, --features itpro or --features otpro runs ghcr.io/spice-labs-inc/spice-labs-cli-it, -itpro or -otpro (tag latest) when SPICE_IMAGE is not set. The option is not passed on to the CLI.

Pin the CLI version

By default every run pulls spicelabs/spice-labs-cli:latest. To stay on one version, set the tag:

export SPICE_IMAGE_TAG=1.9.2
$env:SPICE_IMAGE_TAG = "1.9.2"

SPICE_IMAGE takes priority over everything else that picks an image. When it is set, spice runs exactly that reference: SPICE_IMAGE_TAG and the --features option are ignored, and an image named without a tag means latest. So if you set SPICE_IMAGE, put the tag in it:

export SPICE_IMAGE=spicelabs/spice-labs-cli:1.9.2
$env:SPICE_IMAGE = "spicelabs/spice-labs-cli:1.9.2"

Run without network access

To prove a survey makes no network calls, cut the container off from the network and skip the upload:

SPICE_DOCKER_NETWORK=none spice survey inventory payments-api ./build/libs --no-upload --output ./spice-results
$env:SPICE_DOCKER_NETWORK = "none"
spice survey inventory payments-api .\build\libs --no-upload --output .\spice-results
Remove-Item Env:SPICE_DOCKER_NETWORK

The wrapper still pulls the image and checks for a newer wrapper script on your machine before the run. Set SPICE_LABS_CLI_SKIP_PULL=1 as well to skip both.

JVM mode (running without Docker)

With SPICE_LABS_CLI_USE_JVM=1, the wrapper runs the CLI jar with your local Java instead of in Docker. Paths are used as they are, and --features is ignored. Docker mode is the one these docs describe and the one to use when you can. JVM mode needs:

  • Java 21 or later on your PATH.
  • The CLI jar at the path in SPICE_LABS_CLI_JAR. Build it from the spice-labs-cli repository. Plugins are loaded from a plugins/ folder beside the jar.
  • oras on your PATH for image surveys.
  • syft on your PATH to identify OS packages, Go modules and lockfile dependencies. Without it the survey still runs but finds far fewer packages, and prints no warning.

The Docker image includes all of these. On Windows, set SPICE_LABS_JVM_ARGS to a single JVM option, such as -XX:MaxRAMPercentage=75, when you use JVM mode.

VariableDefaultWhat it does
SPICE_LABS_CLI_USE_JVM01 runs the CLI with Java on your machine instead of in Docker.
SPICE_LABS_CLI_JAR/opt/spice-labs-cli/spice-labs-cli.jarThe CLI jar used in JVM mode.

Configuration file

Settings you use on every run can live in a TOML file instead of on the command line. spice reads one file per run.

Where the file is found

PlatformLocation, first match wins
AnyThe file you name with spice --config <file>
macOS and Linux$XDG_CONFIG_HOME/spice/config.toml (by default ~/.config/spice/config.toml), then spice/config.toml in each $XDG_CONFIG_DIRS folder (by default /etc/xdg)
Windows%APPDATA%\spice\config.toml, then %PROGRAMDATA%\spice\config.toml

The first file found is the only one used. Naming a file that does not exist with --config is an error, but finding no file at the default locations just means there is no configuration file. --config belongs to spice itself, so it goes before the subcommand:

spice --config ./ci.toml survey inventory payments-api ./build/libs

Settings

Settings are grouped by the job they describe:

[analysis]
threads = 16
max_records = 100000

[upload]
target_chunk_size = 64

[logging]
level = "debug"
GroupKeys
analysisthreads (default: half your CPU cores), max_records (default: 5000)
uploadtarget_chunk_size (MB), encrypt_only, skip_key, comment, bundle_format_version
logginglevel: error, warn, info, debug or trace (default: info)

A group at the top of the file applies to every command that reads it. To change one command only, write the group under that command’s name:

[analysis]
threads = 16

[survey.inventory.analysis]
threads = 4

The log file cannot be set in the configuration file. Use the --log-file option instead: the wrapper writes the log on your machine, and a path named anywhere else would be written inside the container and lost.

Other paths named in the configuration file are mounted into the container automatically, so they resolve to the same place as on your machine.

One setting, three names

Every setting has the same name in all three places:

FormShapeExample
Configuration keysnake_case in a group[analysis] max_records
Optionkebab-case--max-records
Environment variableSPICE_<GROUP>_<KEY>SPICE_ANALYSIS_MAX_RECORDS

Which value wins

defaults  <  [group]  <  [command.group]  <  environment  <  command line

When one source overrides another, the run logs it, for example analysis.threads = 8 (SPICE_ANALYSIS_THREADS) overrides 16 ([analysis] in ...).

Check what a run will use

spice config explain shows every setting a command would use and where each value came from, without running a survey. For example, with this configuration file at ~/.config/spice/config.toml:

[analysis]
threads = 4

[survey.inventory.analysis]
max_records = 20000

[logging]
level = "debug"

and the log level set from the environment:

SPICE_DOCKER_FLAGS="-e SPICE_LOGGING_LEVEL=warn" spice config explain survey inventory
$env:SPICE_DOCKER_FLAGS = "-e SPICE_LOGGING_LEVEL=warn"
spice config explain survey inventory
Remove-Item Env:SPICE_DOCKER_FLAGS

the output names the source of each value, and logs the override:

# /home/you/.config/spice/config.toml

INFO ⚙️  logging.level = warn (SPICE_LOGGING_LEVEL) overrides debug ([logging] in /home/you/.config/spice/config.toml)
[analysis]
  max_records = 20000    [survey.inventory.analysis] in /home/you/.config/spice/config.toml
  threads     = 4        [analysis] in /home/you/.config/spice/config.toml

[logging]
  level = "warn"    SPICE_LOGGING_LEVEL

A setting you have not set shows default. Without a configuration file, the first line reads # No configuration file; showing defaults and the environment. Add --group=<name> to show one group only.

If a group name is misspelled, or belongs to a plugin you do not have, the run warns and continues: No command reads [anaylsis] — check the spelling, or the plugin may not be installed.