{"id":19380709,"url":"https://github.com/f1x3d/pbac.aspnetcore","last_synced_at":"2025-12-25T04:05:10.965Z","repository":{"id":181643353,"uuid":"667063060","full_name":"f1x3d/Pbac.AspNetCore","owner":"f1x3d","description":"A helper library for implementing the permission/attribute based access control (ABAC) with JSON web tokens using the ASP.NET Core's policy-based access control (PBAC)","archived":false,"fork":false,"pushed_at":"2024-09-08T12:38:38.000Z","size":39,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-19T07:24:35.405Z","etag":null,"topics":["abac","access","aspnet","aspnetcore","auth","authorization","csharp","dotnet","dotnet-core","jwt","pbac","permissions","ukrainian"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/f1x3d.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-16T14:18:14.000Z","updated_at":"2025-08-18T01:46:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"b8509e72-1a0c-4ded-aeca-aa073be2ea56","html_url":"https://github.com/f1x3d/Pbac.AspNetCore","commit_stats":null,"previous_names":["f1x3d/pbac.aspnetcore"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/f1x3d/Pbac.AspNetCore","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f1x3d%2FPbac.AspNetCore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f1x3d%2FPbac.AspNetCore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f1x3d%2FPbac.AspNetCore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f1x3d%2FPbac.AspNetCore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/f1x3d","download_url":"https://codeload.github.com/f1x3d/Pbac.AspNetCore/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/f1x3d%2FPbac.AspNetCore/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274934915,"owners_count":25376754,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-13T02:00:10.085Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abac","access","aspnet","aspnetcore","auth","authorization","csharp","dotnet","dotnet-core","jwt","pbac","permissions","ukrainian"],"created_at":"2024-11-10T09:14:36.861Z","updated_at":"2025-12-25T04:05:05.918Z","avatar_url":"https://github.com/f1x3d.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"﻿# Pbac.AspNetCore\n\n[![NuGet](https://img.shields.io/nuget/v/Pbac.AspNetCore?logo=nuget\u0026label=NuGet)](https://nuget.org/packages/Pbac.AspNetCore)\n\n## Description\n\nA helper library for implementing the [permission/attribute based access control (ABAC)](https://en.wikipedia.org/wiki/Attribute-based_access_control) with [JSON web tokens](https://en.wikipedia.org/wiki/JSON_Web_Token) using the ASP.NET Core's [policy-based access control (PBAC)](https://learn.microsoft.com/en-us/aspnet/core/security/authorization/policies).\n\n* Scalable \u0026 compact - when converting a permission list to a string, it encodes 4 permissions in a single character ([see the implementation details below](#implementation)). This allows you to store [up to 1,024 permissions](https://learn.microsoft.com/en-us/graph/api/resources/extensionproperty?view=graph-rest-1.0#properties) in a single JWT claim in Azure AD B2C, for example.\n* Performant and has low memory allocations ([see the benchmarks below](#benchmarks))\n\n## Usage\n\n1. Create the permissions enum:\n    ```csharp\n    public enum Permissions\n    {\n        Create = 0,\n        Read = 1,\n        Update = 2,\n        Delete = 3,\n    }\n    ```\n\n    Note that having the exact underlying value for each permission is important - messing it up will mess the permissions stored!\n\n    Also, only enums with the `int` as an underlying type (the default) are currently supported.\n\n1. Set the user permission values inside your identity provider using the `PermissionSet`:\n    ```csharp\n    user.Claims[ClaimNames.Permissions] = new PermissionSet\u003cPermissions\u003e(new[]\n        {\n            Permissions.Create,\n            Permissions.Read,\n        })\n        .ToCompactString();\n    ```\n\n1. Add the permission policy requirement handler with the same claim name as above:\n    ```csharp\n    services.AddPermissionBasedAuthorization\u003cPermissions\u003e(options =\u003e\n        options.PermissionsClaimName = ClaimNames.Permissions);\n    ```\n\n    Note that if you re-define the authorization `DefaultPolicy` in your app then the code above should be inserted after your logic to make the permission policies inherit the new default policy.\n\n1. (Optionally) Inherit the `AuthorizePermission\u003cT\u003e` with the specific permissions enum type:\n    ```csharp\n    public class AuthorizePermissionAttribute : AuthorizePermissionAttribute\u003cPermissions\u003e\n    {\n        public AuthorizePermissionAttribute(Permissions permission)\n            : base(permission)\n        { }\n    }\n    ```\n\n    Or create an extension method if using the Minimal APIs:\n    ```csharp\n    public static TBuilder RequirePermission\u003cTBuilder\u003e(this TBuilder builder, Permissions permission)\n        where TBuilder : IEndpointConventionBuilder\n    {\n        if (builder == null)\n            throw new ArgumentNullException(nameof(builder));\n\n        return builder.RequireAuthorization(new AuthorizePermissionAttribute\u003cPermissions\u003e(permission));\n    }\n    ```\n\n1. Decorate the controllers/endpoints with the `AuthorizePermission\u003cT\u003e` (or the one created above) attribute:\n    ```csharp\n    [HttpGet]\n    [Authorize(Permissions.Read)]\n    public IActionResult Get()\n        =\u003e Ok();\n    ```\n\n    Or if using the minimal APIs:\n    ```csharp\n    app.MapGet(\"/\", () =\u003e Results.Ok())\n    .RequirePermission(Permissions.Read);\n    ```\n\n## Implementation\n\nThe permission set is being serialized into a string as a hex number where _N_-th bit represents the presence of a permission with the underlying value of _N_.\n\nFor example, consider the following permission enum:\n\n```\npublic enum Permissions\n{\n    Create = 0,\n    Read = 1,\n    Update = 2,\n    Delete = 3,\n    Manage = 4,\n}\n```\n\nThen, the binary representation of a set containing all permissions above would look like this:\n\n```\n   1    F - permission string\n┌┬┬┤ ┌┬┬┤\n0001 1111 - permission bit values\n││││ ││││\n7654 3210 - bit positions\n└┬┘│ ││││\n │ │ │││└ Create\n │ │ ││└ Read\n │ │ │└ Update\n │ │ └ Delete\n │ └ Manage\n └ Not used\n```\n\nFor deserialization, the above is done in the reversed order.\n\nAlso, because based on the enum value we can calculate the specific bit position we need to check, we don't need to deserialize the entire string when we verify a single permission.\n\n## Benchmarks\n\n* Checking a single permission value from the compact string:\n\n    |                      Method |     Mean |    Error |   StdDev | Allocated |\n    |---------------------------- |---------:|---------:|---------:|----------:|\n    | PermissionSet_HasPermission | 74.17 ns | 1.382 ns | 1.225 ns |         - |\n\n* Validating a user has a required permission in their claim list:\n\n    |                                                         Method |     Mean |   Error |   StdDev | Allocated |\n    |--------------------------------------------------------------- |---------:|--------:|---------:|----------:|\n    | PermissionAuthorizationHandlerBenchmark_HandleRequirementAsync | 359.4 ns | 6.79 ns | 13.25 ns |     144 B |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff1x3d%2Fpbac.aspnetcore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ff1x3d%2Fpbac.aspnetcore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ff1x3d%2Fpbac.aspnetcore/lists"}