M6d.Cerebro 0.3.0

dotnet add package M6d.Cerebro --version 0.3.0
                    
NuGet\Install-Package M6d.Cerebro -Version 0.3.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="M6d.Cerebro" Version="0.3.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="M6d.Cerebro" Version="0.3.0" />
                    
Directory.Packages.props
<PackageReference Include="M6d.Cerebro" />
                    
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 M6d.Cerebro --version 0.3.0
                    
#r "nuget: M6d.Cerebro, 0.3.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 M6d.Cerebro@0.3.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=M6d.Cerebro&version=0.3.0
                    
Install as a Cake Addin
#tool nuget:?package=M6d.Cerebro&version=0.3.0
                    
Install as a Cake Tool

Cerebro C# SDK

This SDK provides reusable licensing and entitlement-gating primitives for any C# / ASP.NET Core application that consumes Cerebro licenses.

Project structure

The library is organized by responsibility to make navigation easier:

  • src/M6d.Cerebro/Licensing/Abstractions: public service contracts.
  • src/M6d.Cerebro/Licensing/Models: license payload and validation result models.
  • src/M6d.Cerebro/Licensing/Options: configurable licensing options.
  • src/M6d.Cerebro/Licensing/Services: default implementations.
  • src/M6d.Cerebro/Licensing/Extensions: DI and startup helpers.
  • src/M6d.Cerebro/Licensing/Constants: built-in public keys.
  • src/M6d.Cerebro/Licensing/AspNetCore/Abstractions: HTTP entitlement resolver contracts.
  • src/M6d.Cerebro/Licensing/AspNetCore/Options: ASP.NET Core behavior configuration.
  • src/M6d.Cerebro/Licensing/AspNetCore/Routing: route-to-entitlement mapping primitives.
  • src/M6d.Cerebro/Licensing/AspNetCore/Middleware: request gating middleware.
  • src/M6d.Cerebro/Licensing/AspNetCore/Extensions: ASP.NET Core pipeline/endpoint helpers.
  • samples: runnable example projects.

What is included

  • License key validation compatible with Cerebro-generated keys.
  • Typed entitlement reads and on/off checks from validated licenses.
  • ASP.NET Core middleware for:
    • blocking requests with invalid or expired licenses.
    • blocking requests whose entitlement the license does not enable.
    • returning RFC 7807 Problem Details responses by default.
  • Configurable route-to-entitlement mapping.
  • Optional endpoint helper to expose the license's entitlements.

Samples

  • samples/MinimalApiEntitlementGateSample: minimal API with license validation middleware and entitlement gating.
  • samples/StartupStyleApiSample: class-based Startup configuration with controllers and endpoint routing.

Testing

  • Unit tests live in tests/M6d.Cerebro.Tests (xunit.v3 on Microsoft.Testing.Platform).
  • From the repository root, bun run dotnet builds, checks formatting, tests and packs the solution. bun run --cwd packages/cerebro-dotnet <build|check|test|lint|format|pack> runs one command through scripts/dotnet.ts, which refuses an SDK other than the one global.json pins.
  • The package targets net10.0. Directory.Build.props turns every analyzer rule into an error, and CSharpier owns formatting.

Releases

Releases run from the monorepo; see "Releasing" in the root README.md.

Installation and setup

NuGet package ID: M6d.Cerebro.

Register services in Program.cs or Startup.ConfigureServices:

using M6d.Cerebro.Licensing.Extensions;
using M6d.Cerebro.Licensing.AspNetCore.Extensions;
using System.Net.Http;

services.AddCerebroLicensing(
    configureLicensing: options =>
    {
        options.LicenseKeyEnvironmentVariableName = "MSR_LICENSE_KEY";
        options.AppId = "your-product-id";
        // options.PublicKey = "..."; // optional override
    },
    configureEntitlementRouting: routes =>
    {
        routes.MapFirstSegmentPrefix("kpis", "kpis");
        routes.MapFirstSegmentPrefix("plans", "plans");
        routes.MapFirstSegmentPrefix("operations", "operations");

        routes.MapPathPrefix("settings/kpis", "kpis", HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete, HttpMethod.Patch);
        routes.MapPathPrefix("settings/plans", "plans", HttpMethod.Post, HttpMethod.Put, HttpMethod.Delete, HttpMethod.Patch);
    });

Set AppId to the product ID from Cerebro to reject licenses for other products. The comparison is case-sensitive. A mismatch returns CerebroLicenseValidationFailure.WrongApp. The default is null, which accepts any product.

Add middleware in the request pipeline:

using M6d.Cerebro.Licensing.AspNetCore.Extensions;

app.UseCerebroLicenseValidation();
app.UseRouting();
app.UseAuthentication();
app.UseAuthorization();
app.UseCerebroEntitlementGating();

Optionally fail startup if the license is invalid:

using M6d.Cerebro.Licensing.Extensions;

app.Services.EnsureCerebroLicenseIsValid();

Optionally expose the current license entitlements:

using M6d.Cerebro.Licensing.AspNetCore.Extensions;

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
    endpoints.MapCerebroEntitlementsEndpoint();
});

By default, MapCerebroEntitlementsEndpoint() maps GET /licenses/entitlements:

{ "reports": true, "exports": false, "maxUsers": 10, "tier": "pro", "seats": null }

An invalid license produces {}. License validation middleware can still block requests before they reach the endpoint.

Direct service usage

Inject ICerebroLicenseService anywhere:

using M6d.Cerebro.Licensing.Abstractions;

public class MyService(ICerebroLicenseService licenseService)
{
    public bool CanUseAdvancedReports() => licenseService.IsEnabled("advanced_reports");

    public bool CanAddUser(long userCount) => licenseService.IsWithinLimit("maxUsers", userCount + 1);

    public bool HasUnlimitedSeats() =>
        licenseService.TryGet<long?>("seats", out var seats) && seats is null;

    public long? GetMaxUsers() =>
        licenseService.TryGet<long?>("maxUsers", out var users) ? users : 0;

    public double? GetPrice() =>
        licenseService.TryGet<double?>("price", out var price) ? price : 0;
}

GetEntitlements() returns the license's entitlements by code as signed, an IReadOnlyDictionary<string, JsonElement>. IsEnabled(code) is true only for an entitlement signed as JSON true. IsWithinLimit(code, count) is true when the entitlement is a number of at least count, or JSON null (unlimited); any other value or an absent code allows nothing. TryGet<T>(code, out value) uses the configured CerebroLicensingOptions.JsonSerializerOptions. Code lookup is case-insensitive, as with IsEnabled and IsWithinLimit. It returns false and the default value for absent codes, invalid licenses, or incompatible requested types. Use long? for whole numbers and double? for decimals. A null number means unlimited. For example, 3000000000 fits long?; requesting it as int? returns false and null. Signature validation is cached. Expiration is checked on every service call through UtcNowProvider when ValidateExpirationDate is enabled. Expired licenses return LicenseExpired and grant no entitlements.

Generate API docs

The project enables XML documentation output in the library project file. Public APIs are documented with XML comments so IDE IntelliSense and generated docs remain useful for integrators.

Compatibility details

  • License payload is decoded as UTF-16.
  • Signature verification uses RSA PKCS#1 v1.5 with MD5 hash.
  • Payload fields are id, appId, deviceIds, expirationDate, and entitlements.
  • entitlements maps every active entitlement code to true or false for on/off entitlements, otherwise a string, number, or null. A null number means unlimited.
  • CerebroLicenseDetails.Entitlements is an IReadOnlyDictionary<string, JsonElement>. A payload without entitlements, or with an object or array as a value, fails with DeserializationFailed.
  • The signer escapes [SEPARATOR] inside JSON strings as \u005BSEPARATOR]. Signature validation uses the original JSON; parsing restores the literal text.
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
0.3.0 71 11/2/2026
0.2.0 203 10/29/2026
0.1.0 74 10/29/2026