Skip to content

Configuration

Rod Christiansen edited this page Oct 8, 2026 · 3 revisions

Configuration

Every setting the agent reads, where it can be set, and what it does. The layering is built by SettingsLoader in src/Configuration/SettingsLoader.cs, using the key paths in src/Shared/ReportMateSettingsKeys.cs. The runner and the Managed Reports Runner App share that file, so both read the same keys.

Where settings live

Key Who writes it Purpose
HKLM\SOFTWARE\Policies\ReportMate MDM (CSP / OMA-URI) or Group Policy Managed settings. Highest registry precedence
HKLM\SOFTWARE\ReportMate\Settings The installer, the install command, the app's Prefs tab, local administrators Machine settings
HKLM\SOFTWARE\ReportMate\Secrets The runner, the installer, the app Credentials (Passphrase, ApiKey). ACL is SYSTEM and Administrators full control, nothing inherited, nobody else
HKLM\SOFTWARE\Config\ReportMate Older deployments Deprecated. Still read as a fallback
Values directly under HKLM\SOFTWARE\ReportMate Older deployments Deprecated as a settings location. Still read as a fallback. Also holds run state (LastRunTime, InstallTime, Version)

All keys are read in the 64-bit registry view.

Precedence

Highest first. A value from a higher source wins.

  1. --api-url and --device-id on the command line, for that run only.
  2. The protected credential store, HKLM\SOFTWARE\ReportMate\Secrets. It only ever holds what policy or Settings supplied (or a legacy value when neither did), so it sits above them.
  3. Policy: HKLM\SOFTWARE\Policies\ReportMate.
  4. Machine settings: HKLM\SOFTWARE\ReportMate\Settings.
  5. Legacy registry: HKLM\SOFTWARE\Config\ReportMate, then the top-level values of HKLM\SOFTWARE\ReportMate.
  6. Environment variables prefixed REPORTMATE_.
  7. C:\ProgramData\ManagedReports\appsettings.yaml, only when it is trusted (see below).
  8. Built-in defaults compiled into the binary.

Run any command with -v to have the agent print the source order (the credential store is not listed in that printout) and the resolved ApiUrl, DeviceId and DebugLogging.

Credentials

Passphrase and ApiKey are credentials. On every run, before settings are read, the runner moves any readable copy into the protected store:

  • A credential found under Policies\ReportMate or ReportMate\Settings is written to the store, and the readable copy is blanked (set to an empty string) rather than deleted, so a policy setting still shows as managed and a lower key cannot take it over. Of those two keys, the higher one that holds the name at all decides.
  • A credential found in a legacy key is stored only when the store is empty and neither managed key holds the name (Config\ReportMate before the top-level key). Every legacy copy is then deleted. Only these two values are ever deleted from a legacy key.
  • Nothing is blanked or deleted until the store reads back exactly the value written.

Moving a credential needs an elevated process. The scheduled tasks run as SYSTEM, so this happens on the first scheduled run after a credential is set. A process that is not elevated cannot read the store and treats the credential as unset. Credential values are never logged or displayed; the log names the setting and the key only.

The legacy YAML file

C:\ProgramData\ManagedReports\appsettings.yaml is read only when no non-administrator can change it. The runner trusts the file when SYSTEM, Administrators or TrustedInstaller own it, no other account holds a write, append, change-permissions or take-ownership right on it, and neither the file nor its folder is a link. Otherwise the file is skipped and the log records why, for example Ignoring C:\ProgramData\ManagedReports\appsettings.yaml: S-1-5-32-545 can change it.

The installer locks C:\ProgramData\ManagedReports down to SYSTEM and Administrators full control and Users read, owned by Administrators, so the file it deploys is trusted.

appsettings.json next to the binary is not part of the chain.

Deprecated keys

HKLM\SOFTWARE\Config\ReportMate and the values directly under HKLM\SOFTWARE\ReportMate are deprecated. On install, upgrade or the install command, each setting found there that ReportMate\Settings does not already hold is copied into Settings under its current name; the legacy keys are not otherwise changed. Run state (LastRunTime, InstallTime, Version) and credentials are not copied. While a legacy key still supplies a setting, every run logs a warning naming it.

Settings

The registry value name is what you write under Policies\ReportMate or ReportMate\Settings. Every value name maps to the config key ReportMate:<ValueName>, so any setting the runner reads can be set by policy. LogLevel is the one exception and maps to Logging:LogLevel:Default.

Boolean values accept a REG_DWORD 0 or 1 as well as the strings true and false. A REG_MULTI_SZ value is joined with commas.

Registry value Config key Default Effect
ApiUrl ReportMate:ApiUrl (empty) Base URL of the ReportMate API. Required: with no value the HTTP client has no base address and every request fails
ServerUrl ReportMate:ApiUrl Older spelling of ApiUrl, accepted in any key. Within one key, ApiUrl wins
Passphrase ReportMate:Passphrase (empty) Credential. Sent as the X-Client-Passphrase header and in the payload metadata
ApiKey ReportMate:ApiKey (empty) Credential. Sent as the X-API-Key header
DeviceId ReportMate:DeviceId (auto) Overrides the derived device id. Normally left unset
CollectionIntervalSeconds ReportMate:CollectionIntervalSeconds 3600 Recorded only. The scheduled tasks, not this value, decide when collection happens
CollectionInterval ReportMate:CollectionIntervalSeconds Older spelling of CollectionIntervalSeconds
MaxDataAgeMinutes ReportMate:MaxDataAgeMinutes 30 A full run without --force is skipped when the last successful run is more recent than this
ApiTimeoutSeconds ReportMate:ApiTimeoutSeconds 300 Timeout for each API request, in seconds
MaxRetryAttempts ReportMate:MaxRetryAttempts 3 Attempts per transmission before giving up
OsQueryPath ReportMate:OsQueryPath C:\Program Files\osquery\osqueryi.exe Path to the osquery shell
CompressPayload ReportMate:CompressPayload true Gzip the request body. Set false to send uncompressed. The client also drops to uncompressed for the rest of a run when the server answers a compressed body with HTTP 400
DebugLogging ReportMate:DebugLogging false Forces the log to Debug level regardless of --verbose
LogLevel Logging:LogLevel:Default Information Written by the installer. The file log level follows --verbose and DebugLogging
UserAgent ReportMate:UserAgent ReportMate/1.0 User-Agent header, applied when the HTTP client does not already carry one
LogDirectory ReportMate:LogDirectory C:\ProgramData\ManagedReports\logs Where the rolling log file is written. Per-transmission payload copies always go to C:\ProgramData\ManagedReports\logs
Development:Enabled false Adds a console sink and suppresses the Windows Event Log sink. Set through YAML or REPORTMATE_Development__Enabled

Run state on the top-level key:

Value Written by Meaning
LastRunTime The runner, after each successful full run Read back by the MaxDataAgeMinutes check
InstallTime The install command When configuration was last installed
Version The install command Client version at that time

Values the runner accepts but does not act on

These appear in the app's Prefs tab, the shipped YAML or the installer, but no code in the runner reads them today:

Value Note
CimianIntegrationEnabled Written by the install command and the app. The installs module collects Cimian data whether or not it is set
StorageMode Stored by the app. The hardware module takes its storage mode from --storage-mode only, default auto
SkipCertificateValidation Stored by the app. Certificate validation is not changed
ProxyUrl, and the YAML ReportMate:Proxy section No proxy is configured on the HTTP client. It uses the system default proxy behaviour of .NET
OsQueryConfigPath Written by the installer. Query packs are always read from C:\ProgramData\ManagedReports\osquery
DataDirectory, CacheDirectory, ConfigDirectory In the shipped YAML. The cache path is fixed at C:\ProgramData\ManagedReports\cache

Environment variables

Two forms are read:

  • REPORTMATE_ followed by a config path with __ for : names that key outright, for example REPORTMATE_ReportMate__ApiUrl or REPORTMATE_Development__Enabled.
  • REPORTMATE_ followed by a setting name with no __ names a ReportMate: setting, matched without case or underscores. REPORTMATE_API_KEY sets ReportMate:ApiKey; REPORTMATE_MAXRETRYATTEMPTS sets ReportMate:MaxRetryAttempts.

When ReportMate:ApiUrl is still empty, the bare variables REPORTMATE_API_URL, API_URL and SERVER_URL are tried in that order.

Environment variables rank below every registry key, so they only take effect where no registry value is set.

Installer-time variables

The MSI and NUPKG post-install scripts read these from the process environment, or from a .env file in C:\Program Files\ReportMate\ or beside the package scripts. They are only consulted during installation.

Variable Effect
REPORTMATE_API_URL, or PROD_API_URL Written to ReportMate\Settings as ApiUrl when no key already sets it
REPORTMATE_PASSPHRASE, or PROD_PASSPHRASE Stored in the protected store as Passphrase when nothing already sets it
REPORTMATE_AUTO_CONFIGURE Auto-configuration runs unless this is false, 0, no or off

build.ps1 copies a .env file from the repository root into the package build directories when one exists, so a package can carry these values. Anything in a package is readable by whoever has the package; treat a passphrase baked in this way accordingly.

The installer also writes these defaults to ReportMate\Settings, only where Settings has no value, so an upgrade never resets what an administrator or the app set: CollectionIntervalSeconds 3600, LogLevel Information, OsQueryPath C:\Program Files\osquery\osqueryi.exe, OsQueryConfigPath C:\ProgramData\ManagedReports\osquery.

Setting it by MDM

Write managed values to HKLM\SOFTWARE\Policies\ReportMate. A value there wins over Settings, the app locks its field and shows it as managed by policy, and neither the app nor the install command overwrites it.

New-Item -Path 'HKLM:\SOFTWARE\Policies\ReportMate' -Force | Out-Null
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\ReportMate' -Name 'ApiUrl' -Value 'https://reportmate.example.com'
Set-ItemProperty -Path 'HKLM:\SOFTWARE\Policies\ReportMate' -Name 'Passphrase' -Value '<passphrase>'

The next elevated run moves the passphrase into the protected store and blanks the readable copy under Policies. Leave the blank value in place: it keeps the setting marked as policy-managed.

Setting it locally

For a single machine, use the app's Prefs tab, or write to the machine settings key from an elevated shell:

New-Item -Path 'HKLM:\SOFTWARE\ReportMate\Settings' -Force | Out-Null
Set-ItemProperty -Path 'HKLM:\SOFTWARE\ReportMate\Settings' -Name 'ApiUrl' -Value 'https://reportmate.example.com'

Confirm what the agent resolved:

managedreportsrunner.exe info -v

The install command

managedreportsrunner.exe install --api-url <url> must run elevated. It copies legacy settings into Settings, moves credentials into the protected store, then writes ApiUrl, DeviceId (the configured one or a generated one), CollectionIntervalSeconds, LogLevel, OsQueryPath and CimianIntegrationEnabled to Settings, and ApiKey (when set) to the protected store, skipping any value policy already sets. InstallTime and Version go to the top-level key.

--api-url takes effect because the runner reads it ahead of the command parser. --api-key and --device-id on install are accepted by the parser; --device-id is honoured the same way as --api-url, while --api-key is not read, so set ApiKey through a registry key instead.

Clone this wiki locally