abpframework / abpframework/abp

Improve dynamic permission definition aggregation to support module extensions

Open
#25,665 0 comments 0 reactions 1 assignee View on GitHub

@maliming is already working on this.

Since Jun 23, 2026.

feature-request
Dominant language
C#
Stars
14.4k
Forks
3.7k
Avg merge
15h 32m
Merged PRs (30d)
106

Description

Is there an existing issue for this?
  • I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.

When implementing dynamic permissions, settings, or features that extend existing modules, I noticed that the current implementation of IPermissionDefinitionManager.GetGroupsAsync (and similar managers for settings and features) filters out definitions that share the same name as statically defined ones.

Specifically, when a user extends a module without using plugins or direct references, and adds custom permissions, these custom definitions are silently discarded during the GetGroupsAsync call because the system assumes that any definition with a duplicate name is a duplicate entry and should be skipped. This makes it impossible to extend built-in modules with additional permission, setting, or feature definitions in a clean way when the extension is not integrated through standard module referencing mechanisms.

This behavior is not documented and creates a hidden limitation for modular extension scenarios.

Describe the solution you'd like

I propose that the ABP framework should support aggregating dynamic and static definitions for permissions, settings, and features.

Expected behavior:

When GetGroupsAsync is called, it should return a combined set of definitions from both static registration and dynamic providers.

If the dynamic definition has the same name as the static definition, the framework should merge or override it based on the dynamic option strategy (for example, the dynamic option takes precedence over the static one, or an exception is thrown and clear guidance is provided).

This should be consistent across PermissionDefinitionManager, SettingDefinitionManager, and FeatureDefinitionManager.

Additional context

https://github.com/abpframework/abp/blob/38746937a5bb9ab51a0d74ac7df122cd3eb0b847/framework/src/Volo.Abp.Features/Volo/Abp/Features/FeatureDefinitionManager.cs#L56-L69

Example of Combined Permissions:

public virtual async Task<IReadOnlyList<PermissionGroupDefinition>> GetGroupsAsync()
{
    var staticGroups = await _staticStore.GetGroupsAsync();
    var dynamicGroups = await _dynamicStore.GetGroupsAsync();

    var mergedGroups = new Dictionary<string, PermissionGroupDefinition>();

    foreach (var staticGroup in staticGroups)
    {
        mergedGroups[staticGroup.Name] = staticGroup;
    }

    foreach (var dynamicGroup in dynamicGroups)
    {
        if (mergedGroups.TryGetValue(dynamicGroup.Name, out var existingGroup))
        {
            MergeGroupPermissions(existingGroup, dynamicGroup);
        }
        else
        {
            mergedGroups[dynamicGroup.Name] = dynamicGroup;
        }
    }

    return mergedGroups.Values.ToImmutableList();
}

// Implement MergeGroupPermissions

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.