rpt-permissions

Mcafee123's avatarfrom Mcafee123

Configure RPT token exchange and permission-based authorization for affolterNET.Web.Bff. Use when setting up Keycloak permissions, resource policies, or fine-grained access control.

⭐0stars🔀0forks📁View on GitHub🕐Updated Jan 8, 2026

When & Why to Use This Skill

This Claude skill facilitates the implementation of fine-grained access control (FGAC) by configuring RPT (Requesting Party Token) exchange and permission-based authorization for affolterNET.Web.Bff. It bridges the gap between Keycloak identity management and .NET backend security, ensuring robust resource protection through policy-based authorization, efficient token caching, and seamless integration between the BFF and modern SPAs.

Use Cases

  • Case 1: Implementing fine-grained authorization in .NET applications using Keycloak RPT tokens to secure specific API resources.
  • Case 2: Configuring complex resource policies, scopes, and permissions within Keycloak for enterprise-grade access management.
  • Case 3: Developing permission-aware frontend components in frameworks like Vue.js that dynamically react to RPT-based claims.
  • Case 4: Troubleshooting RPT token exchange failures and optimizing permission caching to balance security with application performance.
namerpt-permissions
descriptionConfigure RPT token exchange and permission-based authorization for affolterNET.Web.Bff. Use when setting up Keycloak permissions, resource policies, or fine-grained access control.

RPT Permissions

Configure Keycloak RPT-based permission authorization.

For complete reference, see Library Guide.

Overview

RPT (Requesting Party Token) enables fine-grained permissions:

  1. User authenticates and gets access token
  2. BFF exchanges access token for RPT
  3. RPT contains granted permissions
  4. Controllers authorize based on permissions

Quick Start

Enable Authorization Mode

var options = builder.Services.AddBffServices(isDev, config, opts => {
    opts.ConfigureBff = bff => {
        bff.AuthMode = AuthenticationMode.Authorize;
    };
});

Use Permission Policies

[Authorize(Policy = "admin-resource")]
[HttpGet("admin")]
public IActionResult AdminOnly() => Ok();

// Multiple permissions (any match)
[Authorize(Policy = "admin-resource,manager-resource")]
[HttpGet("management")]
public IActionResult Management() => Ok();

Keycloak Configuration

Resource Setup

  1. Enable "Authorization" on your client
  2. Create Resources (e.g., "admin-resource", "user-resource")
  3. Create Scopes (e.g., "view", "manage", "create")
  4. Create Policies (role-based, user-based, etc.)
  5. Create Permissions linking policies to resources/scopes

Permission Structure

{
  "permissions": [
    {
      "rsname": "admin-resource",
      "scopes": ["view", "manage"]
    },
    {
      "rsname": "user-resource",
      "scopes": ["read", "create"]
    }
  ]
}

Permission Checking in Code

// Single permission
[RequirePermission("admin-resource:view")]
public IActionResult AdminView() { ... }

// Multiple permissions (any match)
[RequirePermission("admin-resource:manage", "user-resource:delete")]
public IActionResult AdminManage() { ... }

Using Authorize Policy (Alternative)

// Single permission
[Authorize(Policy = "admin-resource:view")]
public IActionResult AdminView() { ... }

// Multiple permissions (comma-separated)
[Authorize(Policy = "admin-resource:manage,user-resource:delete")]
public IActionResult AdminManage() { ... }

Note: RequirePermission is a convenience wrapper that sets the Policy internally.

Programmatic Check

public class MyController : ControllerBase
{
    public IActionResult ConditionalAction()
    {
        var permissions = User.FindAll("permission")
            .Select(c => c.Value);

        if (permissions.Contains("admin-resource:manage"))
        {
            // Admin-specific logic
        }

        return Ok();
    }
}

SPA Permission Checking

// Auth store
const useAuthStore = defineStore('auth', {
    state: () => ({
        permissions: [] as { resource: string; action: string }[]
    }),
    actions: {
        hasPermission(resource: string, action: string): boolean {
            return this.permissions.some(
                p => p.resource === resource && p.action === action
            );
        }
    }
});

// Component usage
<template>
    <button v-if="authStore.hasPermission('admin-resource', 'manage')">
        Admin Action
    </button>
</template>

Permission Claims Format

When the RPT middleware processes permissions, it adds claims to the user identity:

Property Value
Claim Type "permission"
Claim Value "{resource}:{scope}"

Examples: "admin-resource:view", "user-resource:create"

Caching

RPT tokens are cached per user to avoid repeated Keycloak calls:

{
  "affolterNET": {
    "Web": {
      "PermissionCache": {
        "ExpirationMinutes": 5
      }
    }
  }
}

Troubleshooting

Permissions not recognized

  • Verify AuthMode is Authorize
  • Check Keycloak client has Authorization enabled
  • Ensure resources/permissions are configured
  • Review RPT token contents in jwt.io

Permission denied unexpectedly

  • Check policy evaluation in Keycloak
  • Verify user has required role for policy
  • Review permission-to-policy mappings

RPT exchange fails

  • Verify client credentials are correct
  • Check Keycloak authorization services are enabled
  • Review Keycloak logs for errors