fix(security): preflight and /raw banner check the merged driver+device config (#850)
The deploy gate's merged-config path check is now one helper, CredentialReferenceDeployChecks.MergedOnlyProblems (problems the runtime merge reveals that the per-config checks do not), shared by the gate and CredentialReferencePreflight.Scan - so an AuthType switch in one config and a UserCertificatePath in the other is listed as a Draft finding '(merged with its devices)' on the banner before a deploy refuses it. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+42
@@ -52,4 +52,46 @@ public sealed class CredentialReferencePreflightInstanceAndPathTests
|
||||
f.Problem.ShouldContain("lmxopcua#836");
|
||||
f.Problem.ShouldNotContain("plant.pfx");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// lmxopcua#850: the AuthType switch in one config and the path in the other — each config passes alone, the
|
||||
/// runtime-merged config does not. The deploy gate catches it; the banner must show it before a deploy does.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void A_path_split_from_its_certificate_switch_is_listed_from_the_merged_config()
|
||||
{
|
||||
var findings = CredentialReferencePreflight.Scan(
|
||||
[Drv("o", "Upstream", DriverTypeNames.OpcUaClient, """{"AuthType":"Anonymous","UserCertificatePath":"C:\\stolen\\host.pfx"}""")],
|
||||
[new Device { DeviceId = "dev-o", DriverInstanceId = "o", Name = "d", DeviceConfig = """{"AuthType":"Certificate"}""" }],
|
||||
[]);
|
||||
|
||||
var f = findings.ShouldHaveSingleItem();
|
||||
f.Source.ShouldBe(CredentialFindingSource.Draft);
|
||||
f.DriverInstanceId.ShouldBe("o");
|
||||
f.DeviceName.ShouldBeNull();
|
||||
f.Problem.ShouldContain("merged with its devices");
|
||||
f.Problem.ShouldContain("lmxopcua#836");
|
||||
f.Problem.ShouldNotContain("host.pfx");
|
||||
}
|
||||
|
||||
/// <summary>Control: a problem already reported on one config is not listed a second time from the merge.</summary>
|
||||
[Fact]
|
||||
public void A_path_already_reported_on_its_own_config_is_not_duplicated_by_the_merge() =>
|
||||
CredentialReferencePreflight.Scan(
|
||||
[Drv("o", "Upstream", DriverTypeNames.OpcUaClient, """{"AuthType":"Certificate","UserCertificatePath":"C:\\certs\\plant.pfx"}""")],
|
||||
[new Device { DeviceId = "dev-o", DriverInstanceId = "o", Name = "d", DeviceConfig = "{}" }],
|
||||
[])
|
||||
.ShouldHaveSingleItem().Problem.ShouldNotContain("merged");
|
||||
|
||||
/// <summary>lmxopcua#849: an env: reference naming another instance is listed like a secret: one.</summary>
|
||||
[Fact]
|
||||
public void A_cross_instance_env_reference_is_listed() =>
|
||||
CredentialReferencePreflight.Scan(
|
||||
[
|
||||
Drv("DRV-a", "A", DriverTypeNames.Galaxy, "{}"),
|
||||
Drv("DRV-b", "B", DriverTypeNames.Galaxy, """{"Gateway":{"ApiKeySecretRef":"env:OTOPCUA_GALAXY_DRV_A_KEY"}}"""),
|
||||
],
|
||||
[],
|
||||
[])
|
||||
.ShouldHaveSingleItem().Problem.ShouldContain("lmxopcua#849");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user