50 lines
3.9 KiB
JSON
50 lines
3.9 KiB
JSON
{
|
|
"_logging": "Host-021: Serilog is the sole logger provider (Program.cs calls builder.Host.UseSerilog()), so the standard Microsoft 'Logging:LogLevel' block has no effect and was removed. The minimum level is set via 'ScadaBridge:Logging:MinimumLevel' (bound to LoggingOptions per Host-011); sinks are defined under the 'Serilog' section below and applied via ReadFrom.Configuration (Host-014). See LoggerConfigurationFactory + Component-Host.md REQ-HOST-8.",
|
|
"ScadaBridge": {
|
|
"Security": {
|
|
"Auth": {
|
|
"_comment": "DisableLogin bypasses the login form and auto-authenticates every request as User with all roles. DEV/TEST ONLY — no environment guard; a startup warning is the only protection. Never enable in production.",
|
|
"DisableLogin": false,
|
|
"User": "multi-role"
|
|
}
|
|
}
|
|
},
|
|
"Secrets": {
|
|
"_sqlitePath": "Deliberately unset. ZB.MOM.WW.Secrets 0.6.2 validates Secrets:SqlitePath at startup — it must be ABSOLUTE and must NOT sit inside the content root, because a path inside the deployment directory is destroyed by an ordinary upgrade (this is what wiped the MxGateway API-key store on 2026-08-09). The former value here ('scadabridge-secrets.db') was relative and would now fail the boot. Leaving it unset gives dev the absolute per-user LocalApplicationData default; every real deployment supplies its own absolute path via its environment overlay.",
|
|
"MasterKey": { "Source": "Environment", "EnvVarName": "ZB_SECRETS_MASTER_KEY" },
|
|
"RunMigrationsOnStartup": true,
|
|
"ResolveCacheTtl": "00:00:30",
|
|
"Store": {
|
|
"_comment": "CENTRAL ONLY (a Site always ignores this and keeps its local SQLite store, permanently - Task 11 retired secrets replication, so there is no decorator left for a site to be given). 'Sqlite' (default) is per-node: on a clustered central, each node's secrets can silently drift the moment anyone edits one on only a single node, which then ships an inconsistent secret set to sites on artifact deploy - StartupValidator warns on a >=2-seed central left on Sqlite. 'SqlServer' points BOTH central nodes at ONE shared SQL-Server database directly (Secrets:SqlServer:ConnectionString, fail-closed on a blank or ${secret:} value), so the pair can never diverge.",
|
|
"Provider": "Sqlite"
|
|
},
|
|
"_replication": "Secrets replication (the gRPC hub, and the SQL-Server ReplicatingSecretStore mode that preceded it) is retired - Task 11. Secrets:Replication:Enabled=true is now a hard startup failure on either role; sites receive secrets exclusively via Deploy Artifacts, and Secrets:Store:Provider=SqlServer (above) is how a clustered central shares one secret set.",
|
|
"SqlServer": {
|
|
"ConnectionString": "",
|
|
"SchemaName": "zbsecrets",
|
|
"_comment": "Read ONLY when Secrets:Store:Provider=SqlServer: points BOTH central nodes at ONE shared SQL-Server secret store so the pair cannot diverge. Must be a LITERAL or environment value (Secrets__SqlServer__ConnectionString), never a ${secret:} reference - the pre-host expander needs this store to resolve references, so the reference could never resolve (bootstrap circularity; registration rejects it). SITES leave it empty - sites talk to central, never to central's database. Every node that handles deployed secrets must still carry the SAME ZB_SECRETS_MASTER_KEY - only ciphertext crosses the wire, so a node with a different KEK fails closed on resolve with a kek_id mismatch that reads like corruption but is a deployment error."
|
|
}
|
|
},
|
|
"Serilog": {
|
|
"Using": [
|
|
"Serilog.Sinks.Console",
|
|
"Serilog.Sinks.File"
|
|
],
|
|
"WriteTo": [
|
|
{
|
|
"Name": "Console",
|
|
"Args": {
|
|
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] [{NodeRole}/{NodeHostname}] {Message:lj}{NewLine}{Exception}"
|
|
}
|
|
},
|
|
{
|
|
"Name": "File",
|
|
"Args": {
|
|
"path": "logs/scadabridge-.log",
|
|
"rollingInterval": "Day"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|