WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@adamruzicka
Copy link
Contributor

@adamruzicka adamruzicka commented Aug 15, 2025

I might be away from work for a couple of weeks, so I'm opening this as a draft for the time being to remember what I wanted to do here and hopefully spark some discussion in the meantime.

TL; DR

If a role has organizations or locations assigned, the permissions granted by that role apply only in the context of those organizations/locations.

"Steps to reproduce"-styled example

  1. Create organization Allowed
  2. Create organization Forbidden
  3. Clone the Organization admin role into Allowed Organization admin and assign the clone to organization Allowed
  4. Create a user
    1. Assign it to both organizations
    2. Assign the role to it
  5. Create a subnet an assign it to organization Forbidden
  6. Log in as the user

Behaviour before the changes:

  1. The user can freely pick both organizations
  2. The user sees the Infrastructure > Subnets menu item in both organizations (and any)
  3. The user can go to Infrastructure > Subnets in both organizations (and any)
  4. The user doesn't see any subnets, because the "second level" inside the page filters out the subnet in the forbidden organization

Behaviour after the changes:

  1. The user can freely pick both organizations
  2. The user sees the Infrastructure > Subnets menu item in organization Allowed and in any
    1. The user does not see the menu item in Forbidden organization
  3. The user can go to Infrastructure > Subnets in in organization Allowed and in any
    1. When navigating to /subnets in Forbidden organization, the user gets an error page stating that the user does not have view_subnets permission in the current organization and location scope

Background

Foreman comes with a RBAC system that can be leveraged to have fine-grained control over which actions can be performed by users. The essential model is that individual permissions are linked to roles, users are assigned to roles and users are granted permissions through their roles.

Roles can be assigned to organizations and locations. There is an assumption that if a role is assigned to a taxonomy (organization or location) it applies only in the scope of that taxonomy - a clone of Organization admin role assigned to organization Allowed should grant permissions over the entirety of the Allowed organization, but not outside of it. This is supported by documentation. This holds, as long as the user is assigned to the same and no other organization.

Users, same as Roles, can be assigned to organizations and locations too. Problems (or at least undefined behaviour) arise when there is a mismatch between the taxonomies of the User and the taxonomies of the User's roles.

The permissions are enforced at two different levels. In layman's terms, one is when accessing pages, the other is about what gets shown inside those pages.

The tricky thing here is that the page-access level is not taxonomy-aware, the check is really just "does the user have the required permission, through any of their roles?".

In the model sitatuion outlined above, the expectation people seem to have is that in this case, the user should not be able to do anything in organization Forbidden. The user probably should still have an option to select both organizations in the organization picker, after all, they're still a member of both of them, but they shouldn't be able to navigate to any pages there. What really happens is that the user can go to pages in organization Forbidden, but then the second level should kick in and filter out the things the user is not allowed to see - in this case, they shouldn't see anything.

Changes introduced here

In this PR, I'm adding a set of helpers to make the page-access level checks taxonomy-aware and switching over to them. This affects what menu items show in the navigation as well as enforcing those permissions more strictly when accessing pages.

The taxonomy-awareness is implemented in a relatively straightforward way. Roles without taxonomies grant their permissions globally, roles with taxonomies grant them only within those taxonomies. When the permission checks are done, the role's taxonomies are taken into consideration and compared against current taxonomies. In here I deliberately chose to ignore taxonomy inheritance - if a role is expected to grant permissions in a child organization, it should be assigned to the child organization directly.

Note:
This soft-depends on #10370 . That PR removes one case that would otherwise have to be covered as well - without that PR, individual filters can be configured to override organization and location scoping configured on the role.

But why?

  1. The new behaviour seems to be more in-line with what people intuitively expect.
  2. The current two-level does not cover all cases
    1. In some cases, the in-page level does not support taxonomy-based filtering and while those cases could be fixed on their own, it felt better to address this at a more fundamental level

TODOs

  • put together an RFC on discourse and ideally present this at the community demo ahead of time
  • check how this plays with plugins, especially katello

Open questions

  • instead of new helpers and gradual roll-out with explicit changes, should we just change what the old helpers do?

Copy link
Contributor

@adamlazik1 adamlazik1 left a comment

Choose a reason for hiding this comment

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

I tried but haven't been able to break it, appears to work as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants