docs(secrets): document the plain-IConfigurationRoot reload gap and OtOpcUa's redundant starter (scadaproj#49)
The reload gap for a plain IConfigurationRoot is documented rather than fixed: closing it would mean inserting a provider into ConfigurationRoot's internal list. No family host is exposed (plain roots are built with reloadOnChange: false; the rest pass a ConfigurationManager). clustered-secrets.md notes that AddZbSecretsAkkaReplication now starts the actor itself, so OtOpcUa's SecretReplicationStarter becomes redundant once it adopts 0.6.6. Claude-Session: https://claude.ai/code/session_01GT67AEHd2Acv1YPwGfXEoV
This commit is contained in:
@@ -105,6 +105,18 @@ keeps its startup value until restart — editing it, or rotating the secret, ta
|
||||
start. A plain `ConfigurationBuilder().Build()` root gets the values re-applied after each reload,
|
||||
which is weaker; build such a root without `reloadOnChange`.
|
||||
|
||||
*Known gap, not fixed (scadaproj#49):* a plain `IConfigurationRoot` has a fixed provider list, so
|
||||
the overlay cannot be added to it; the library writes the values into its providers and re-applies
|
||||
them from the root's reload token. Direct `IConfiguration` reads see the pinned value after a reload,
|
||||
but an `IOptionsMonitor` bound to that root can rebind from the placeholder first — reload callbacks
|
||||
run in an order the library does not control (the token's callbacks run last-registered-first, and
|
||||
the expander registers early). Inserting a provider into a built root would mean mutating
|
||||
`ConfigurationRoot`'s internal list, which this library deliberately does not do. Nobody in the
|
||||
family is exposed today (ScadaBridge and the ignitionoee router build their plain root with
|
||||
`reloadOnChange: false`; the other hosts pass a `ConfigurationManager`). If you must reload a plain
|
||||
root, expand into a `ConfigurationManager` instead, or re-read the key per use rather than through
|
||||
`IOptionsMonitor`.
|
||||
|
||||
The master key is 32 bytes, provided base64 in `ZB_SECRETS_MASTER_KEY` (Environment source).
|
||||
A missing/invalid key fails closed at startup (`MasterKeyUnavailableException`).
|
||||
|
||||
|
||||
@@ -154,6 +154,11 @@ Optional but recommended: without it the protocol still round-trips under Akka's
|
||||
serializer, but the serializer carrying secret ciphertext becomes an inherited default rather than
|
||||
a deliberate choice.
|
||||
|
||||
Since `0.6.6` `AddZbSecretsAkkaReplication` starts the replication actor itself once the host has
|
||||
started (scadaproj#33), so a node that only expands `${secret:}` references pre-host still
|
||||
replicates. **OtOpcUa's own `SecretReplicationStarter` is then redundant** — it resolves the same
|
||||
actor, so keeping it is harmless; drop it when OtOpcUa adopts `0.6.6` (scadaproj#49).
|
||||
|
||||
### Securing the transport
|
||||
|
||||
Rows on the wire are ciphertext and the KEK never travels, so a passive eavesdropper learns
|
||||
|
||||
Reference in New Issue
Block a user