Skip to content

feat: support hierarchical permission wildcards#1327

Open
memleakd wants to merge 1 commit into
codeigniter4:developfrom
memleakd:feat/hierarchical-permission-wildcards
Open

feat: support hierarchical permission wildcards#1327
memleakd wants to merge 1 commit into
codeigniter4:developfrom
memleakd:feat/hierarchical-permission-wildcards

Conversation

@memleakd
Copy link
Copy Markdown

This PR intends to finalize the hierarchical permissions work from #1253 and #1309, which had stalled for some time.

Shield already supports wildcard permissions, but the current behavior is limited when permissions are organized into deeper namespaces.

In larger, real-world applications, permissions often grow beyond two segments. The flat/single-level wildcard behavior makes those permission sets harder to express and maintain cleanly, often requiring custom workarounds.

This PR makes wildcard permissions work with deeper structures while keeping the existing $user->can() and $group->can() APIs unchanged.

A trailing wildcard now covers the dotted scope itself and its descendants:

'forum.posts.*'

matches forum.posts, forum.posts.create, and forum.posts.comments.delete.

Wildcards can also be used in the middle of a permission, so forum.*.create matches forum.posts.create and forum.comments.create, but not forum.posts.comments.create.

I tried to address the concerns and review feedback from the earlier attempts:

  • wildcard matching is shared instead of duplicated;
  • both group-level and direct user-level permissions use the same matcher;
  • direct user wildcard permissions still need to be listed in Config\AuthGroups::$permissions before assignment;
  • * must be a complete segment;
  • * cannot be the first segment;
  • standalone * does not grant everything;
  • admin.* does not grant the root admin label;
  • tests cover the matcher itself and the public $user->can() / $group->can() paths.

I'd appreciate any feedback. Hopefully this can help move this long-standing and requested feature forward.

Add hierarchical wildcard matching for Shield permissions.

- Support nested trailing wildcards like forum.posts.*
- Support middle-segment wildcards like forum.*.create
- Share wildcard matching between user and group permission checks
- Document wildcard semantics and direct user wildcard assignment
- Cover matcher behavior and public authorization paths

Co-authored-by: bgeneto <bgeneto@duck.com>
Co-authored-by: christianberkman <christianberkman@users.noreply.github.com>

Signed-off-by: memleakd <121398829+memleakd@users.noreply.github.com>
Copy link
Copy Markdown
Member

@michalsn michalsn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to make wildcards simpler: trailing wildcards match children only, never the parent. So forum.posts.* would match forum.posts.create but NOT forum.posts.

The current "parent matching" feels like hidden privilege escalation. If someone sets up forum.posts.* thinking "all actions on posts", they probably don't expect it also grants the bare forum.posts scope - which could be used as a different kind of gate elsewhere in their app. Current behavior is non-intuitive to me.

@michalsn michalsn requested a review from datamweb May 27, 2026 15:13
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