Skip to content

Configuration

A self-hosted inSCADA is configured through environment variables. Two things are worth knowing before you edit anything: there is a master key the application will not start without, and there is a right way to hand secrets to the process.

This is the one secret you supply by hand. Left blank, the application does not start.

Every other key — the interface session key, the attribute key that reads the encrypted columns in the database, the cluster key, the code-integrity key and the electronic-signature key — is generated on first start and kept encrypted. You neither choose nor record those. The encrypted bundle lives in Redis, with a copy at ${ins.data.path}/secrets.json, and what opens it is derived from INS_MASTER_KEY (PBKDF2).

The key is chosen once per installation; there is no rotation path.

Every setting whose value is a secret is given to the process as an environment variable — never as a -D on the java command line, and never as a program argument.

This is not a matter of style: a process’s arguments are public. Any account with a login on the machine can read the command line of a running process; no privilege is required. An environment variable is not like that — only the process’s owner can read it.

Terminal window
# WRONG — every user on this box can read the master key
java -Dins.master.key=... -jar inscada.jar
# RIGHT
export INS_MASTER_KEY=...
java -jar inscada.jar

The application says so at startup: for each sensitive setting that arrived on the command line it writes one warning line naming the setting, never the value. It does not refuse to start, because taking a plant down over a value that is correct would be the wrong trade. Check the startup log after a deployment; a clean start prints none of these lines.

The same applies to whatever wraps the process. A systemd unit reads secrets with EnvironmentFile= — the file readable only by the service account — rather than putting them in ExecStart=; a container uses --env-file or a secret mount. If you run it under a Windows service wrapper, load the environment the same way: from a permission-restricted environment file, not the command line.

Anything whose default is blank is something you are expected to supply.

VariableDefaultDescription
INS_MASTER_KEY—Required. See above
DB_URLjdbc:postgresql://localhost:5432/inscadaPostgreSQL address
DB_USERNAME · DB_PASSWORDblankDatabase credentials
REDIS_HOST · REDIS_PORTlocalhost · 6379Redis
INFLUX_URL · INFLUX_DBhttp://localhost:8086 · inscadaThe historian
SSL_KEYSTORE · SSL_KEYSTORE_PASSWORDblankTLS keystore
APP_TRUSTSTORE · APP_TRUSTSTORE_PASSWORDblankTruststore for outbound connections
LOG_FILE./logs/inscada.logThe log file
SettingDefaultWhat is in it
ins.data.path./dataThe encrypted secret bundle’s copy, and working data
ins.filesystem.path./fsUploaded files

Both are relative to the working directory. When you back up the installation directory, make sure the two are covered.

Everything an installation keeps in Redis — the secret bundle, the cluster’s leadership record, live values, sessions — sits in a single logical database, 0 when unset. A second installation pointed at the same Redis, a test instance beside production or a second plant, must use a different database number; otherwise the two share one space.

PortWhat
8082The application and the API
8083The sandbox

The sandbox is a separate origin by design: Custom HTML pages and animation scripts run in an isolated frame, and that separation is the isolation boundary.

Because cookies are host-only, the sandbox origin must be on the same host as the application. On different hosts the cookies never reach the frame, and the fix is to bring the sandbox back to the same host — usually with a proxy on that machine fronting :8083 — rather than widening the cookie’s domain.

Four settings decide the topology. Two are bind settings — where the server listens — and two are advertised — the origin the client is told to use. They are separate on purpose: behind a proxy, the port the server binds and the origin the client sees legitimately differ.

SettingLayerDefaultMeaning
INS_SANDBOX_ADDRESSbindblank → all interfacesThe address the sandbox listens on. Set 127.0.0.1 when a proxy on the same machine owns the public port
server.sandbox.portbind8083The sandbox port
INS_SANDBOX_URLadvertisedhttps://localhost:8083The full sandbox origin the client sees
INS_APP_URLadvertisedhttps://localhost:8082The backend / API origin

The advertised origins form an exact-match allowlist with no wildcard. A wrong value breaks only your own installation — a frame will not render, or an origin will not be trusted.

TopologyINS_SANDBOX_ADDRESSAdvertised sandboxAdvertised app
Single box, no proxyblankhttps://<host>:8083https://<host>:8082
Proxy on the same machine127.0.0.1The proxy’s public originThe backend origin
Separate-machine DMZthe internal interface’s addressThe public originThe DMZ origin

With a proxy on the same machine, bind the public port in the proxy to the machine’s real address and forward it to 127.0.0.1:8083; a bare :8083 block binds all interfaces and collides with the loopback listener (“address already in use”).

  • /actuator/health — the proxy indicator reports the intended mode and nothing is DOWN. On a clustered node, health-check a load balancer against /actuator/health/readiness rather than raw /actuator/health.
  • The startup log carries no proxy warning and no line reporting that a secret arrived on the command line.
  • Behind a reverse proxy, 8082 and 8083 are not reachable from outside it, and the proxy sends X-Forwarded-Proto: https.
  • A Custom HTML page or an animation opens in the browser — this exercises the sandbox origin and the cookie flow end to end.
  • INS_MASTER_KEY has been recorded somewhere outside the product.