Skip to content

Add support for Workflows resource type#66

Open
RovinKYK wants to merge 9 commits intowso2-extensions:masterfrom
RovinKYK:add_workflows
Open

Add support for Workflows resource type#66
RovinKYK wants to merge 9 commits intowso2-extensions:masterfrom
RovinKYK:add_workflows

Conversation

@RovinKYK
Copy link
Copy Markdown
Contributor

@RovinKYK RovinKYK commented Apr 7, 2026

Purpose

Add export/import support for the Workflows resource type, including Workflow Associations as a dependent sub-resource. Introduces role identifier reference resolution within workflow templates and fixes association isEnabled state not being applied on creation.

Related to https://github.com/wso2-enterprise/iam-product-management/issues/662

Goals

  • Export and import workflows via the IS workflow management REST APIs
  • Export workflow associations embedded in their parent workflow file; import and sync them as part of the same workflow operation
  • Maintain an explicit local association name list (WorkflowAssociations.*) to drive stale association cleanup without requiring a per-workflow association lookup on import
  • Resolve role identifier references within workflow template steps, replacing deployed role IDs with portable names across environments
  • Strip user-type step options from exported workflow files since user references are environment-specific and non-portable
  • Fix workflow associations not reflecting isEnabled: false on initial creation
  • Wire role identifier mappings into AddToIdentifierMap on both export and import so that workflows processed later in the pipeline can resolve role references correctly

Approach

Two resource types: WORKFLOWS and WORKFLOW_ASSOCIATIONS

Workflows introduce two resource types: WORKFLOWS as the primary resource and WORKFLOW_ASSOCIATIONS as a sub-resource. Associations are not exported as standalone files. Instead, each workflow file embeds its associations under an associations key. On export, a separate flat WorkflowAssociations.* file records only association names, used purely as a deletion manifest on import.

WORKFLOW_ASSOCIATIONS is declared as a sub-resource constant (not added to ResourceOrder) and gets its own entry in getResourcePath() and init.go scopes. This keeps it invisible as a standalone resource while still allowing shared utilities to route API calls. Failures are summarized in Workflows.

Sub-resource failure mapping to main resource summary

Association failures during import are attributed to the parent WORKFLOWS resource type in the summary rather than creating a separate WORKFLOW_ASSOCIATIONS failure row. When removeDeletedDeployedWfAssociations fails to delete a stale association, the affected workflow name is added to a failedWorkflows set. The main import loop skips those workflows and records the failure under WORKFLOWS. This surfaces the problem at the workflow level, which is the actionable unit for the operator.

Explicit association list for delete

Rather than fetching all deployed associations and matching them against per-workflow lookups, a single WorkflowAssociations.* file is written during export containing all exported association names. On import, this file is read once and diffed against the full deployed association list to identify and delete stale entries before any workflow create/update is attempted. This avoids N+1 API calls and provides a clear, auditable local record of which associations are under management.

Fixing isEnabled: false not applied on creation

The IS workflow association POST API creates associations in an enabled state regardless of the isEnabled field in the request body. createAssociation detects when the local definition has isEnabled: false, reads the created association's ID from the POST response body, and immediately issues a PATCH to disable it. This two-step sequence is encapsulated in disableAssociation in workflowUtils.go.

Role reference resolution in workflow templates

Workflow template steps contain options arrays with role values stored as server-specific IDs (e.g. "abc123"). On export, ReplaceReferences is called with the reference metadata defined in constants.go:

RESOURCE_REFERENCE_METADATA = map[ResourceType][]ResourceReferenceMeta{
    WORKFLOWS: {                                                                                                                                                     
        {ReferencedResourceType: ROLES, ReferencePaths: []string{
            "template.steps.[step=all_items].options.[entity=roles].values",                                                                                         
        }},                                                                                                                                                          
    },                                                                                                                                                               
}

This replaces role IDs with display names in the exported file. On import, references are resolved back to IDs using the identifier map populated during the roles import step, which runs earlier in ResourceOrder. To support this, roles/export.go and roles/import.go now call AddToIdentifierMap on each successfully processed role so the map is populated regardless of which direction the pipeline runs.

Stripping user step options

User-type step options (entity == "users") reference specific user accounts by server-specific identifiers and cannot be meaningfully ported across environments. removeUserStepOptions filters them out during export. Steps that become empty after filtering are also removed. A warning is logged on both export and import to make
the omission explicit to the operator.

Workflow associations sync

syncWorkflowAssociations reconciles the associations declared in the local workflow file against the currently deployed association list. For each association in the file it either creates (if not deployed) or updates via PATCH (if deployed). Association identity is matched by name. The full association body is sent on both create and PATCH to keep the logic uniform.

User Stories

As a system administrator, I want to export and import approval workflows using IAM-CTL to enable version control and maintain consistent IAM configurations.

Release Note

Added Workflow management support to IAM-CTL tool.

Documentation

Link(s) to product documentation that addresses the changes of this PR. If no doc impact, enter “N/A” plus brief explanation of why there’s no doc impact

Training

Link to the PR for changes to the training content in https://github.com/wso2/WSO2-Training, if applicable

Certification

Type “Sent” when you have provided new/updated certification questions, plus four answers for each question (correct answer highlighted in bold), based on this change. Certification questions/answers should be sent to certification@wso2.com and NOT pasted in this PR. If there is no impact on certification exams, type “N/A” and explain why.

Marketing

Link to drafts of marketing content that will describe and promote this feature, including product page changes, technical articles, blog posts, videos, etc., if applicable

Automation tests

  • Unit tests

    Code coverage information

  • Integration tests

    Details about the test cases and coverage

Security checks

Samples

Provide high-level details about the samples related to this feature

Related PRs

List any other related PRs

Migrations (if applicable)

Describe migration steps and platforms on which migration has been tested

Test environment

List all JDK versions, operating systems, databases, and browser/versions on which this feature/fix was tested

Learning

Describe the research phase and any blog posts, patterns, libraries, or add-ons you used to solve the problem.

Copilot AI review requested due to automatic review settings April 7, 2026 18:26
Copy link
Copy Markdown

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

Adds first-class Workflows support to iamctl, enabling workflow export/import (including workflow associations) and integrating workflow-specific keyword/reference handling into the existing resource pipeline.

Changes:

  • Introduces a new workflows package with export/import logic, including handling of workflow associations and workflow-step sanitization.
  • Extends utils to recognize the new resource types/configs (WORKFLOWS + WORKFLOW_ASSOCIATIONS), add API paths, add workflow array/reference metadata, and support GET list query params.
  • Updates roles import/export to populate the identifier map so workflow role references can be replaced during export/import.

Reviewed changes

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

Show a summary per file
File Description
iamctl/pkg/workflows/workflowUtils.go Workflow + association helper logic (list/retrieve/process/serialize; export summary helper).
iamctl/pkg/workflows/import.go Imports workflows and syncs/deletes workflow associations.
iamctl/pkg/workflows/export.go Exports workflows, collects association names, writes association list file.
iamctl/pkg/utils/setup.go Adds WorkflowConfigs to tool/keyword config structs.
iamctl/pkg/utils/resourceOrder.go Adds WORKFLOWS to the processing order.
iamctl/pkg/utils/keywordUtils.go Registers workflow array identifiers.
iamctl/pkg/utils/init.go Adds workflow/workflow-association OAuth scopes.
iamctl/pkg/utils/constants.go Adds new resource types/config constants and workflow reference metadata (Workflows → Roles).
iamctl/pkg/utils/apiUtils.go Adds query param support for list requests + workflow API paths.
iamctl/pkg/roles/rolesUtils.go Simplifies role ID lookup helper.
iamctl/pkg/roles/import.go Registers role identifiers during import (needed for reference replacement).
iamctl/pkg/roles/export.go Registers role identifiers during export (needed for reference replacement).
iamctl/cmd/cli/importAll.go Wires workflows into importAll.
iamctl/cmd/cli/exportAll.go Wires workflows into exportAll.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

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