On this page
- Configuration ownership
- Managed settings
- Appliance-owned values
- Network settings
- Backup and upgrade behavior
- Storage settings
- Export and data-governance settings
- Query and cache settings
- Garbage collection
- Demo settings
- Removed and forbidden keys
- Inspect configuration without leaking it
- Partial upload retention in 0.9.7
Ingotron 0.9.7 configuration reference
The installer owns the appliance baseline and the installed CLI reconciles it.
The Admin UI provides the normal path for the small set of reversible settings
available to operators. This document describes the installed appliance at
/opt/ingotron; it is not a guide to the legacy checkout stack or
docker-compose.production.yml.
Configuration ownership
The effective environment is /opt/ingotron/state/env. Its companion
env.meta.json records where values came from and which command owns them.
Permissions are root-only. Do not copy the repository's .env.example over
this file: that example is a readable schema, not an install template.
Every setting belongs to one of four classes:
| Class | Examples | Owner and change method |
|---|---|---|
| Computed address set | APPLIANCE_URL, all five OIDC_*_URL values |
sudo ingotron set-address; never edit separately |
| Generated secret | database passwords, scoped S3 keys, provisioning token | Installer/upgrade reconciliation; rotate only through a documented recovery path |
| Release policy | appliance ingest profile, shared-token denial, same-origin CORS | Signed release; do not override |
| Operator setting | health timeout, time-index cache size | Admin UI review/apply transaction |
Upgrade reconciliation adds new values, renames or removes retired keys, and
does not silently replace a recorded operator value. Use
sudo ingotron upgrade --show-config-changes to review the proposed change set.
Open Admin → Configuration to view the four settings exposed by 0.9.7.
The UI allows changes only to INGOTRON_HEALTH_TIMEOUT and
TIME_INDEX_CACHE_SIZE_MB. Select Review changes, inspect the planned
restart, then select Apply reviewed plan. The transaction validates the
candidate, applies it to the owning service, waits for health, and restores the
previous state if the health check fails. Reload the page after a stale plan or
an interrupted request; do not submit the same change repeatedly while the
service is recovering.
set-address and the TLS commands remain the supported transactions for their
own values. Do not edit state/env or invoke raw Compose to force a change:
the CLI owns the overlay order, project identity, state paths, and recovery
journal. Root operators may use sudo ingotron config show, sudo ingotron config plan, or sudo ingotron config apply for the same narrow settings
boundary when UI access is unavailable.
The full appliance runs on one Linux server. The Admin UI may be opened from any trusted browser, while each robot receives only the small agent. RHEL-family and Fedora hosts with SELinux Enforcing are currently refused by the installer and upgrade path until a packaged Ingotron SELinux policy exists. Never disable SELinux to bypass that refusal.
The appliance reserves numeric GID 10001 for its manager socket and mounted
service files. Installation creates the system group ingotron-secrets at that
GID when it is absent. Installation and manager activation refuse a conflicting
group name or GID, explicit group members, or host accounts whose primary GID is
10001. Existing accounts and groups are not reassigned. Resolve the reported
collision before retrying; do not add human or unrelated service accounts to
this group, because membership grants access to the manager's host-control API.
The numeric container identity remains 10001:10001.
Managed settings
These four settings are visible in Admin → Configuration. Two are reversibly editable; the other two are shown for awareness and are controlled by the signed release or host operator because changing them can have irreversible effects.
| Key | Default | UI state | Valid values / effect |
|---|---|---|---|
ALLOW_UNSCRUBBED |
false |
Read-only | Release/host policy; blocks exports containing raw media when false |
GC_DRY_RUN |
true |
Read-only | Release/host policy; prevents garbage collection deletion while true |
INGOTRON_HEALTH_TIMEOUT |
300 |
Editable | Whole seconds from 60 to 3600; health deadline for managed changes and upgrade/recovery |
TIME_INDEX_CACHE_SIZE_MB |
512 |
Editable | Whole megabytes from 1 to 2048; query time-index cache upper bound |
The UI reads a revision, creates a plan token, and requires that reviewed plan when applying. If the release, revision, or running service set changes first, the plan is rejected and the UI asks you to reload and review again. Changing the cache size recreates the query service; the UI waits for it to return before reporting success.
Appliance-owned values
Public address and OIDC
| Key | Typical value | Meaning |
|---|---|---|
APPLIANCE_URL |
https://10.20.30.40:8003 |
Canonical browser/API origin |
OIDC_ISSUER |
<APPLIANCE_URL>/auth/realms/ingotron |
Bundled realm issuer |
OIDC_JWKS_URL |
Issuer plus /protocol/openid-connect/certs |
Token-verification keys |
OIDC_AUTHORIZATION_URL |
Issuer plus /protocol/openid-connect/auth |
Browser authorization endpoint |
OIDC_TOKEN_URL |
Issuer plus /protocol/openid-connect/token |
Token endpoint |
OIDC_END_SESSION_URL |
Issuer plus /protocol/openid-connect/logout |
Sign-out endpoint |
These six values are one atomic set. Change them only with:
sudo ingotron set-address https://vault.example.com:8003The command also reconciles TLS SANs and service state. KEYCLOAK_REALM
defaults to ingotron, OIDC_AUDIENCE to robot-vault, OIDC_CLIENT_ID to
robot-vault-ui, OIDC_ROLE_CLAIM to roles, and scopes to
openid profile email offline_access. Those bundled-realm identifiers are
release inputs, not a bring-your-own-OIDC interface.
Identity and ingest policy
| Key | 0.9.7 policy | Notes |
|---|---|---|
INGEST_SECURITY_PROFILE |
appliance |
Selects per-robot appliance authentication |
INGEST_SHARED_TOKEN_POLICY |
deny |
Refuses the legacy fleet-wide bearer on a fresh appliance |
INGEST_LEGACY_SHARED_GRACE_UNTIL |
Absent, or adoption time + 30 days | Written only for a legacy adoption |
CORS_ALLOWED_ORIGINS |
Empty | The UI and API are same-origin |
ENABLE_HSTS |
false |
Avoids pinning a browser to an untrusted private CA by default |
The appliance's robot listener uses TLS plus a per-robot bearer credential. It
does not use mTLS. INGEST_AUTH_TOKEN remains a required internal/adoption
value but is not a credential to distribute to new robots.
Generated secrets
The installer generates at least the following, then gives services only the credentials they need:
POSTGRES_PASSWORDand scoped database-role passwords;MINIO_ROOT_USER,MINIO_ROOT_PASSWORD, and scoped S3 secret keys;INGEST_AUTH_TOKENandINGEST_PROVISIONING_TOKEN;- the Keycloak database password and bootstrap-operator password;
- the Ed25519 dataset-signing key; and
- the appliance CA private key and listener private keys.
Keycloak passwords are mounted from root-owned files, not placed in container environment variables. The dataset signing key and CA are identities, not replaceable caches. Back them up and never paste them into diagnostics.
Network settings
| Key | Default | Range/format | Purpose |
|---|---|---|---|
QUERY_BIND_HOST |
0.0.0.0 |
Host IP | Bind address for browser/API HTTPS |
QUERY_HTTPS_PORT |
8003 |
Free TCP port | Published browser/API port |
INGEST_BIND_HOST |
0.0.0.0 |
Host IP | Bind address for robot ingest TLS |
INGEST_GRPC_PORT |
50051 |
Free TCP port | Published robot gRPC port |
Only those two ports are intended appliance endpoints. PostgreSQL, MinIO, Redis, Keycloak's internal listeners, metrics, and evaluator-only consoles stay on the private Compose network.
A public port is part of APPLIANCE_URL; do not change QUERY_HTTPS_PORT
alone. Use set-address, which keeps OIDC redirects and certificates aligned.
If restricting a bind address, make sure browsers and robots still use an
address covered by the certificate.
Backup and upgrade behavior
| Key | Default | Valid values | Meaning |
|---|---|---|---|
INGOTRON_HEALTH_TIMEOUT |
300 |
Integer 60 to 3600 seconds | Persistent upgrade/rollback health deadline |
A command-line upgrade --health-timeout SECONDS takes precedence over this
setting for that run. The release keeps two immutable releases by default. The
CLI keeps the latest three pre-upgrade backups while retaining the backup
needed for previous_version; those retention counts are install metadata,
not public environment overrides in 0.9.7.
Storage settings
| Key | Default | Notes |
|---|---|---|
S3_BUCKET |
robotics-data |
Internal MinIO bucket used by every scoped service identity |
S3_REGION |
us-east-1 |
Region supplied to S3 clients |
MINIO_ROOT_USER |
Generated | Bootstrap owner name; the release Compose file has no fallback |
Changing a bucket, region, or root identity after data exists is a migration, not a cosmetic environment edit. The appliance's supported 0.9.7 storage topology is its bundled MinIO. Do not point individual services at different buckets/endpoints or replace their scoped credentials by hand.
The authoritative Docker volume names are in
/opt/ingotron/state/install.json, not in this environment. That distinction
matters after adoption.
Export and data-governance settings
| Key | Default | Valid values | Effect |
|---|---|---|---|
ALLOW_UNSCRUBBED |
false |
true/false |
false refuses exports containing media recorded as raw; release/host-controlled in 0.9.7 |
QA_MIN_SCORE |
Unset | Finite 0 to 100 | When set, excludes episodes below the latest DEFECT score; unscored episodes also fail |
MCAP_PASSTHROUGH_APPROVED_SHA256 |
Empty | Comma-separated lowercase SHA-256 digests | Exact reviewed whole-source MCAP allowlist |
EXPORTER_MAX_ATTEMPTS |
3 |
Positive integer | Bounds starts before a transient export failure dead-letters |
This release has no bundled PII-scrubbing backend, so it records media with raw
PII state. ALLOW_UNSCRUBBED=true permits exports of that raw media. It does
not mean the data was scrubbed. The 0.9.7 baseline is false; changing this
policy is not a reversible Admin UI operation. Setting it to false affects
export, not ingest or historical retention.
QA_MIN_SCORE uses the displayed 0 to 100 DEFECT scale. It is not a fraction:
80, not 0.8, means eighty. An invalid or non-finite value stops exporter
configuration instead of silently disabling the gate.
The MCAP allowlist cannot waive camera-bearing-source inspection or the raw media gate. Approve exact digests only after independent review; do not use a wildcard or a broad prefix.
Query and cache settings
TIME_INDEX_CACHE_SIZE_MB is managed through Admin → Configuration. Its
default is 512 and the accepted range is 1 to 2048 whole megabytes. Reduce it
on a memory-constrained host at the cost of more index work. Applying a new
value recreates the query service and waits for its health check. This is not
the Keycloak JVM limit; the bundled IdP has its own release-controlled memory
cap.
Garbage collection
| Key | Default | Valid values | Effect |
|---|---|---|---|
GC_DRY_RUN |
true |
true/false |
Logs candidates without deleting when true; release/host-controlled in 0.9.7 |
GC_MIN_AGE_HOURS |
24 |
Non-negative number | Minimum object age before consideration |
GC_DELETE_LIMIT |
2000 |
Positive integer | Maximum deletions per pass |
GC_INTERVAL_SECONDS |
3600 |
Positive integer | Delay between passes where supported by the runner |
Keep dry-run enabled until its output has been reviewed against a tested backup. In 0.9.7 it is visible in the Admin UI but not editable there. Garbage collection relies on the registry's reachability model and cannot repair a missing MinIO backup. After a database restore, post-backup objects may be unreferenced; take extra care before enabling deletion.
Demo settings
The ingotron demo profile accepts these deterministic seeder settings when
they are present in the effective environment:
| Key | Default | Meaning |
|---|---|---|
SEED_SIM_EPISODES |
3 |
Number of generated episodes |
SEED_SIM_DURATION |
15 |
Seconds per episode |
SEED_SIM_SEED |
42 |
Deterministic byte/content seed |
SEED_SIM_BAD_EPISODE |
2 |
Episode intentionally damaged; 0 disables |
These change only newly generated demo content.
Removed and forbidden keys
The 0.9.7 CLI refuses or removes values that would break signed-release or installation identity:
| Key | Replacement |
|---|---|
ROBOT_VAULT_VERSION |
sudo ingotron upgrade --version VERSION |
REGISTRY |
Signed manifest's digest-pinned image references |
COMPOSE_PROJECT_NAME |
Fixed project identity ingotron |
SECRETS_GID |
Fixed appliance secrets group 10001 |
QUERY_PORT |
Renamed to QUERY_HTTPS_PORT during reconciliation |
Do not add these back to state/env. Image mirroring/air-gap operation is not
a supported per-host registry override in this release.
Inspect configuration without leaking it
sudo ingotron status --json and sudo ingotron version --json are the only
0.9.7 commands with machine-readable output. Other commands explicitly refuse
--json rather than emitting prose that automation might misparse.
When diagnosing configuration:
sudo ingotron status --json
sudo ingotron version --json
sudo ingotron tls statusDo not attach state/env, env.meta.json, install.json, rendered Keycloak
configuration, docker inspect, private TLS files, or backups to a ticket
without a deliberate secret review. Redact passwords, tokens, claim material,
private keys, internal hostnames, and customer identifiers.
See Operations for safe change and recovery procedures and Security for the trust model and current limitations.
Partial upload retention in 0.9.7
Durable partial uploads use fixed chunks between 5 MiB and 8 MiB. The server retains an inactive session for seven days and checks for expired sessions every 15 minutes. These are fixed implementation limits, not editable Admin settings. Saved progress is the server-confirmed total at the last resume check, which can include chunks after a missing range.
Migration 026 and the matching new server, toolkit, robot agent, and ingest object-store policy are required. Update both the appliance and robot agent through the signed release to enable durable partial resume.