mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-25 03:43:05 +08:00
data-channels-quic-experimental
2
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
f6b27025a6 |
Classify sensitive log parameters with Microsoft.Extensions.Compliance data classification (#4864)
## Proposed changes Fixes #4857. The stack's log messages wrote network addresses (endpoint, discovery and reverse connect URLs, host names, IP addresses, ports), application and user identities, file paths and exception texts as plain parameters. Applications had no reliable way to keep them out of general-purpose logs. This PR replaces the stack's own redaction mechanism with the standard .NET [data classification and redaction](https://learn.microsoft.com/dotnet/core/extensions/data-redaction) packages. Each sensitive `[LoggerMessage]` parameter is classified. The application decides per classification what reaches its logs: erase it, replace it with an HMAC token so entries stay correlatable, or pass it through. ### Taxonomy `Opc.Ua.Redaction.OpcUaDataClassifications` defines the `OpcUa` taxonomy and one attribute per classification: | Classification | Used for | Parameters | |---|---|---| | `[NetworkAddress]` | URLs, host and domain names, IP/MAC addresses, end points, ports | 120 | | `[ApplicationIdentity]` | certificates, subject, issuer, thumbprint, ApplicationUri | 103 | | `[FilePath]` | file, directory and certificate store paths | 67 | | `[SensitiveText]` | exception or remote-supplied text passed as a parameter | 55 | | `[UserIdentity]` | user names, token subjects | 7 | Correlation ids (`ChannelId`, `SessionId`, ...), status codes and NodeIds stay unclassified. ### Pipeline and defaults - Opc.Ua.Core now references `Microsoft.Extensions.Telemetry(.Abstractions)` 10.11.0, so every project above Core uses the `Microsoft.Gen.Logging` generator. Opc.Ua.Client already did, through Http.Resilience. The packages ship net462 and netstandard2.0 builds, so net48 is supported. - **A plain `ILoggerFactory` logs `(null)` in place of classified values.** Classified values are only written by the redaction-aware logger. - The new `ILoggingBuilder.EnableOpcUaRedaction()` turns that logger on. It is `EnableRedaction()` with the discriminator off; otherwise every unredacted value gets `:ParamName` appended. `AddOpcUa().AddLogging(...)` and `DefaultTelemetry.Create(...)` call it, as do the samples, so they log the same information as before until redactors are registered. - `services.AddOpcUa()` alone does not change the host's logging. Generic-host apps call `builder.Logging.EnableOpcUaRedaction()`. This is documented as a behavior-breaking change in `docs/migrate/2.0.x/telemetry.md`. ### Obsolete API `Redact`, `RedactionWrapper<T>`, `IRedactionStrategy`, `RedactionStrategies` and `SimpleRedactionStrategy` are `[Obsolete]`. They still work, but the stack no longer uses them. ### Not classified - The `Exception` passed to a log call. Applications can drop exception messages with `LoggerEnrichmentOptions.IncludeExceptionMessage`. - Exception and `ServiceResult` message texts. - `ServiceResult`/`StatusCode` parameters and logged data values. - The few log calls whose level is decided at run time. - `Opc.Ua.Vision.OpenUsd`, which references only Opc.Ua.Types and cannot see the attributes. ### Generator behavior differences These are visible to log consumers and to tests: - `IFormattable` values such as `NodeId` are stored in the structured state as invariant strings, not as objects. - The generated log state is a thread-local object that is cleared after the call. - Classified values are pooled redactor objects, valid only during the `Log` call. Tests that inspected log state after the fact now capture it during the call. The shared `RecordingLoggerProvider` snapshots classified values. ## Related Issues - Fixes #4857 ## Types of changes - [ ] Bugfix (non-breaking change which fixes an issue) - [x] Enhancement (non-breaking change which adds functionality) - [ ] Test enhancement (non-breaking change to increase test coverage) - [x] Breaking change (fix or feature that would cause existing functionality to not work as expected; plain logger factories drop classified values) - [x] Documentation Update (if none of the other choices apply) ## Checklist - [x] I have read the CONTRIBUTING doc. - [x] I have signed the CLA. - [x] I ran tests locally with my changes, all passed. - [x] I fixed all failing tests in the CI pipelines. - [x] I fixed all introduced issues with CodeQL and LGTM. - [x] I have added tests that prove my fix is effective or that my feature works and increased code coverage. - [x] I have added necessary documentation (if appropriate). - [ ] Any dependent changes have been merged and published in downstream modules. ## Further comments New tests: - `LogClassificationCoverageTests` (Tools.Tests) scans all 104 stack assemblies and fails if an address, identity or path parameter of a `[LoggerMessage]` method is unclassified. - `DataClassificationLoggingTests` (Core.Tests) pins erasing and HMAC redaction, pass-through, the plain-factory drop, and both stack defaults. Local results on net10.0: | Suite | Passed | Failed | |---|---|---| | Core.Tests | 6,489 | 0 | | Client.Tests | 3,231 | 0 | | Tools.Tests | 7,210 | 0 | | PubSub.Tests | 1,536 | 0 | | Core.Diagnostics.Tests | 571 | 0 | | Configuration.Tests | 241 | 0 | - **Server.Tests:** the full run predates the final test fixes and had 12 failures. All 12 were in the fixtures fixed afterwards, which now pass: RoleStateBinding (45/45) and the FileDirectory and compatibility-logging fixtures (74/74 in total). The full Core.Tests and Server.Tests runs were not repeated after those fixes. - **Builds:** `UA.slnx` builds with 0 errors for net10.0 and net48, and the whitespace check passes. - **NativeAOT:** not confirmed locally, because the machine has no C++ linker. A trimmed publish of `Opc.Ua.Aot.Tests` reported no trim or AOT warnings from the stack, the new packages or the generated logging code; its only errors come from the TUnit test framework (`FSharp.Core` not found). The `aot-test` CI job has to confirm the native build. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Marc Schier <marcschier@users.noreply.github.com> |
||
|
|
1bb4bdca1d |
Add Machine Vision Parts 1 and 2 (#4733)
# Description Implement the released [OPC 40100-1](https://reference.opcfoundation.org/specs/OPC-40100-1) and [OPC 40100-2](https://reference.opcfoundation.org/specs/OPC-40100-2) specifications with generated models, provider-backed runtimes, typed clients, MCP workflows, and DI/Machinery integration. - **Part 1 stays in `Opc.Ua.Vision`** and its client/server packages alongside the distinct Perception model. Provide control/acquisition state machines, jobs and synchronized steps, recipe/product/configuration/result management, file transfers, diagnostics, events, and conditions. - **Part 2 is in `Opc.Ua.MachineVision`, `.Client`, and `.Server`.** Provide asset categories, identification, image-handling aspects, health/maintenance data, topology, and transactional updates. The base Vision assemblies do not reference these optional packages; the Part 2 wire model does not depend on Part 1. - Preserve the release-pinned model bytes, wire namespaces and NodeIds. Perception types are in `Opc.Ua.Vision.Perception`; the AMCM generated namespace remains `Opc.Ua.Vision.MachineVision.AMCM`, and asset client/server extension namespaces remain `Opc.Ua.Vision.Client` and `Opc.Ua.Vision.Server`. - Use `AddOpcUaMachineVision` and `AddOpcUaMachineVisionAMCM` for model loading and factory registration. Each has node-collection, encodeable-factory-builder and node-state-factory-builder overloads. These short entry points delegate to the generated implementations; existing namespace-derived generated names remain available for compatibility. - Support multiple independent named systems/assets under one namespace-owning manager. Reuse injectable providers, file binding, bounded memory stores, optional transactional `IFileSystemProvider` persistence, state machines, telemetry and conformance infrastructure. - Keep one `docs/Vision.md` guide, titled `Machine Vision (OPC 40100-1 and OPC 40100-2)`, and one `Opc.Ua.Mcp.Vision` package. Include deterministic server/client samples. - Expose 17 Machine Vision MCP tools, including capabilities/status, bounded relationships and observation, complete small-file uploads/downloads, management, explicit control, conditions, and chunked transfers. Catalogue counts: 39 Vision-specific, 43 with connection tools, 81 Vision+Robotics, 155 Full. Every Machine Vision wire parameter has a schema description. **Compatibility and limits:** `AddVision()` remains Perception-only unless released parts are selected. Standalone Part 2 uses `AddVision().AddMachineVision()`; Machinery composition uses `AddVisionToMachinery()`. Existing tool defaults and command signatures are preserved. Observation owns and cleans up its subscription: 5 seconds/50 notifications by default, capped at 60 seconds/100 notifications. Complete-file tools are capped at 1 MiB; larger files use chunked transfers. Domain Error values remain distinct from UA service failures. **Versioning:** the seven Vision/MachineVision/MCP packages and their Debug variants follow the repository root version instead of being forced to preview. Vision.OpenUsd and its descendants remain preview-only. Development builds still inherit the root prerelease version. No release version, tag, release branch, publication policy, or feed promotion is changed. **Review actions:** all fourteen review threads have action/evidence replies and are resolved. Changes include the unified guide, Perception namespace, separate Part 2 packages and final naming, multi-system ownership explanation, interrupted-write cleanup, observer failure isolation, complete MCP parameter descriptions, and explicit package inventory. The preview-layout migration topic and the requested ReleaseProcess caveat were removed. The test Publish collector now retries recognized transient failures within one cancellation budget and propagates other exceptions. Commit |