Skip to content
Talk to our solutions team

Configuration

rules.svc reads one bootstrap YAML file at start, overlays it with command-line flags, then merges the result over the service node it resolves from the config plane. This page enumerates every key the binary actually reads. Keys not listed here are not read by this service.

For what the service does with that configuration once it is up, see Service. For diagnosing a boot that produced no output, see Troubleshooting.

SourceSetsPrecedence
Config plane (config.url / config.path)The resolved service node fetched at bootLowest — the bootstrap map is merged over it
Bootstrap YAML fileEvery key on this pageBeats the config plane
Command-line flagsThe fourteen flags belowHighest — a non-empty flag overwrites the YAML value
Tenant config, per tenantmeta.url, meta.isexternalRead from the tenant record, not the service section

The bootstrap file defaults to .rules.yaml in the working directory. Change it with -f.

Terminal window
rules.svc -f /etc/kis/rules.yaml

An empty flag falls back to the YAML value; a non-empty flag is written back into the bootstrap map and wins. At boot the resolved config-plane node is fetched first and the bootstrap map is merged on top of it, so a key present in the bootstrap file always beats the same key published by the config plane. That includes port, which is re-read from the merged map immediately before the listener is created.

These fourteen persistent flags and the version subcommand are everything the service declares. The command framework adds its own help and completion commands on top.

FlagTypeDefaultEffect
-f, --configstring.rules.yamlBootstrap YAML file path
-p, --portstringnoneHTTP listen port
--sidstringnoneService instance id
--datacenterstringnoneDatacenter label
--clusterstringnoneCluster label
--config_urlstringnoneConfig server URL
--config_apikeystringnoneConfig server API key. Boot fails with error: either config.apikey or svccert should be present when config.url is set and neither is
--servicediscovery_urlstringnoneService registry URL
--servicediscovery_apikeystringnoneService registry API key. Boot fails with error: either servicediscovery_apikey or svccert should be present when servicediscovery_url is set and neither is
--svccertstringnoneService certificate path
--svckeystringnoneService private key path
--rootcacertstringnoneRoot CA certificate path
--jwt_public_keystringnonePublic key for verifying tenant tokens
--zerotruststringnone — resolves to truetrue (case-insensitive) serves over TLS; any other non-empty value is false, including yes and 1

There is no --host, no --log-level and no --jwt_private_key flag — those are configuration keys only. rules.svc version prints the service name, version, commit hash, build timestamp and the build’s age. The build number is compiled in but never printed.

KeyTypeDefaultEffect
portstringnone — requiredTCP port the HTTP server binds. Boot aborts with invalid/empty port provided when neither the flag nor this key is set.
hoststring"" (all interfaces)Bind address, joined as host:port.
reuseportbooltrueBind with SO_REUSEPORT so several instances share the port. Set false for a plain listener.
KeyTypeDefaultEffect
zerotrustbooltrueWhen true the server is served over TLS with the configured service certificate. When false the certificate is still loaded but TLS resolution returns nil and the server listens in plain HTTP.
svccertstring (path)""Service certificate, PEM.
svckeystring (path)""Service private key, PEM.
rootcacertstring (path)""Root CA used to validate peers.
rootcakeystring (path)""Root CA key, used by certificate auto-renewal. No flag.
insecureskipverifyboolfalseDisables peer certificate verification.
auto_renew_certificatesbooltrueEnables automatic certificate renewal.
jwt_public_keystring (path)""Public key for verifying tenant tokens on /rule.
jwt_private_keystring (path)""Private key for signing tokens. Configuration only — this binary registers no flag for it.
KeyTypeDefaultEffect
config.urlstring (URL)""Remote config server. Wins over config.path when both are set; config.path is then logged as ignored.
config.pathstring (path)""Local directory of config documents.
config.apikeystring""API key for the remote config server.
config.cachestring (path)""Warm-cache file holding the last-known-good config, read when the remote is down. Remote mode only.
boot.retry_windowduration string or int seconds90sHow long boot keeps retrying the service-discovery and config clients before giving up. Retries back off from 1s to a 10s ceiling. Raise it when the config plane starts after this service.

With neither config.url nor config.path set, the bootstrap file itself is the config source. A config client that cannot be built inside the retry window fails boot with config-client-init and exit 1.

Rule definitions reach the service only from the platform metadata plane. There is no local rules directory, no import command and no admin endpoint — see Service for the delivery path and document shape.

KeyTypeDefaultEffect
meta.urlstring (URL)""required for rule loadingMetadata server. Rule loading reads it from the tenant’s config section; the same key in the service section only decides whether a chassis-level metadata client is registered. Without the tenant-level value that tenant has no rule source.
meta.isexternalboolfalseTenant-level flag telling the metadata client the server sits outside the trust boundary.
api.keystring""API key presented when initialising every per-tenant metadata client. The URL is per tenant; this key is global.
meta.apikeystring""API key for the chassis-registered metadata client, separate from the per-tenant clients above.
meta.dirstring (path)""Local metadata mirror, used only when meta.url is empty.
KeyTypeDefaultEffect
timeouts.readint seconds or duration string15sReadTimeout on the HTTP server. An integer is read first; only if absent is the string parsed as a duration. A parse failure logs and keeps the default.
timeouts.writeint seconds or duration string15sWriteTimeout. This is the only unconditional ceiling on a synchronous rule execution.
timeouts.readheaderint seconds or duration string5sReadHeaderTimeout.
timeouts.defaultcontexttimeoutduration string1sGlobal fallback context timeout registered with the timeout checker.
timeouts.serviceslist of mapsemptyPer-service timeout table. Only the entry whose name equals rules is applied; when no entry matches, previously loaded service timeouts are cleared. Loaded at boot and on every tenant refresh.
timeouts.services[].defaultcontexttimeoutduration stringnoneDefault deadline for the matched service entry.
timeouts.services[].timeouts.enabledbooltrueEnables the matched service entry.
timeouts.services[].pathconfig[].exprstring (regexp)noneURL path pattern the entry applies to. Invalid patterns are logged and skipped.
timeouts.services[].pathconfig[].durationduration stringnoneTimeout for paths matching expr.
timeouts.services[].pathconfig[].enabledbooltrueWhen false the matched path gets no timeout.
KeyTypeDefaultEffect
loadtenantslist of stringsemptyTenants whose config is fetched at boot so it is resident before the first request. Failures log warm tenant on start failed and boot continues.

Entries must be full four-part customer:product:env:tenant keys. The refresh dispatcher requires exactly four non-empty colon-separated parts; a short or malformed key logs a warning and returns, so that tenant’s rules never load while the service still reports healthy and ready.

KeyTypeDefaultEffect
sidstring<hostname>-rules-<port>Service instance id: log tag, registry id, dependency-container key suffix.
instancestringvalue of sidConfig-resolution instance leaf.
datacenterstringdefaultDeployment identity tag; feeds log fields, service-discovery scoping and request context.
clusterstringdefaultDeployment identity tag.
labelsmap of string to stringnoneCohort labels used for config matching. Legacy alias tags; labels wins when both are present.
KeyTypeDefaultEffect
servicediscovery_urlstring (URL)""Registry to register with. When empty a dummy client is used and the registration log line is suppressed.
servicediscovery_apikeystring""Registry API key.
KeyTypeDefaultEffect
vault.urlstring (URL)""A vault client is initialised and registered only when this is non-empty. Leave empty when the deployment has no Vault.
vault.apikeystring""API key for the remote vault client.
vault.filestring (path)""Local vault file, used only when vault.url is empty.
KeyTypeDefaultEffect
log.levelstringerrortrace, debug, info, warn, error, fatal, panic or disabled. An unparseable value leaves the level unchanged.
realtimedebugboolfalseWhen true, a request carrying the X-Debug-Log header or the _debug_log_ query parameter is logged at debug level for that request only. Read per request from the resolved config, so it takes effect without a restart.
KeyTypeDefaultEffect
routinepool.sizeint100Worker pool size. The listener loop, the per-tenant metadata monitors and the config monitors all occupy pool slots.
routinepool.queueint100Pool queue depth.
routinepool.spawnint50Pool spawn threshold.
KeyTypeReality
defaultauthorizationactionboolParsed at boot into a package variable that nothing else in the binary reads. It is not an authorization switch.
vault.url (service copy)stringAlso copied into a package variable nothing reads. The key still has its real chassis effect above — deciding whether a vault client is created.

None of the engine’s execution limits are configurable — there is no flag and no configuration key for any of them. The values below are fixed for every deployment.

LimitValueConfigurableEffect
Max cycles5000NoThe engine re-evaluates all rule conditions in a loop; each cycle where at least one rule is runnable increments a counter. Exceeding the cap aborts the execution.
Rule set version1.0.0NoEvery knowledge base is keyed name plus version. The service always loads and executes at the default version.
Abort on failed rule evaluationtrueNoAny error while evaluating a rule’s when or executing its then aborts the whole execution instead of skipping the rule.
Plugin setutility built-ins plus the document pluginNoutil, num, strings, time, math, map and array are bound in every execution. The document plugin is registered as well, so bbox is bound in any execution whose request carries document input.

The service binds one port and registers exactly three routes: POST /rule, GET /health and GET /ready. Both probes are registered directly on the router and short-circuit ahead of the tenant middleware, so they need no headers and no token.

ProbeSuccessFailureBody
GET /ready200500ready:true / ready:false, plain text
GET /health200500JSON with healthy, dependencies, memstats and version

The memstats block reports Alloc, HeapAlloc, HeapSys, HeapIdle, HeapInUse, TotalAlloc and Sys in MiB, plus NumGC as a count. It is the only built-in memory observability for this block. dependencies is always {} — this service registers none. version is always the empty string: the binary never sets the value the probe reports, so do not key a deployment check on it.

{
"healthy": true,
"dependencies": {},
"memstats": { "Alloc": 12, "HeapAlloc": 12, "HeapSys": 27, "HeapIdle": 12, "HeapInUse": 14, "TotalAlloc": 41, "Sys": 39, "NumGC": 6 },
"version": ""
}

SIGINT or SIGTERM starts shutdown. The listener is closed, then every per-tenant metadata monitor is stopped.

StepBehaviour
SignalSIGINT or SIGTERM
HTTPThe listener is closed
MonitorsEvery per-tenant metadata monitor is stopped, then each monitor’s done channel is signalled

Every key below is read by the binary. The module ships no example configuration file.

port: "8443"
host: ""
log:
level: info
svccert: /etc/certs/service.crt
svckey: /etc/certs/service.key
rootcacert: /etc/certs/rootca.crt
zerotrust: true
config:
url: https://config.internal
apikey: <secret>
api:
key: <metadata-api-key>
loadtenants:
- acme:erp:prod:eu1
timeouts:
read: 15s
write: 60s
readheader: 5s
routinepool:
size: 100
queue: 100
spawn: 50
  • Service — boot sequence, rule delivery and the request path
  • Troubleshooting — what each failure looks like and how to clear it
  • Errors — the full error table and response shapes
  • Rules — what compiles and runs inside a rule body
  • CLI — running rules locally without the service