fix(security): scope operator-authored credential references per driver (#815)
A Designer could point a Galaxy / OpcUaClient endpoint at a host they control, set a credential field to any reference the node can resolve (env:ConnectionStrings__ConfigDb, env:ServerHistorian__ApiKey, secret:<any>, Galaxy file:<any path>) and click Test Connect / live browse; the node resolved the value and sent it to that host. One shared rule in Core.Abstractions (CredentialReferences + DriverCredentialPolicy) generalises the #803 Heidenhain namespace: - Galaxy: secret:galaxy/... | secret:otopcua/galaxy/... | env:OTOPCUA_GALAXY_... | legacy env:GALAXY_MXGW_...; file: refused; dev:/literal API key unchanged. - OpcUaClient: secret:opcuaclient/... | env:OTOPCUA_OPCUACLIENT_...; literals unchanged. - Heidenhain adopts the shared parser/resolver (namespace unchanged). Enforced at the AdminUI save path (DriverConfigSaveGate), the deploy gate (CredentialReferenceDeployChecks, code CredentialReferenceOutOfScope), Test Connect (AdminOperationsActor, before any probe), live browse (BrowserSessionService, before any browser) and again at resolve time in every driver/browser (fail closed, before any store/env read). Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -585,6 +585,20 @@ public sealed class AdminOperationsActor : ReceiveActor
|
||||
return;
|
||||
}
|
||||
|
||||
// lmxopcua#815: refuse a credential reference outside the driver's namespace BEFORE any probe runs — the
|
||||
// probe would otherwise be the seam that resolves it and sends it to the author-chosen endpoint. Nothing
|
||||
// is read from the secret store or the environment on this path.
|
||||
var credentialProblems = DriverCredentialPolicy.DescribeProblems(msg.DriverType, msg.ConfigJson);
|
||||
if (credentialProblems.Count > 0)
|
||||
{
|
||||
replyTo.Tell(new TestDriverConnectResult(
|
||||
false,
|
||||
"Test Connect refused: " + string.Join(" ", credentialProblems),
|
||||
null,
|
||||
msg.CorrelationId));
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(() => ProbeAsync(probe, msg)).PipeTo(replyTo);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user