Skip to content

Update Role management to support Roles V2 Api#68

Open
RovinKYK wants to merge 3 commits intowso2-extensions:masterfrom
RovinKYK:add_roles
Open

Update Role management to support Roles V2 Api#68
RovinKYK wants to merge 3 commits intowso2-extensions:masterfrom
RovinKYK:add_roles

Conversation

@RovinKYK
Copy link
Copy Markdown
Contributor

@RovinKYK RovinKYK commented Apr 10, 2026

Purpose

The Roles V2 API introduces breaking changes in the roles resource structure that the existing import/export implementation could not handle:

  • The permissions array now includes $ref fields that contain environment-specific URLs, causing validation errors on import if not stripped.
  • The audience object includes a value field containing an internal UUID (for org-scoped roles) or application ID (for app-scoped roles), which is non-portable across environments.
  • New system roles (Administrator, Impersonator) introduced in IS 7.0.0 were not excluded from import and deletion, causing errors.
  • Application IDs captured during import were not being stored, so cross-resource reference resolution (e.g. resolving app name → ID for role audience) had no data to work with.

This PR adds version-aware handling for the Roles V2 API and implements a reference resolution mechanism for application and organization IDs used in role audience fields.

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

Goals

  • Support Roles V2 API (/scim2/v2/Roles/) for IS 7.0.0 and above while maintaining backward compatibility with V1
  • Correctly strip non-portable fields ($ref, audience.value) on export and resolve them back on import
  • Resolve organization-scoped role audience values by fetching the super organization ID at import time
  • Resolve application-scoped role audience values by name-to-ID lookup using a cross-resource identifier map
  • Exclude Administrator and Impersonator system roles from import and deletion on IS 7.0.0+
  • Populate the identifier map during application import/update so role audience references can be resolved

Approach

  • Introduced RolesV2ApiExists flag in utils, which is set by comparing Roles at the start of export and import
  • Added processExportedRole() to strip $ref from permission entries and remove audience.value before writing to file
  • Added processAudienceForImport() to rehydrate audience.value at import time: for organization audience type, calls GetSuperOrganizationId() from the new organizations package; for application audience type, resolves the name via ReplaceReferences() using RESOURCE_REFERENCE_METADATA
  • Updated SendImportRequest() to return the *http.Response so callers can extract the Location header and capture the newly created resource ID
  • Updated application import and update paths (importApplication, importAppWithCRUD, updateApplication, updateAppWithCRUD) to call AddToIdentifierMap() after success, and export to call it after each successful export
  • Added organizations package with GetSuperOrganizationId() fetching via the self endpoint
  • Added ORGANIZATIONS resource type and path routing, and internal_organization_view OAuth2 scope
  • Added roleArrayIdentifiers so permissions/properties arrays are correctly serialized with stable identifiers
  • Extended system role exclusion list to include Administrator and Impersonator when V2 API is active

User stories

Summary of user stories addressed by this change>

Release note

Brief description of the new feature or bug fix as it will appear in the release notes

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 10, 2026 11:56
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

This PR updates role management to support a Roles V2 SCIM API, introduces role-specific export/import transformations (audience + permissions handling), and adds application identifier mapping to support cross-resource reference replacement during role import.

Changes:

  • Add Roles V2 API routing (v1 vs v2 endpoint selection) and role payload preprocessing for export/import.
  • Track application identifiers during export/import to support reference replacement (e.g., role audience → application).
  • Extend constants/metadata (resource type additions, system-role constants, scopes, array identifier metadata).

Reviewed changes

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

Show a summary per file
File Description
iamctl/pkg/utils/versionUtils.go Introduces a global flag to switch role base URL behavior for Roles V2.
iamctl/pkg/utils/versionRequirements.go Adds a minimum-version constant intended to gate Roles V2 usage.
iamctl/pkg/utils/keywordUtils.go Adds array identifier support for ROLES.
iamctl/pkg/utils/init.go Extends OAuth scopes with role permissions update scope.
iamctl/pkg/utils/constants.go Adds ORGANIZATIONS resource type, system-role constants, role array identifiers, and role→application reference metadata.
iamctl/pkg/utils/commonUtils.go Changes Contains behavior (case-sensitive vs case-insensitive).
iamctl/pkg/utils/apiUtils.go Changes SendImportRequest to return *http.Response, updates role base URL selection, and adjusts roles GET query params.
iamctl/pkg/userStores/import.go Updates import call site for new SendImportRequest signature.
iamctl/pkg/roles/rolesUtils.go Adds export/import processing for Roles V2 payloads and version-based API selection.
iamctl/pkg/roles/import.go Enables Roles V2 mode during import; updates system-role skipping and role create flow for audience/reference handling.
iamctl/pkg/roles/export.go Enables Roles V2 mode during export; adds role preprocessing for exported payloads.
iamctl/pkg/organizations/organizationUtils.go Adds helper to resolve the “super organization” ID used when importing org-audience roles.
iamctl/pkg/identityProviders/import.go Updates import call site for new SendImportRequest signature.
iamctl/pkg/claims/import.go Updates import call site for new SendImportRequest signature.
iamctl/pkg/applications/import.go Captures import response to derive app ID from Location and populates identifier map for downstream reference replacement.
iamctl/pkg/applications/export.go Populates identifier map during export to support reference replacement.
Comments suppressed due to low confidence (1)

iamctl/pkg/utils/commonUtils.go:55

  • Contains was changed from case-insensitive (strings.EqualFold) to case-sensitive (==). This is used by RemoveDeletedLocalResources during export; if the remote resource names differ only by case from the local filenames, this can incorrectly delete local files. If case-insensitive matching is still required, revert to strings.EqualFold (or document/enforce consistent casing end-to-end).
func Contains(slice []string, item string) bool {

	for _, s := range slice {
		if s == item {
			return true
		}
	}
	return false

💡 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