Permify / permify

An open-source authorization as a service inspired by Google Zanzibar, designed to build and manage fine-grained and scalable authorization systems for any application.
https://permify.co/
Apache License 2.0
4.99k stars 225 forks source link

[BUG] The problem of breakage in the third chain. #1744

Closed xXAvoraXx closed 3 weeks ago

xXAvoraXx commented 3 weeks ago

Describe the bug I am developing a schema on the chain of authority sharing, in which I have a scenario in which an authority accessed by higher authorities is shared with lower authorities. If there is a break in the chain, the following should be cut off. Why is there a break in the 3rd chain when the editor role should have access to action1?

image

To Reproduce

entity user {}
entity role {
    relation member @user
    relation shared_from @permission_share
    permission can_shared_access = shared_from.can_access
    permission can_access = member
}
entity perm {
    relation direct_access @role
    relation shared_access @permission_share
    permission can_shared_access = shared_access.can_access and direct_access.can_shared_access
    permission can_access = direct_access.can_access or can_shared_access
}
entity permission_share {
    relation shared_access @role
    relation shared_permission @permission_share
    permission can_shared_access = shared_access.can_shared_access
    permission role_member = shared_access.member
    permission shared_permission_access = shared_permission.role_member and can_shared_access
    permission can_access = role_member or shared_permission_access
}

- name: Test
  checks:
    - entity: perm:action1
      subject: user:supervisor
      assertions:
        can_access: true
    - entity: perm:action1
      subject: user:admin
      assertions:
        can_access: true
    - entity: perm:action1
      subject: user:mod
      assertions:
        can_access: true
    - entity: perm:action1
      subject: user:editor
      assertions:
        can_access: true

Example Application https://play.permify.co/?s=s-HGgiKceXmHZ4qCvcMiyyX4QmKkPnhv

Expected behavior A clear and concise description of what you expected to happen.

Additional context

tolgaOzen commented 3 weeks ago

Hello @xXAvoraXx ,

To address recursive operations when referencing the same entity at higher levels, you can set up the permission like this:

permission shared_permission_access = (shared_permission.role_member and can_shared_access) or shared_permission.shared_permission_access

This approach will include itself as intended. For recursive operations with the same entity, this document should be helpful: Permify Recursive REBAC Documentation. I hope this meets your needs!

validation file:

schema: |-
    entity user {}

    entity role {
        relation member @user
        relation shared_from @permission_share

        permission can_shared_access = shared_from.can_access
        permission can_access = member
    }

    entity perm {
        relation direct_access @role
        relation shared_access @permission_share

        permission can_shared_access = shared_access.can_access and direct_access.can_shared_access
        permission can_access = direct_access.can_access or can_shared_access
    }

    entity permission_share {
        relation shared_access @role
        relation shared_permission @permission_share

        permission can_shared_access = shared_access.can_shared_access
        permission role_member = shared_access.member
        permission shared_permission_access = (shared_permission.role_member and can_shared_access) or shared_permission.shared_permission_access
        permission can_access = role_member or shared_permission_access
    }

relationships:

  - perm:action1#direct_access@role:supervisor
  - perm:action1#shared_access@permission_share:role/supervisor/action/action1

  - permission_share:role/supervisor/action/action1#shared_access@role:admin
  - permission_share:role/supervisor/action/action1#shared_permission@permission_share:role/admin/action/action1

  - permission_share:role/admin/action/action1#shared_access@role:mod
  - permission_share:role/admin/action/action1#shared_permission@permission_share:role/mod/action/action1

  - permission_share:role/mod/action/action1#shared_access@role:editor
  - permission_share:role/mod/action/action1#shared_permission@permission_share:role/editor/action/action1

  - permission_share:role/editor/action/action1#shared_access@role:writer
  - permission_share:role/editor/action/action1#shared_permission@permission_share:role/writer/action/action1

  - role:supervisor#member@user:supervisor
  - role:supervisor#shared_from@permission_share:role/supervisor/action/action1

  - role:admin#member@user:admin
  - role:admin#shared_from@permission_share:role/admin/action/action1

  - role:mod#member@user:mod
  - role:mod#shared_from@permission_share:role/mod/action/action1

  - role:editor#member@user:editor
  - role:editor#shared_from@permission_share:role/editor/action/action1

  - role:writer#member@user:writer
  - role:writer#shared_from@permission_share:role/writer/action/action1

attributes: []

scenarios:
  - name: Test
    checks:
      - entity: perm:action1
        subject: user:supervisor
        assertions:
          can_access: true
      - entity: perm:action1
        subject: user:admin
        assertions:
          can_access: true
      - entity: perm:action1
        subject: user:mod
        assertions:
          can_access: true
      - entity: perm:action1
        subject: user:editor
        assertions:
          can_access: true
xXAvoraXx commented 3 weeks ago

Thank you for your response. I missed this part, my mistake.

permission shared_permission_access = (shared_permission.role_member and can_shared_access) or shared_permission.shared_permission_access