Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 rbac: Issue with Conditional Access for catalog-entity Resource #2957

Open
2 tasks done
zeshanziya opened this issue Feb 20, 2025 · 4 comments
Open
2 tasks done
Labels
bug Something isn't working workspace/rbac

Comments

@zeshanziya
Copy link

Workspace

rbac

📜 Description

I was setting up the RBAC plugin for Backstage, but it is not working as expected with one of the plugins that use catalog-entity as the resource type for permission.

Here is how the permission is declared:

import { RESOURCE_TYPE_CATALOG_ENTITY } from '@backstage/plugin-catalog-common/alpha';

export const platformshEnvironmentManagePermission = createPermission({
  name: 'platformsh.environment.manage',
  attributes: { },
  resourceType: RESOURCE_TYPE_CATALOG_ENTITY,
});

Previously, we checked for access in our permission policy like this:

if (
      isPermission(request.permission, platformshEnvironmentManagePermission)
    ) {
      return createCatalogConditionalDecision(
        request.permission,
        catalogConditions.isEntityOwner({
          claims: user?.info.ownershipEntityRefs ?? [],
        }),
      );
    }

This worked as expected.

After migrating to the RBAC plugin, I set up the permission in rbac-policy.csv as follows:

p, role:default/default_policy, platformsh.environment.manage, use, allow

I also added a conditional policy in conditional-policies.yaml:

---
result: CONDITIONAL
roleEntityRef: 'role:default/default_policy'
pluginId: platformsh
resourceType: catalog-entity
permissionMapping:
  - use
conditions:
  rule: IS_ENTITY_OWNER
  resourceType: catalog-entity
  params:
    claims:
      - '$ownerRefs'

However, it always results in DENY, even when the user should have access.

👍 Expected behavior

The RBAC plugin should allow access to users who meet the IS_ENTITY_OWNER condition for a catalog-entity resource.

Am I missing something? Or is there another way to use catalog-entity resource permissions in a custom plugin?

👎 Actual Behavior with Screenshots

Even when a user is the owner of the catalog-entity, the RBAC plugin always denies access.

👟 Reproduction steps

NA

📃 Provide the context for the Bug.

Screenshot of conditional policies in db

Image

This is what I see in the log

[backend]: 2025-02-20T02:11:29.054Z permission info Policy check for user:default/axlzeetest1 actor=[object Object] meta=[object Object] request=undefined isAuditLog=true response=undefined eventName=PermissionEvaluationStarted stage=evaluatePermissionAccess status=succeeded
[backend]: 2025-02-20T02:11:29.071Z permission info Send condition to plugin with id platformsh to evaluate permission platformsh.environment.manage with resource type catalog-entity and action use for user user:default/axlzeetest1 actor=[object Object] meta=[object Object] request=undefined isAuditLog=true response=undefined eventName=ConditionEvaluationCompleted stage=evaluatePermissionAccess status=succeeded

👀 Have you spent some time to check if this bug has been raised before?

  • I checked and didn't find similar issue

🏢 Have you read the Code of Conduct?

Are you willing to submit PR?

Yes I am willing to submit a PR!

@zeshanziya zeshanziya added the bug Something isn't working label Feb 20, 2025
@PatAKnight
Copy link
Contributor

So, what is currently happening, is whenever you set the pluginId to platformsh the RBAC plugin will send the conditional rule and the required resources to the plugin platformsh to evaluate and if your plugin does not implement any conditional rules of its own, then it will return a conditional result of deny. I believe that the pluginId should instead be catalog to ensure that the catalog properly evaluates the IS_ENTITY_OWNER rule.

I assume what you are trying to do is only show catalog entities to the user if they own them and then allow them access to the plugin from the catalog entity page.

This should be accomplished with the following:

rbac-policy.csv (no changes here)

g, user:default/some-user-here, role:default/your-role-here
p, role:default/your-role-here, platformsh.environment.manage, use, allow

conditional-policies.yaml (updated the pluginId and permissionMapping)

result: CONDITIONAL
roleEntityRef: 'role:default/your-role-here'
pluginId: catalog
resourceType: catalog-entity
permissionMapping:
  - read
conditions:
  rule: IS_ENTITY_OWNER
  resourceType: catalog-entity
  params:
    claims:
      - '$ownerRefs'

This combination should only let the user access their catalog entities and then let them access the plugins resources from the catalog entity page.

@zeshanziya
Copy link
Author

Thank @PatAKnight for quick review. The issue is that if we set the conditional rule for the read permission, users can only access entities they own. However, we don't want that. Users should be able to access all entities, but they should only be able to perform certain actions if they own the entity.

we have similar permissions using the catalog-entity resource type across multiple plugins, each with different permission names and rules.

@PatAKnight
Copy link
Contributor

Ah, I understand what you are trying to do. Yeah, unfortunately, that is a limitation of the plugin at the moment. Those incredibly fine grain permissions that can be set up through a coded approach give a lot more flexibility versus our no code approach.

At the moment, there are only a couple of things that I can think of to potentially solve your use case. The first would be to create conditional rules for your plugin. This way, you can check if they are an owner and then perform the action. This would give you the most flexibility as you can easily add more permissions and rules as your uses cases expand.

Another option that I have had somewhat success with is utilizing the catalog conditional rules within another plugin. This allows you to reuse rules that have already been defined but with the drawback of needing to rely more heavily on the catalog. In this case you can then filter based on whether or not the user is an owner.

I believe that this is the plugin in question. You are already filtering right before the authorize call. What you could potentially do instead is something along the lines of:

import {
  createConditionTransformer,
  createPermissionIntegrationRouter,
} from '@backstage/plugin-permission-node';


// Where tranformConditions gets the filter that you wish to use
  const transformConditions = createConditionTransformer(
    createConditionTransformer(THE_DECIDED_UPON_RULE_SET)
  );

  router.post(
    '/project/:id/environments',
    async (
  // ...

      const credentials = await httpAuth.credentials(req, { allow: ['user'] });
      const decision = (
        await permissions.authorizeConditional(
          [{  permission: platformshEnvironmentManagePermission  }],
          { credentials },
        )
      )[0];

      if (decision.result === AuthorizeResult.DENY) {
        throw new NotAllowedError('Unauthorized');
      }

      if (decision.result === Authorize.CONDITIONAL) {
        const filter = transformConditions(decision.conditions);
      }

      const entity = await findEntityByProjectId(
        catalogApi,
        req.params.id,
        filter, // Update findEntityByProjectId to now accept a filter
        token,
      );

      if (!entity) {
        throw new Error(
          'No matching entity found for given platformsh project.',
        );
      }

This would just rework it so that you check for any additional filters, IS_ENTITY_OWNER, and then apply those whenever retrieving the list of entities.

As mentioned, when using the catalog plugin's rules, I have had somewhat success. I am able to get the filter that I am looking for. I just haven't been able to wire everything up at the moment, because I don't have a plugin that can utilize the filter. I also have not been able to confirm if the original permission framework correctly applies the old coded approach either.

@zeshanziya
Copy link
Author

Thanks @PatAKnight for detailed instructions. I will give it a try.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working workspace/rbac
Projects
None yet
Development

No branches or pull requests

3 participants