ClaimsPolicyBuilder 1.0.0

dotnet add package ClaimsPolicyBuilder --version 1.0.0
                    
NuGet\Install-Package ClaimsPolicyBuilder -Version 1.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ClaimsPolicyBuilder" Version="1.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ClaimsPolicyBuilder" Version="1.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ClaimsPolicyBuilder" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ClaimsPolicyBuilder --version 1.0.0
                    
#r "nuget: ClaimsPolicyBuilder, 1.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ClaimsPolicyBuilder@1.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ClaimsPolicyBuilder&version=1.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ClaimsPolicyBuilder&version=1.0.0
                    
Install as a Cake Tool

ClaimsPolicyBuilder

A fluent DSL for building ASP.NET Core claims-based authorization policies with compile-time safety.

.NET 10 License: MIT

Problem

Authorization in ASP.NET Core is powerful but ergonomically poor. AuthorizationPolicyBuilder requires 5–10 lines of repetitive policy.Require* calls per policy, uses magic strings for policy names, and offers no composition story.

Solution

ClaimsPolicyBuilder provides:

  • A fluent DSL that expresses policies in 1–2 readable lines
  • Compile-time policy name constants via a Roslyn source generator — typos become build errors, not runtime 403s
  • Policy composition with Extends, And, and Or
  • Zero runtime cost — produces standard AuthorizationPolicy instances

Installation

dotnet add package ClaimsPolicyBuilder

Quick Start

services.AddClaimsPolicies(policies =>
{
    policies.Add("CanEditInvoices")
        .RequireAuthenticated()
        .RequireScope("invoices:write")
        .RequireAnyRole("Accountant", "Admin")
        .RequireClaim("tenant", "acme");

    policies.Add("CanViewReports")
        .Extends("CanEditInvoices")
        .RequireClaim("feature", "reports");

    policies.Add("AdminOnly")
        .RequireRole("Admin")
        .Or(p => p.RequireClaim("override", "true"));
});

Using Generated Policy Name Constants

The source generator emits a Policies class with const string fields:

// Auto-generated at compile time
[Authorize(Policy = Policies.CanEditInvoices)]
public IResult EditInvoice() { ... }

[Authorize(Policy = Policies.AdminOnly)]
public IResult AdminAction() { ... }

Configure the Generated Namespace

Use an assembly attribute:

[assembly: ClaimsPolicyNamespace("MyApp.Auth")]

Or an MSBuild property in your .csproj:

<PropertyGroup>
  <ClaimsPolicyBuilder_Namespace>MyApp.Auth</ClaimsPolicyBuilder_Namespace>
</PropertyGroup>

Defaults to <RootNamespace>.Authorization.

API Reference

Policy Registration

Method Description
services.AddClaimsPolicies(Action<IPolicyRegistration>) Entry point for registering policies
policies.Add(string name) Creates a new named policy and returns a fluent builder

Policy Builder

Method Description
.RequireAuthenticated() Requires an authenticated user
.RequireRole(string) Requires a single role
.RequireAnyRole(params string[]) Requires any one of the specified roles
.RequireAllRoles(params string[]) Requires all of the specified roles
.RequireClaim(string type, params string[]) Requires a claim with optional allowed values
.RequireClaimMatching(string type, Func<string, bool>) Requires a claim matching a predicate
.RequireScope(params string[]) Requires OAuth2-style scope values (space-separated)
.RequireAssertion(Func<AuthorizationHandlerContext, bool>) Custom assertion escape hatch
.Extends(string policyName) Inherits all requirements from another policy (logical AND)
.And(Action<IPolicyBuilder>) Adds additional requirements (logical AND)
.Or(Action<IPolicyBuilder>) Adds alternative requirements (logical OR)

Source Generator Diagnostics

ID Severity Description
CPB001 Error Duplicate policy name detected
CPB002 Warning Policy name is not a valid C# identifier

Examples

1. Simple Role-Based Policy

services.AddClaimsPolicies(policies =>
{
    policies.Add("AdminOnly").RequireRole("Admin");
});

2. Multi-Tenant Policy

services.AddClaimsPolicies(policies =>
{
    policies.Add("TenantAccess")
        .RequireAuthenticated()
        .RequireClaim("tenant", "acme");
});

3. Composed Policies

services.AddClaimsPolicies(policies =>
{
    policies.Add("BaseTenant")
        .RequireAuthenticated()
        .RequireClaim("tenant", "acme");

    policies.Add("TenantAdmin")
        .Extends("BaseTenant")
        .RequireRole("Admin");
});

4. OR Composition

services.AddClaimsPolicies(policies =>
{
    policies.Add("CanAccess")
        .RequireRole("Admin")
        .Or(p => p.RequireClaim("bypass", "true"));
});

5. Scope-Based API Policy

services.AddClaimsPolicies(policies =>
{
    policies.Add("ReadWrite")
        .RequireAuthenticated()
        .RequireScope("api:read", "api:write");
});

Sample App

A runnable ASP.NET Core sample lives in samples/ClaimsPolicyBuilder.Sample. It wires up every policy above and protects minimal-API endpoints with the generated Policies.* constants. A header-driven test auth handler lets you flip a request between allowed and denied without an identity provider:

dotnet run --project samples/ClaimsPolicyBuilder.Sample
# 200 — all requirements met
curl -i http://localhost:5080/invoices/edit \
  -H "X-User: alice" -H "X-Roles: Accountant" \
  -H "X-Scope: invoices:write" -H "X-Claims: tenant=acme"
# 403 — drop the scope and the same request is forbidden
curl -i http://localhost:5080/invoices/edit \
  -H "X-User: alice" -H "X-Roles: Accountant" -H "X-Claims: tenant=acme"

See the sample README and sample.http for the full success/denied matrix of every policy.

Design Decisions

  • Extends semantics: Extending means logical AND of all requirements from the parent policy. Override semantics were considered but rejected as surprising in auth contexts.
  • Or implementation: ASP.NET Core's policy model is AND-only by default. Or is implemented as a single RequireAssertion wrapping both sub-policies. This loses requirement-level introspection but provides correct OR evaluation.
  • No replacement: The library produces standard AuthorizationPolicy instances. It integrates with existing [Authorize], minimal API .RequireAuthorization(), and Blazor <AuthorizeView>.

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net10.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0 137 5/30/2026