Skip to content

External plugin loading: step type conflicts require LoadPluginWithOverride workaround #266

@intel352

Description

@intel352

Problem

When loading external plugins that register step types already provided by built-in plugins, the standard engine.LoadPlugin() fails with:

step type "step.authz_check" already registered

This happens because:

  1. The pipelinesteps plugin registers a built-in step.authz_check (mock/no-op implementation)
  2. An external plugin (e.g., workflow-plugin-authz) also registers step.authz_check with a real Casbin-backed implementation
  3. LoadPlugin() rejects the duplicate

Current Workaround

We use LoadPluginWithOverride() (added in v0.3.12 via PR #263) for all external plugins:

if err := engine.LoadPluginWithOverride(adapter); err != nil {
    return nil, nil, fmt.Errorf("register external plugin %q: %w", name, err)
}

This works but is a blunt instrument — it allows any external plugin to silently override any built-in type, not just the intentional overrides.

Desired Behavior

A more granular approach would be helpful. Some ideas:

  1. Plugin-declared intent — External plugins could declare which types they intend to override vs. add new. The loader could then reject unexpected overrides while allowing declared ones.

  2. Per-type override control — Something like engine.LoadPluginWithOverrides(plugin, allowOverride: ["step.authz_check"]) to whitelist specific overrides.

  3. Built-in "placeholder" types — Built-in plugins could mark certain types as "placeholder" or "overridable", so external plugins replacing them don't need special loading.

  4. Plugin priority/ordering — External plugins loaded later could override earlier registrations by default (last-writer-wins), with a warning log.

Context

  • workflow v0.3.12LoadPluginWithOverride exists and works
  • workflow-plugin-authz v0.2.0 — registers step.authz_check (Casbin) + authz.casbin module type
  • pipelinesteps plugin — registers built-in step.authz_check (mock PolicyEngine backend)
  • The built-in step.authz_check only works with the mock PolicyEngineModule and is not useful in production — the external plugin's version with real Casbin is always needed

Additional Note

The workflow-plugin-authz v0.2.0 release notes mentioned renaming the step to step.authz_check_casbin, but the actual binary still registers step.authz_check. If the plugin did use a unique name, this conflict wouldn't arise — but the ability to override built-in implementations is still a valid use case that would benefit from first-class support.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions