community-plugins icon indicating copy to clipboard operation
community-plugins copied to clipboard

🚀 RBAC: Add `defaultPermissions` support to RBAC CSV configuration

Open spencer-steed opened this issue 3 months ago • 3 comments

Workspace

rbac

🔖 Feature description

Add support for a defaultPermissions section in the RBAC CSV configuration that automatically applies foundational permissions to any authenticated user without requiring individual role assignments.

🎤 Context

The RBAC plugin currently requires explicit role assignment for every user or group to receive permissions. For large organizations, this creates a significant administrative burden when you want to provide baseline permissions to all authenticated users.

Currently, to provide baseline permissions to all users in a Backstage instance, you must:

  1. Create a group containing all users, or
  2. Use the admin users configuration (which grants unlimited access), or
  3. Manually assign every individual user to a role

For organizations with large user bases, none of these approaches are scalable or maintainable:

  • Group-based approach: Requires maintaining group membership for every user
  • Admin Users: Provides unlimited access, which is too permissive for baseline permissions
  • Individual assignment: Not feasible for large user counts

Use Case Example: All authenticated users should be able to:

  • Read catalog entities (components, systems, APIs)
  • View software templates
  • Browse the scaffolder template catalog
  • Browse Techdocs Documentation

But NOT be able to:

  • Execute scaffolder actions (create new projects)
  • Modify catalog entities (delete mainly)
  • Manage RBAC policies

Current Implementation Required:

# Must create a role for basic permissions
p, role:default/authenticated_users, catalog-entity, read, allow
p, role:default/authenticated_users, scaffolder.template.parameter.read, read, allow

# Must assign ALL users to this role (many assignments for large orgs)
g, user:default/alice, role:default/authenticated_users
g, user:default/bob, role:default/authenticated_users
g, user:default/charlie, role:default/authenticated_users
# ... potentially hundreds or thousands more lines

✌️ Possible Implementation

The defaultPermissions feature can be implemented by extending the existing CSV parser and permission policy evaluation logic in the RBAC backend.

Key Implementation Points:

  1. CSV Parser Enhancement - Modify the CSVFileWatcher class in csv-file-watcher.ts to recognize and handle defaultPermissions entries:

    • Extend the parse() method to detect lines starting with defaultPermissions
    • Store default permissions separately from role-based permissions during CSV processing
  2. Permission Policy Integration - Enhance the RBACPermissionPolicy.handle() method in permission-policy.ts:

    • Add default permission evaluation as the final fallback in the permission hierarchy
    • Check default permissions only after user-specific and role-based permissions have been evaluated
  3. Enforcer Delegate Enhancement - Extend the EnforcerDelegate class in enforcer-delegate.ts to manage default permissions:

    • Add methods to store and retrieve default permissions separately from Casbin's standard policy storage
    • Implement default permission lookup that doesn't interfere with existing role-based evaluations

Code Changes Required:

// In csv-file-watcher.ts - Add default permissions parsing
async findFileContentDiff() {
  // Existing logic...
  
  // New: Handle defaultPermissions entries
  if (convertedPolicy[0] === 'defaultPermissions') {
    convertedPolicy.splice(0, 1);
    this.csvFilePolicies.addedDefaultPermissions.push(convertedPolicy);
  }
}

// In permission-policy.ts - Add default permission evaluation
async handle(request: PolicyQuery, user?: PolicyQueryUser): Promise<PolicyDecision> {
  // Existing permission checks...
  
  // New: Check default permissions as final fallback
  if (await this.hasDefaultPermission(permissionName, action)) {
    return { result: AuthorizeResult.ALLOW };
  }
  
  return { result: AuthorizeResult.DENY };
}

Configuration Integration:

The implementation should work seamlessly with existing CSV configuration:

Permission Evaluation Order:

  1. Admin Users check (existing)
  2. Explicit user policies (existing)
  3. Group/role policies (existing)
  4. Default permissions (new) ← Lowest priority fallback
  5. Deny by default (existing)

This approach maintains full backward compatibility while providing the scalable default permissions capability needed for large organizations.

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

  • [x] 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!

spencer-steed avatar Sep 17 '25 19:09 spencer-steed

cc: @PatAKnight @AndrienkoAleksandr

04kash avatar Sep 23 '25 14:09 04kash

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

github-actions[bot] avatar Nov 22 '25 18:11 github-actions[bot]

Adding do not stale label since this is an important feature request with contributed implementations:

  • https://github.com/backstage/community-plugins/pull/3521
  • https://github.com/backstage/community-plugins/pull/390
  • https://github.com/backstage/community-plugins/pull/4350

dzemanov avatar Nov 24 '25 16:11 dzemanov