Conversation
There was a problem hiding this comment.
Pull request overview
This PR strengthens runtime and builder-side validation to ensure only valid KernelProcessStep (and step state) types are accepted/loaded, improving safety when building processes and when restoring steps from Dapr-persisted state.
Changes:
- Add type validation in
ProcessStepBuilderTypedto reject non-KernelProcessStepstep types (with corresponding unit tests). - Add Dapr runtime validation for loaded step types (and step state types) and improve error behavior when type resolution fails.
- Add new unit tests covering
TypeInfo.ConvertValueandDaprStepInfo.ToKernelProcessStepInfovalidation/error paths.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| dotnet/src/Experimental/Process.UnitTests/Core/ProcessBuilderTests.cs | Adds unit tests verifying AddStepFromType(Type) rejects invalid types and accepts valid step types. |
| dotnet/src/Experimental/Process.Runtime.Dapr/Serialization/TypeInfo.cs | Throws a KernelException when Type.GetType(...) fails, instead of deserializing with a null type. |
| dotnet/src/Experimental/Process.Runtime.Dapr/DaprStepInfo.cs | Validates that resolved inner step types are assignable to KernelProcessStep. |
| dotnet/src/Experimental/Process.Runtime.Dapr/Actors/StepActor.cs | Validates loaded inner step types and validates persisted step-state types during activation. |
| dotnet/src/Experimental/Process.Runtime.Dapr.UnitTests/TypeInfoTests.cs | New tests for TypeInfo.ConvertValue success + failure cases. |
| dotnet/src/Experimental/Process.Runtime.Dapr.UnitTests/DaprStepInfoTests.cs | New tests for DaprStepInfo.ToKernelProcessStepInfo type validation. |
| dotnet/src/Experimental/Process.Core/ProcessStepBuilder.cs | Adds validation in ProcessStepBuilderTyped constructor to enforce KernelProcessStep step types. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Automated Code Review
Reviewers: 4 | Confidence: 88%
✓ Correctness
This PR adds type validation checks across the Dapr process runtime to ensure that deserialized types are valid KernelProcessStep or KernelProcessStepState subclasses before use. It also fixes a potential NullReferenceException in TypeInfo.ConvertValue where Type.GetType could return null and was used with a null-forgiving operator. All changes are correct, well-tested, and improve error handling by providing clear error messages instead of obscure runtime failures.
✓ Security Reliability
This PR adds type-validation checks at several deserialization/type-resolution trust boundaries in the Dapr process runtime, hardening against arbitrary type instantiation and null reference errors. The changes are well-targeted security improvements. One minor gap: the new state-type validation in StepActor only checks non-null resolved types, leaving the pre-existing null stateType → ArgumentNullException path unimproved despite being in the same code block.
✓ Test Coverage
This PR adds type validation guards (ensuring types are KernelProcessStep/KernelProcessStepState subclasses) across ProcessStepBuilder, DaprStepInfo, StepActor, and TypeInfo, and fixes a potential NullReferenceException in TypeInfo.ConvertValue. New unit tests cover ProcessStepBuilder, DaprStepInfo, and TypeInfo changes well. However, the two new validation paths added in StepActor.cs (lines 105-108 and 381-384) have no corresponding unit tests. StepActor inherits from Dapr's Actor base class which makes direct unit testing harder, but this is a notable coverage gap for the new defensive checks.
✓ Design Approach
The PR adds
IsAssignableFrom(KernelProcessStep)guards at three independent call sites (ProcessStepBuilderTyped,DaprStepInfo.ToKernelProcessStepInfo,StepActor.InitializeStep) and fixes a null-forgiving operator bug inTypeInfo.ConvertValue. TheTypeInfo.csfix is correct and straightforward. The main design concern is that theIsAssignableFromvalidation is scattered across calers rather than placed at the single authoritative contract — theKernelProcessStepInfoconstructor, which already checksVerify.NotNull(innerStepType)but does not validate the type hierarchy. Placing the guard there once would prevent future callers from bypassing it and eliminate duplication. The PR does improve the status quo (no guards → guards in several places), so this is not a blocking issue, but it extends an ad-hoc pattern rather than fixing it at the root.
Suggestions
- In
StepActor.ActivateStepAsync, whenType.GetType(stepStateType.Value)returns null (e.g., assembly/type renamed), the newstateType is not nullguard is skipped and execution falls through toJsonSerializer.Deserialize(stateObjectJson, stateType!), producing an unhelpfulArgumentNullException. Consider also throwing a descriptiveKernelExceptionfor the null case, consistent with the pattern used inTypeInfo.ConvertValueand the_innerStepTypecheck inInitializeStep.
Automated review by westey-m's agents
Motivation and Context
Description
Contribution Checklist