Skip to content

fix(plugin): sanitize remote step payloads#708

Merged
intel352 merged 1 commit into
mainfrom
fix/remote-plugin-strict-proto
May 18, 2026
Merged

fix(plugin): sanitize remote step payloads#708
intel352 merged 1 commit into
mainfrom
fix/remote-plugin-strict-proto

Conversation

@intel352
Copy link
Copy Markdown
Contributor

@intel352 intel352 commented May 18, 2026

Summary

  • filter pipeline metadata that cannot be represented by protobuf Struct before invoking remote steps
  • strip engine-internal underscore-prefixed config keys before STRICT_PROTO typed plugin config encoding
  • add regression coverage for HTTP metadata filtering and strict typed config with _config_dir

Dependency

  • Required by Buymywishlist admin bootstrap/passkey rollout before production deploy can rely on strict remote plugin calls.

Verification

  • GOWORK=off go test ./plugin/external

Remote steps must not send host-only HTTP metadata or engine internal config keys through strict protobuf plugin contracts.
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens external (gRPC) step execution by sanitizing payloads that are encoded into protobuf Struct/typed Any, preventing failures/leakage when pipeline metadata or engine-internal config keys are present.

Changes:

  • Filter pipeline metadata entries that cannot be represented by google.protobuf.Struct before sending them to remote steps.
  • Strip engine-internal _-prefixed config keys (e.g. _config_dir) before STRICT_PROTO typed config encoding.
  • Add regression tests covering HTTP metadata filtering and _config_dir stripping for strict contracts.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.

File Description
plugin/external/remote_step.go Filters unrepresentable metadata prior to Struct encoding; strips internal config keys prior to typed config encoding.
plugin/external/remote_step_test.go Adds regression coverage ensuring invalid HTTP metadata doesn’t break remote calls and strict typed config encoding ignores _config_dir.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 81.81818% with 2 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
plugin/external/remote_step.go 81.81% 1 Missing and 1 partial ⚠️

📢 Thoughts on this report? Let us know!

@github-actions
Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:274: parsing iteration count: invalid syntax
baseline-bench.txt:563762: parsing iteration count: invalid syntax
baseline-bench.txt:879930: parsing iteration count: invalid syntax
baseline-bench.txt:1179865: parsing iteration count: invalid syntax
baseline-bench.txt:1489946: parsing iteration count: invalid syntax
baseline-bench.txt:1793403: parsing iteration count: invalid syntax
benchmark-results.txt:274: parsing iteration count: invalid syntax
benchmark-results.txt:297725: parsing iteration count: invalid syntax
benchmark-results.txt:610998: parsing iteration count: invalid syntax
benchmark-results.txt:886168: parsing iteration count: invalid syntax
benchmark-results.txt:1161083: parsing iteration count: invalid syntax
benchmark-results.txt:1464000: parsing iteration count: invalid syntax
goos: linux
goarch: amd64
pkg: github.com/GoCodeAlone/workflow/dynamic
cpu: AMD EPYC 7763 64-Core Processor                
                            │ benchmark-results.txt │
                            │        sec/op         │
InterpreterCreation-4                  6.892m ± 59%
ComponentLoad-4                        3.592m ±  1%
ComponentExecute-4                     1.964µ ±  1%
PoolContention/workers-1-4             1.089µ ±  3%
PoolContention/workers-2-4             1.087µ ±  1%
PoolContention/workers-4-4             1.094µ ±  2%
PoolContention/workers-8-4             1.091µ ±  1%
PoolContention/workers-16-4            1.113µ ±  3%
ComponentLifecycle-4                   3.591m ±  1%
SourceValidation-4                     2.332µ ±  1%
RegistryConcurrent-4                   791.9n ±  4%
LoaderLoadFromString-4                 3.623m ±  1%
geomean                                18.71µ

                            │ benchmark-results.txt │
                            │         B/op          │
InterpreterCreation-4                  2.027Mi ± 0%
ComponentLoad-4                        2.180Mi ± 0%
ComponentExecute-4                     1.203Ki ± 0%
PoolContention/workers-1-4             1.203Ki ± 0%
PoolContention/workers-2-4             1.203Ki ± 0%
PoolContention/workers-4-4             1.203Ki ± 0%
PoolContention/workers-8-4             1.203Ki ± 0%
PoolContention/workers-16-4            1.203Ki ± 0%
ComponentLifecycle-4                   2.183Mi ± 0%
SourceValidation-4                     1.984Ki ± 0%
RegistryConcurrent-4                   1.133Ki ± 0%
LoaderLoadFromString-4                 2.182Mi ± 0%
geomean                                15.25Ki

                            │ benchmark-results.txt │
                            │       allocs/op       │
InterpreterCreation-4                   15.68k ± 0%
ComponentLoad-4                         18.02k ± 0%
ComponentExecute-4                       25.00 ± 0%
PoolContention/workers-1-4               25.00 ± 0%
PoolContention/workers-2-4               25.00 ± 0%
PoolContention/workers-4-4               25.00 ± 0%
PoolContention/workers-8-4               25.00 ± 0%
PoolContention/workers-16-4              25.00 ± 0%
ComponentLifecycle-4                    18.07k ± 0%
SourceValidation-4                       32.00 ± 0%
RegistryConcurrent-4                     2.000 ± 0%
LoaderLoadFromString-4                  18.06k ± 0%
geomean                                  183.3

cpu: AMD EPYC 9V74 80-Core Processor                
                            │ baseline-bench.txt │
                            │       sec/op       │
InterpreterCreation-4               6.690m ± 57%
ComponentLoad-4                     3.503m ±  7%
ComponentExecute-4                  1.836µ ±  0%
PoolContention/workers-1-4          1.011µ ±  2%
PoolContention/workers-2-4          1.010µ ±  0%
PoolContention/workers-4-4          1.016µ ±  1%
PoolContention/workers-8-4          1.010µ ±  1%
PoolContention/workers-16-4         1.013µ ±  2%
ComponentLifecycle-4                3.485m ±  1%
SourceValidation-4                  2.088µ ±  6%
RegistryConcurrent-4                736.5n ±  5%
LoaderLoadFromString-4              3.515m ±  3%
geomean                             17.56µ

                            │ baseline-bench.txt │
                            │        B/op        │
InterpreterCreation-4               2.027Mi ± 0%
ComponentLoad-4                     2.180Mi ± 0%
ComponentExecute-4                  1.203Ki ± 0%
PoolContention/workers-1-4          1.203Ki ± 0%
PoolContention/workers-2-4          1.203Ki ± 0%
PoolContention/workers-4-4          1.203Ki ± 0%
PoolContention/workers-8-4          1.203Ki ± 0%
PoolContention/workers-16-4         1.203Ki ± 0%
ComponentLifecycle-4                2.183Mi ± 0%
SourceValidation-4                  1.984Ki ± 0%
RegistryConcurrent-4                1.133Ki ± 0%
LoaderLoadFromString-4              2.182Mi ± 0%
geomean                             15.25Ki

                            │ baseline-bench.txt │
                            │     allocs/op      │
InterpreterCreation-4                15.68k ± 0%
ComponentLoad-4                      18.02k ± 0%
ComponentExecute-4                    25.00 ± 0%
PoolContention/workers-1-4            25.00 ± 0%
PoolContention/workers-2-4            25.00 ± 0%
PoolContention/workers-4-4            25.00 ± 0%
PoolContention/workers-8-4            25.00 ± 0%
PoolContention/workers-16-4           25.00 ± 0%
ComponentLifecycle-4                 18.07k ± 0%
SourceValidation-4                    32.00 ± 0%
RegistryConcurrent-4                  2.000 ± 0%
LoaderLoadFromString-4               18.06k ± 0%
geomean                               183.3

pkg: github.com/GoCodeAlone/workflow/middleware
cpu: AMD EPYC 7763 64-Core Processor                
                                  │ benchmark-results.txt │
                                  │        sec/op         │
CircuitBreakerDetection-4                     286.1n ± 4%
CircuitBreakerExecution_Success-4             21.45n ± 1%
CircuitBreakerExecution_Failure-4             66.23n ± 1%
geomean                                       74.07n

                                  │ benchmark-results.txt │
                                  │         B/op          │
CircuitBreakerDetection-4                    144.0 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

                                  │ benchmark-results.txt │
                                  │       allocs/op       │
CircuitBreakerDetection-4                    1.000 ± 0%
CircuitBreakerExecution_Success-4            0.000 ± 0%
CircuitBreakerExecution_Failure-4            0.000 ± 0%
geomean                                                 ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                  │ baseline-bench.txt │
                                  │       sec/op       │
CircuitBreakerDetection-4                  317.0n ± 9%
CircuitBreakerExecution_Success-4          22.65n ± 0%
CircuitBreakerExecution_Failure-4          70.96n ± 0%
geomean                                    79.87n

                                  │ baseline-bench.txt │
                                  │        B/op        │
CircuitBreakerDetection-4                 144.0 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

                                  │ baseline-bench.txt │
                                  │     allocs/op      │
CircuitBreakerDetection-4                 1.000 ± 0%
CircuitBreakerExecution_Success-4         0.000 ± 0%
CircuitBreakerExecution_Failure-4         0.000 ± 0%
geomean                                              ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/module
cpu: AMD EPYC 7763 64-Core Processor                
                                 │ benchmark-results.txt │
                                 │        sec/op         │
IaCStateBackend_InProcess-4                 321.1n ± 26%
IaCStateBackend_GRPC-4                      9.490m ±  3%
JQTransform_Simple-4                        661.5n ± 36%
JQTransform_ObjectConstruction-4            1.506µ ±  2%
JQTransform_ArraySelect-4                   3.465µ ±  2%
JQTransform_Complex-4                       39.09µ ±  1%
JQTransform_Throughput-4                    1.850µ ±  1%
SSEPublishDelivery-4                        63.83n ±  2%
geomean                                     3.853µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
IaCStateBackend_InProcess-4                 416.0 ± 0%
IaCStateBackend_GRPC-4                    5.988Mi ± 9%
JQTransform_Simple-4                      1.273Ki ± 0%
JQTransform_ObjectConstruction-4          1.773Ki ± 0%
JQTransform_ArraySelect-4                 2.625Ki ± 0%
JQTransform_Complex-4                     16.22Ki ± 0%
JQTransform_Throughput-4                  1.984Ki ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                 │ benchmark-results.txt │
                                 │       allocs/op       │
IaCStateBackend_InProcess-4                 2.000 ± 0%
IaCStateBackend_GRPC-4                     6.841k ± 0%
JQTransform_Simple-4                        10.00 ± 0%
JQTransform_ObjectConstruction-4            15.00 ± 0%
JQTransform_ArraySelect-4                   30.00 ± 0%
JQTransform_Complex-4                       324.0 ± 0%
JQTransform_Throughput-4                    17.00 ± 0%
SSEPublishDelivery-4                        0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                 │ baseline-bench.txt │
                                 │       sec/op       │
IaCStateBackend_InProcess-4              304.3n ± 22%
IaCStateBackend_GRPC-4                   10.72m ±  3%
JQTransform_Simple-4                     682.2n ± 40%
JQTransform_ObjectConstruction-4         1.550µ ±  1%
JQTransform_ArraySelect-4                3.691µ ±  8%
JQTransform_Complex-4                    44.99µ ±  3%
JQTransform_Throughput-4                 1.862µ ±  1%
SSEPublishDelivery-4                     63.80n ±  0%
geomean                                  4.019µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
IaCStateBackend_InProcess-4              416.0 ± 0%
IaCStateBackend_GRPC-4                 5.782Mi ± 4%
JQTransform_Simple-4                   1.273Ki ± 0%
JQTransform_ObjectConstruction-4       1.773Ki ± 0%
JQTransform_ArraySelect-4              2.625Ki ± 0%
JQTransform_Complex-4                  16.22Ki ± 0%
JQTransform_Throughput-4               1.984Ki ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

                                 │ baseline-bench.txt │
                                 │     allocs/op      │
IaCStateBackend_InProcess-4              2.000 ± 0%
IaCStateBackend_GRPC-4                  6.870k ± 0%
JQTransform_Simple-4                     10.00 ± 0%
JQTransform_ObjectConstruction-4         15.00 ± 0%
JQTransform_ArraySelect-4                30.00 ± 0%
JQTransform_Complex-4                    324.0 ± 0%
JQTransform_Throughput-4                 17.00 ± 0%
SSEPublishDelivery-4                     0.000 ± 0%
geomean                                             ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/schema
cpu: AMD EPYC 7763 64-Core Processor                
                                    │ benchmark-results.txt │
                                    │        sec/op         │
SchemaValidation_Simple-4                       1.107µ ± 4%
SchemaValidation_AllFields-4                    1.647µ ± 1%
SchemaValidation_FormatValidation-4             1.574µ ± 0%
SchemaValidation_ManySchemas-4                  1.845µ ± 3%
geomean                                         1.517µ

                                    │ benchmark-results.txt │
                                    │         B/op          │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

                                    │ benchmark-results.txt │
                                    │       allocs/op       │
SchemaValidation_Simple-4                      0.000 ± 0%
SchemaValidation_AllFields-4                   0.000 ± 0%
SchemaValidation_FormatValidation-4            0.000 ± 0%
SchemaValidation_ManySchemas-4                 0.000 ± 0%
geomean                                                   ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                    │ baseline-bench.txt │
                                    │       sec/op       │
SchemaValidation_Simple-4                    1.080µ ± 2%
SchemaValidation_AllFields-4                 1.658µ ± 3%
SchemaValidation_FormatValidation-4          1.588µ ± 3%
SchemaValidation_ManySchemas-4               1.589µ ± 4%
geomean                                      1.457µ

                                    │ baseline-bench.txt │
                                    │        B/op        │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

                                    │ baseline-bench.txt │
                                    │     allocs/op      │
SchemaValidation_Simple-4                   0.000 ± 0%
SchemaValidation_AllFields-4                0.000 ± 0%
SchemaValidation_FormatValidation-4         0.000 ± 0%
SchemaValidation_ManySchemas-4              0.000 ± 0%
geomean                                                ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/GoCodeAlone/workflow/store
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ benchmark-results.txt │
                                   │        sec/op         │
EventStoreAppend_InMemory-4                   1.217µ ± 10%
EventStoreAppend_SQLite-4                     1.421m ±  2%
GetTimeline_InMemory/events-10-4              13.70µ ±  2%
GetTimeline_InMemory/events-50-4              68.67µ ± 13%
GetTimeline_InMemory/events-100-4             123.3µ ±  2%
GetTimeline_InMemory/events-500-4             632.7µ ±  1%
GetTimeline_InMemory/events-1000-4            1.292m ±  4%
GetTimeline_SQLite/events-10-4                107.3µ ±  1%
GetTimeline_SQLite/events-50-4                249.7µ ±  2%
GetTimeline_SQLite/events-100-4               422.3µ ±  0%
GetTimeline_SQLite/events-500-4               1.793m ±  0%
GetTimeline_SQLite/events-1000-4              3.499m ±  3%
geomean                                       218.2µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                    769.5 ± 12%
EventStoreAppend_SQLite-4                    1.982Ki ±  2%
GetTimeline_InMemory/events-10-4             7.953Ki ±  0%
GetTimeline_InMemory/events-50-4             46.62Ki ±  0%
GetTimeline_InMemory/events-100-4            94.48Ki ±  0%
GetTimeline_InMemory/events-500-4            472.8Ki ±  0%
GetTimeline_InMemory/events-1000-4           944.3Ki ±  0%
GetTimeline_SQLite/events-10-4               16.74Ki ±  0%
GetTimeline_SQLite/events-50-4               87.14Ki ±  0%
GetTimeline_SQLite/events-100-4              175.4Ki ±  0%
GetTimeline_SQLite/events-500-4              846.1Ki ±  0%
GetTimeline_SQLite/events-1000-4             1.639Mi ±  0%
geomean                                      67.19Ki

                                   │ benchmark-results.txt │
                                   │       allocs/op       │
EventStoreAppend_InMemory-4                     7.000 ± 0%
EventStoreAppend_SQLite-4                       53.00 ± 0%
GetTimeline_InMemory/events-10-4                125.0 ± 0%
GetTimeline_InMemory/events-50-4                653.0 ± 0%
GetTimeline_InMemory/events-100-4              1.306k ± 0%
GetTimeline_InMemory/events-500-4              6.514k ± 0%
GetTimeline_InMemory/events-1000-4             13.02k ± 0%
GetTimeline_SQLite/events-10-4                  382.0 ± 0%
GetTimeline_SQLite/events-50-4                 1.852k ± 0%
GetTimeline_SQLite/events-100-4                3.681k ± 0%
GetTimeline_SQLite/events-500-4                18.54k ± 0%
GetTimeline_SQLite/events-1000-4               37.29k ± 0%
geomean                                        1.162k

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ baseline-bench.txt │
                                   │       sec/op       │
EventStoreAppend_InMemory-4                1.074µ ± 13%
EventStoreAppend_SQLite-4                  1.075m ± 31%
GetTimeline_InMemory/events-10-4           12.40µ ±  5%
GetTimeline_InMemory/events-50-4           69.09µ ±  2%
GetTimeline_InMemory/events-100-4          125.8µ ± 13%
GetTimeline_InMemory/events-500-4          577.2µ ±  1%
GetTimeline_InMemory/events-1000-4         1.179m ±  1%
GetTimeline_SQLite/events-10-4             86.02µ ±  1%
GetTimeline_SQLite/events-50-4             225.1µ ±  2%
GetTimeline_SQLite/events-100-4            391.7µ ±  3%
GetTimeline_SQLite/events-500-4            1.697m ±  1%
GetTimeline_SQLite/events-1000-4           3.339m ±  1%
geomean                                    198.0µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                 764.0 ± 13%
EventStoreAppend_SQLite-4                 1.984Ki ±  1%
GetTimeline_InMemory/events-10-4          7.953Ki ±  0%
GetTimeline_InMemory/events-50-4          46.62Ki ±  0%
GetTimeline_InMemory/events-100-4         94.48Ki ±  0%
GetTimeline_InMemory/events-500-4         472.8Ki ±  0%
GetTimeline_InMemory/events-1000-4        944.3Ki ±  0%
GetTimeline_SQLite/events-10-4            16.74Ki ±  0%
GetTimeline_SQLite/events-50-4            87.14Ki ±  0%
GetTimeline_SQLite/events-100-4           175.4Ki ±  0%
GetTimeline_SQLite/events-500-4           846.1Ki ±  0%
GetTimeline_SQLite/events-1000-4          1.639Mi ±  0%
geomean                                   67.16Ki

                                   │ baseline-bench.txt │
                                   │     allocs/op      │
EventStoreAppend_InMemory-4                  7.000 ± 0%
EventStoreAppend_SQLite-4                    53.00 ± 0%
GetTimeline_InMemory/events-10-4             125.0 ± 0%
GetTimeline_InMemory/events-50-4             653.0 ± 0%
GetTimeline_InMemory/events-100-4           1.306k ± 0%
GetTimeline_InMemory/events-500-4           6.514k ± 0%
GetTimeline_InMemory/events-1000-4          13.02k ± 0%
GetTimeline_SQLite/events-10-4               382.0 ± 0%
GetTimeline_SQLite/events-50-4              1.852k ± 0%
GetTimeline_SQLite/events-100-4             3.681k ± 0%
GetTimeline_SQLite/events-500-4             18.54k ± 0%
GetTimeline_SQLite/events-1000-4            37.29k ± 0%
geomean                                     1.162k

Benchmarks run with go test -bench=. -benchmem -count=6.
Regressions ≥ 20% are flagged. Results compared via benchstat.

@intel352 intel352 merged commit 38a8d4c into main May 18, 2026
30 checks passed
@intel352 intel352 deleted the fix/remote-plugin-strict-proto branch May 18, 2026 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants