ronnythedev/dotnet-clean-architecture-skills/13-dotnet-permission-authorization

Claude Code and agent skill by ronnythedev/dotnet-clean-architecture-skills

Trust tier 2
  • community
LLM review pending
Source check pending

Checking that the SKILL.md file is still in the repository.

Implements permission-based authorization with custom attributes, policy providers, and authorization handlers. Provides granular access control beyond simple role-based authorization.

Install

npx vskill@latest install ronnythedev/dotnet-clean-architecture-skills/13-dotnet-permission-authorization

SKILL.md

Permission-Based Authorization Setup

Overview

This skill implements fine-grained permission-based authorization:

  • Custom [HasPermission] attribute - Declarative permission requirements
  • Policy provider - Dynamically creates policies from permissions
  • Authorization handler - Validates user permissions
  • Claims transformation - Converts roles to permissions

Quick Reference

ComponentPurpose
PermissionsStatic permission constants
RolesStatic role constants
HasPermissionAttributeCustom authorize attribute
PermissionAuthorizationHandlerValidates permissions
PermissionAuthorizationPolicyProviderCreates policies dynamically
RoleToPermissionClaimsTransformationMaps roles to permissions

Authorization Structure

/Infrastructure/Authorization/
├── Permissions.cs
├── Roles.cs
├── HasPermissionAttribute.cs
├── PermissionRequirement.cs
├── PermissionAuthorizationHandler.cs
├── PermissionAuthorizationPolicyProvider.cs
├── RoleToPermissionClaimsTransformation.cs
└── AuthorizationExtensions.cs

Template: Permissions Definition

csharp
// src/{name}.infrastructure/Authorization/Permissions.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// All available permissions in the system
/// Format: {resource}:{action}
/// </summary>
public static class Permissions
{
// ═══════════════════════════════════════════════════════════════
// ORGANIZATION PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string OrganizationsRead = "organizations:read";
public const string OrganizationsWrite = "organizations:write";
public const string OrganizationsDelete = "organizations:delete";
public const string OrganizationsManageSettings = "organizations:manage_settings";
// ═══════════════════════════════════════════════════════════════
// USER PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string UsersRead = "users:read";
public const string UsersWrite = "users:write";
public const string UsersDelete = "users:delete";
public const string UsersManageRoles = "users:manage_roles";
// ═══════════════════════════════════════════════════════════════
// DEPARTMENT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string DepartmentsRead = "departments:read";
public const string DepartmentsWrite = "departments:write";
public const string DepartmentsDelete = "departments:delete";
// ═══════════════════════════════════════════════════════════════
// ASSESSMENT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string AssessmentsRead = "assessments:read";
public const string AssessmentsWrite = "assessments:write";
public const string AssessmentsSubmit = "assessments:submit";
public const string AssessmentsReview = "assessments:review";
// ═══════════════════════════════════════════════════════════════
// REPORT PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string ReportsRead = "reports:read";
public const string ReportsExport = "reports:export";
public const string ReportsViewSensitive = "reports:view_sensitive";
// ═══════════════════════════════════════════════════════════════
// ADMIN PERMISSIONS
// ═══════════════════════════════════════════════════════════════
public const string AdminAccess = "admin:access";
public const string AdminManageSystem = "admin:manage_system";
}

Template: Roles Definition

csharp
// src/{name}.infrastructure/Authorization/Roles.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// All available roles in the system
/// </summary>
public static class Roles
{
public const string SuperAdmin = "SuperAdmin";
public const string Admin = "Admin";
public const string Consultant = "Consultant";
public const string Manager = "Manager";
public const string Associate = "Associate";
public const string Viewer = "Viewer";
}

Template: Role-Permission Mapping

csharp
// src/{name}.infrastructure/Authorization/RolePermissions.cs
namespace {name}.infrastructure.authorization;
/// <summary>
/// Maps roles to their granted permissions
/// </summary>
public static class RolePermissions
{
private static readonly Dictionary<string, HashSet<string>> RolePermissionMap = new()
{
// ═══════════════════════════════════════════════════════════════
// SUPER ADMIN - Full system access
// ═══════════════════════════════════════════════════════════════
[Roles.SuperAdmin] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.OrganizationsWrite,
Permissions.OrganizationsDelete,
Permissions.OrganizationsManageSettings,
Permissions.UsersRead,
Permissions.UsersWrite,
Permissions.UsersDelete,
Permissions.UsersManageRoles,
Permissions.DepartmentsRead,
Permissions.DepartmentsWrite,
Permissions.DepartmentsDelete,
Permissions.AssessmentsRead,
Permissions.AssessmentsWrite,
Permissions.AssessmentsSubmit,
Permissions.AssessmentsReview,
Permissions.ReportsRead,
Permissions.ReportsExport,
Permissions.ReportsViewSensitive,
Permissions.AdminAccess,
Permissions.AdminManageSystem
},
// ═══════════════════════════════════════════════════════════════
// ADMIN - Organization-level admin
// ═══════════════════════════════════════════════════════════════
[Roles.Admin] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.OrganizationsWrite,
Permissions.OrganizationsManageSettings,
Permissions.UsersRead,
Permissions.UsersWrite,
Permissions.UsersManageRoles,
Permissions.DepartmentsRead,
Permissions.DepartmentsWrite,
Permissions.DepartmentsDelete,
Permissions.AssessmentsRead,
Permissions.AssessmentsWrite,
Permissions.AssessmentsReview,
Permissions.ReportsRead,
Permissions.ReportsExport,
Permissions.ReportsViewSensitive,
Permissions.AdminAccess
},
// ═══════════════════════════════════════════════════════════════
// CONSULTANT - External consultants
// ═══════════════════════════════════════════════════════════════
[Roles.Consultant] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.UsersRead,
Permissions.DepartmentsRead,
Permissions.AssessmentsRead,
Permissions.AssessmentsReview,
Permissions.ReportsRead,
Permissions.ReportsExport
},
// ═══════════════════════════════════════════════════════════════
// MANAGER - Department managers
// ═══════════════════════════════════════════════════════════════
[Roles.Manager] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.UsersRead,
Permissions.DepartmentsRead,
Permissions.DepartmentsWrite,
Permissions.AssessmentsRead,
Permissions.AssessmentsWrite,
Permissions.AssessmentsSubmit,
Permissions.AssessmentsReview,
Permissions.ReportsRead
},
// ═══════════════════════════════════════════════════════════════
// ASSOCIATE - Regular employees
// ═══════════════════════════════════════════════════════════════
[Roles.Associate] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.UsersRead,
Permissions.DepartmentsRead,
Permissions.AssessmentsRead,
Permissions.AssessmentsSubmit
},
// ═══════════════════════════════════════════════════════════════
// VIEWER - Read-only access
// ═══════════════════════════════════════════════════════════════
[Roles.Viewer] = new HashSet<string>
{
Permissions.OrganizationsRead,
Permissions.DepartmentsRead,
Permissions.AssessmentsRead,
Permissions.ReportsRead
}
};
/// <summary>
/// Gets all permissions for a role
/// </summary>
public static IReadOnlySet<string> GetPermissionsForRole(string role)
{
return RolePermissionMap.TryGetValue(role, out var permissions)
? permissions
: new HashSet<string>();
}
/// <summary>
/// Gets all permissions for multiple roles
/// </summary>
public static IReadOnlySet<string> GetPermissionsForRoles(IEnumerable<string> roles)
{
var allPermissions = new HashSet<string>();
foreach (var role in roles)
{
var permissions = GetPermissionsForRole(role);
allPermissions.UnionWith(permissions);
}
return allPermissions;
}
/// <summary>
/// Checks if a role has a specific permission
/// </summary>
public static bool HasPermission(string role, string permission)
{
return RolePermissionMap.TryGetValue(role, out var permissions)
&& permissions.Contains(permission);
}
}

Template: HasPermission Attribute

csharp
// src/{name}.infrastructure/Authorization/HasPermissionAttribute.cs
using Microsoft.AspNetCore.Authorization;
namespace {name}.infrastructure.authorization;
/// <summary>
/// Custom authorization attribute that requires a specific permission
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public sealed class HasPermissionAttribute : AuthorizeAttribute
{
public HasPermissionAttribute(string permission)
: base(policy: permission)
{
}
}

Template: Permission Requirement

csharp
// src/{name}.infrastructure/Authorization/PermissionRequirement.cs
using Microsoft.AspNetCore.Authorization;
namespace {name}.infrastructure.authorization;
/// <summary>
/// Authorization requirement for a specific permission
/// </summary>
public sealed class PermissionRequirement : IAuthorizationRequirement
{
public string Permission { get; }
public PermissionRequirement(string permission)
{
Permission = permission;
}
}

Template: Permission Authorization Handler

csharp
// src/{name}.infrastructure/Authorization/PermissionAuthorizationHandler.cs
using System.Security.Claims;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
namespace {name}.infrastructure.authorization;
/// <summary>
/// Handles permission-based authorization requirements
/// </summary>
internal sealed class PermissionAuthorizationHandler
: AuthorizationHandler<PermissionRequirement>
{
private readonly ILogger<PermissionAuthorizationHandler> _logger;
public PermissionAuthorizationHandler(
ILogger<PermissionAuthorizationHandler> logger)
{
_logger = logger;
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
PermissionRequirement requirement)
{
// Get permissions from claims (added by claims transformation)
var permissions = context.User
.FindAll("permission")
.Select(c => c.Value)
.ToHashSet();

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewNot runA model review is scheduled for the next rescan.

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
64
Repository forks
11
7-day trend score
21

Stars and forks are for the whole GitHub repository, not this skill alone. Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/ronnythedev/dotnet-clean-architecture-skills/13-dotnet-permission-authorization/badge)](https://verified-skill.com/skills/ronnythedev/dotnet-clean-architecture-skills/13-dotnet-permission-authorization)

Something wrong with this skill or its page? Tell us.