Skip to content

feat(iac): wire RevokeProviderCredential through remoteIaCProvider#574

Merged
intel352 merged 2 commits into
mainfrom
feat/remote-iac-provider-revoke
May 7, 2026
Merged

feat(iac): wire RevokeProviderCredential through remoteIaCProvider#574
intel352 merged 2 commits into
mainfrom
feat/remote-iac-provider-revoke

Conversation

@intel352

@intel352 intel352 commented May 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds RevokeProviderCredential to remoteIaCProvider so that plugin-backed IaC providers participate in the ProviderCredentialRevoker interface
  • Without this method, the type assertion in infra_bootstrap.go line 331 always fails for remote/plugin-loaded providers, logging "warn: IaC provider does not implement ProviderCredentialRevoker" and skipping revocation entirely
  • Uses the existing remoteServiceContextInvoker duality so context cancellation is honoured when the plugin supports it

Root cause

The tc2-rotate-spaces-keys.yml rotation workflow (run 25503485781) successfully minted new SPACES credentials and stored them in GH secrets, but the old DO Spaces key was NOT revoked at DO because remoteIaCProvider lacked this method. This PR closes that gap.

Still required (DO plugin side)

workflow-plugin-digitalocean/internal/module_instance.go InvokeMethodContext switch also needs case "IaCProvider.RevokeProviderCredential" — that fix is a separate DO plugin PR that will follow this one, then core-dump will get a pin bump to bring both fixes through.

Test plan

  • TestRemoteIaCProvider_RevokeProviderCredential — happy path; verifies method name and args forwarded to invoker
  • TestRemoteIaCProvider_RevokeProviderCredential_PropagatesError — error from invoker surfaces through
  • TestRemoteIaCProvider_RevokeProviderCredential_UsesContext — context-aware invoker branch used when available
  • TestRemoteIaCProvider_ImplementsProviderCredentialRevoker — compile-time assertion var _ interfaces.ProviderCredentialRevoker = p
  • All 35 TestRemoteIaC* tests pass (GOWORK=off go test -count=1 -run TestRemoteIaC ...)

🤖 Generated with Claude Code

Add RevokeProviderCredential to remoteIaCProvider so that
wfctl's plugin-backed IaC provider participates in the
ProviderCredentialRevoker interface. Without this method,
the type assertion in infra_bootstrap.go always fails for
remote (plugin-loaded) providers, silently skipping revocation.

Uses the existing context-aware / context-free invoker duality
(remoteServiceContextInvoker) so cancellation is honoured where
the plugin supports it.

Includes compile-time interface assertion test to catch signature
drift between interface and dispatch layer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 7, 2026 15:14

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 wires RevokeProviderCredential through remoteIaCProvider so plugin-backed IaC providers can participate in credential revocation during wfctl infra bootstrap --force-rotate, instead of being skipped by the ProviderCredentialRevoker type assertion path.

Changes:

  • Added RevokeProviderCredential(ctx, source, credentialID) to remoteIaCProvider, dispatching to IaCProvider.RevokeProviderCredential via the remote service invoker (context-aware when available).
  • Added unit tests covering happy path forwarding, error propagation, context-aware invocation, and interface satisfaction.

Reviewed changes

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

File Description
cmd/wfctl/deploy_providers.go Adds remoteIaCProvider.RevokeProviderCredential dispatch to the plugin subprocess.
cmd/wfctl/deploy_providers_remote_iac_test.go Adds tests validating forwarding/behavior for RevokeProviderCredential and interface implementation.

Comment thread cmd/wfctl/deploy_providers.go Outdated
Comment on lines +628 to +629
"source": source,
"credentialID": credentialID,
Comment on lines +717 to +718
if si.args["credentialID"] != "AKID123" {
t.Errorf("args[credentialID]: got %q, want AKID123", si.args["credentialID"])
The rest of the remoteIaCProvider wire protocol uses snake_case
keys (provider_id, resource_type, ref_name). Rename camelCase
credentialID → credential_id to stay consistent and avoid
silent mismatches if/when args are serialised via proto JSON.

Update the test assertion to match the corrected key name.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented May 7, 2026

Copy link
Copy Markdown

⏱ Benchmark Results

No significant performance regressions detected.

benchstat comparison (baseline → PR)
## benchstat: baseline → PR
baseline-bench.txt:260: parsing iteration count: invalid syntax
baseline-bench.txt:545499: parsing iteration count: invalid syntax
baseline-bench.txt:813802: parsing iteration count: invalid syntax
baseline-bench.txt:1152467: parsing iteration count: invalid syntax
baseline-bench.txt:1665105: parsing iteration count: invalid syntax
baseline-bench.txt:2001400: parsing iteration count: invalid syntax
benchmark-results.txt:260: parsing iteration count: invalid syntax
benchmark-results.txt:305133: parsing iteration count: invalid syntax
benchmark-results.txt:593854: parsing iteration count: invalid syntax
benchmark-results.txt:917702: parsing iteration count: invalid syntax
benchmark-results.txt:1219800: parsing iteration count: invalid syntax
benchmark-results.txt:1536199: 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                 3.189m ± 226%
ComponentLoad-4                       3.668m ±  10%
ComponentExecute-4                    1.977µ ±   1%
PoolContention/workers-1-4            1.105µ ±   2%
PoolContention/workers-2-4            1.104µ ±   3%
PoolContention/workers-4-4            1.104µ ±   2%
PoolContention/workers-8-4            1.117µ ±   2%
PoolContention/workers-16-4           1.125µ ±   1%
ComponentLifecycle-4                  3.692m ±   1%
SourceValidation-4                    2.267µ ±   2%
RegistryConcurrent-4                  822.1n ±   6%
LoaderLoadFromString-4                3.715m ±   2%
geomean                               17.78µ

                            │ 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               3.128m ± 13%
ComponentLoad-4                     3.634m ± 19%
ComponentExecute-4                  1.829µ ±  1%
PoolContention/workers-1-4          1.012µ ±  3%
PoolContention/workers-2-4          1.028µ ±  2%
PoolContention/workers-4-4          1.048µ ±  2%
PoolContention/workers-8-4          1.049µ ±  2%
PoolContention/workers-16-4         1.044µ ±  3%
ComponentLifecycle-4                3.767m ±  2%
SourceValidation-4                  2.129µ ±  6%
RegistryConcurrent-4                755.5n ±  4%
LoaderLoadFromString-4              3.672m ±  3%
geomean                             16.92µ

                            │ 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.0n ± 4%
CircuitBreakerExecution_Success-4             21.54n ± 0%
CircuitBreakerExecution_Failure-4             66.03n ± 2%
geomean                                       74.10n

                                  │ 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                  298.8n ± 3%
CircuitBreakerExecution_Success-4          22.67n ± 1%
CircuitBreakerExecution_Failure-4          71.00n ± 0%
geomean                                    78.34n

                                  │ 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         │
JQTransform_Simple-4                        913.4n ± 24%
JQTransform_ObjectConstruction-4            1.509µ ±  1%
JQTransform_ArraySelect-4                   3.395µ ±  1%
JQTransform_Complex-4                       39.01µ ±  2%
JQTransform_Throughput-4                    1.815µ ±  1%
SSEPublishDelivery-4                        71.14n ±  1%
geomean                                     1.693µ

                                 │ benchmark-results.txt │
                                 │         B/op          │
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       │
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       │
JQTransform_Simple-4                     865.9n ± 23%
JQTransform_ObjectConstruction-4         1.417µ ±  1%
JQTransform_ArraySelect-4                3.520µ ±  1%
JQTransform_Complex-4                    42.44µ ±  2%
JQTransform_Throughput-4                 1.751µ ±  2%
SSEPublishDelivery-4                     63.69n ±  1%
geomean                                  1.653µ

                                 │ baseline-bench.txt │
                                 │        B/op        │
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      │
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.095µ ± 15%
SchemaValidation_AllFields-4                   1.656µ ±  3%
SchemaValidation_FormatValidation-4            1.597µ ±  4%
SchemaValidation_ManySchemas-4                 1.840µ ±  3%
geomean                                        1.519µ

                                    │ 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.119µ ± 19%
SchemaValidation_AllFields-4                1.682µ ±  6%
SchemaValidation_FormatValidation-4         1.590µ ±  1%
SchemaValidation_ManySchemas-4              1.603µ ±  3%
geomean                                     1.480µ

                                    │ 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.121µ ± 29%
EventStoreAppend_SQLite-4                     1.579m ±  4%
GetTimeline_InMemory/events-10-4              14.25µ ±  6%
GetTimeline_InMemory/events-50-4              73.51µ ± 12%
GetTimeline_InMemory/events-100-4             128.6µ ±  1%
GetTimeline_InMemory/events-500-4             660.5µ ±  1%
GetTimeline_InMemory/events-1000-4            1.346m ±  2%
GetTimeline_SQLite/events-10-4                112.8µ ±  2%
GetTimeline_SQLite/events-50-4                259.8µ ±  2%
GetTimeline_SQLite/events-100-4               436.4µ ±  1%
GetTimeline_SQLite/events-500-4               1.863m ±  2%
GetTimeline_SQLite/events-1000-4              3.670m ±  1%
geomean                                       226.8µ

                                   │ benchmark-results.txt │
                                   │         B/op          │
EventStoreAppend_InMemory-4                     793.0 ± 9%
EventStoreAppend_SQLite-4                     1.984Ki ± 4%
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.36Ki

                                   │ 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.105µ ± 14%
EventStoreAppend_SQLite-4                  1.077m ±  5%
GetTimeline_InMemory/events-10-4           12.73µ ±  1%
GetTimeline_InMemory/events-50-4           70.97µ ±  3%
GetTimeline_InMemory/events-100-4          145.0µ ±  2%
GetTimeline_InMemory/events-500-4          720.0µ ±  1%
GetTimeline_InMemory/events-1000-4         1.122m ± 30%
GetTimeline_SQLite/events-10-4             84.77µ ±  2%
GetTimeline_SQLite/events-50-4             221.0µ ±  3%
GetTimeline_SQLite/events-100-4            385.8µ ±  1%
GetTimeline_SQLite/events-500-4            1.674m ±  0%
GetTimeline_SQLite/events-1000-4           3.276m ±  4%
geomean                                    203.3µ

                                   │ baseline-bench.txt │
                                   │        B/op        │
EventStoreAppend_InMemory-4                  779.0 ± 5%
EventStoreAppend_SQLite-4                  1.984Ki ± 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.26Ki

                                   │ 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 faf7545 into main May 7, 2026
18 checks passed
@intel352 intel352 deleted the feat/remote-iac-provider-revoke branch May 7, 2026 15:33
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