fix(security): env: credential references follow the per-instance rule (#849)
env:<PREFIX><INSTANCE>_... is the per-instance convention for every prefix of a driver's scope (OTOPCUA_GALAXY_, GALAXY_MXGW_, OTOPCUA_OPCUACLIENT_, OTOPCUA_HEIDENHAIN_), INSTANCE = a driver id or name upper-cased with every other character as '_'. A variable whose part after the prefix equals or starts with (at a '_' boundary) ANOTHER same-type instance's id or name is refused with CredentialReferenceOtherInstance at save, deploy, Test Connect and browse - the same DriverCredentialPolicy.DescribeOtherInstanceProblems the secret: rule uses (now over CollectInstanceReferences / ReferenceNames). Another-instance matches win over the owner's, as for secrets. Shared variables that name no instance (GALAXY_MXGW_API_KEY) keep working. HasInstanceSegments now also gates on env:, so an env:-only browse needs the ConfigDb (fail-closed without it). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -26,7 +26,7 @@ namespace ZB.MOM.WW.OtOpcUa.AdminUI.Browsing;
|
||||
/// <param name="authenticationStateProvider">Supplies the calling circuit's user.</param>
|
||||
/// <param name="dbFactory">
|
||||
/// The config DB, for the cross-instance credential rule (lmxopcua#835). Null (test graphs) ⇒ a config carrying an
|
||||
/// in-scope <c>secret:</c> reference cannot be checked and is refused (fail-closed).
|
||||
/// in-scope <c>secret:</c>/<c>env:</c> reference cannot be checked and is refused (fail-closed).
|
||||
/// </param>
|
||||
/// <param name="audit">The credential-use audit sink (#835 review I-1); null ⇒ the structured log line only.</param>
|
||||
public sealed class BrowserSessionService(
|
||||
@@ -73,7 +73,7 @@ public sealed class BrowserSessionService(
|
||||
if (DriverCredentialPolicy.HasInstanceSegments(driverType, configJson))
|
||||
{
|
||||
if (dbFactory is null)
|
||||
return new(false, "Browse refused: the driver-instance list needed to check this config's secret: "
|
||||
return new(false, "Browse refused: the driver-instance list needed to check this config's secret:/env: "
|
||||
+ "references is unavailable (lmxopcua#835, fail-closed).", Guid.Empty);
|
||||
try
|
||||
{
|
||||
@@ -88,7 +88,7 @@ public sealed class BrowserSessionService(
|
||||
// Review L-2: a ConfigDb fault must not become a circuit error — refuse (fail-closed) with a message.
|
||||
logger.LogWarning(ex, "Browse credential check failed for driverType={DriverType}", driverType);
|
||||
return new(false, "Browse refused: the driver-instance list could not be read to check this config's "
|
||||
+ "secret: references (lmxopcua#835, fail-closed). Try again.", Guid.Empty);
|
||||
+ "secret:/env: references (lmxopcua#835/#849, fail-closed). Try again.", Guid.Empty);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -611,9 +611,9 @@ public sealed class AdminOperationsActor : ReceiveActor
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
try
|
||||
{
|
||||
// lmxopcua#835: a reference naming ANOTHER driver instance's secret (secret:galaxy/<other>/…) is refused
|
||||
// lmxopcua#835/#849: a reference naming ANOTHER driver instance's secret (secret:galaxy/<other>/…, env:OTOPCUA_GALAXY_<OTHER>_…) is refused
|
||||
// before the probe resolves it — off the mailbox, since it reads the ConfigDb (only when the config
|
||||
// carries an in-scope secret: reference at all).
|
||||
// carries an in-scope secret:/env: reference at all).
|
||||
if (DriverCredentialPolicy.HasInstanceSegments(msg.DriverType, msg.ConfigJson))
|
||||
{
|
||||
await using var db = await _dbFactory.CreateDbContextAsync(cts.Token);
|
||||
|
||||
Reference in New Issue
Block a user