KnOwl.Contracts
2.3.0
dotnet add package KnOwl.Contracts --version 2.3.0
NuGet\Install-Package KnOwl.Contracts -Version 2.3.0
<PackageReference Include="KnOwl.Contracts" Version="2.3.0" />
<PackageVersion Include="KnOwl.Contracts" Version="2.3.0" />
<PackageReference Include="KnOwl.Contracts" />
paket add KnOwl.Contracts --version 2.3.0
#r "nuget: KnOwl.Contracts, 2.3.0"
#:package KnOwl.Contracts@2.3.0
#addin nuget:?package=KnOwl.Contracts&version=2.3.0
#tool nuget:?package=KnOwl.Contracts&version=2.3.0
KnOwl
<img src="assets/knowl-readme-hero.png" alt="KnOwl contract design and runtime distribution" width="100%">
KnOwl is a set of reusable .NET libraries for designing, versioning, promoting, distributing, and consuming async contract metadata. It gives teams a Control Plane where contracts are authored and released, plus a Runtime surface where deployed contracts can be consumed by running services.
The goal is to keep product hosts thin. Your app owns the executable project, configuration, and EF migrations; KnOwl packages provide the domain model, application services, storage adapters, Razor UI, catalog endpoints, distribution endpoints, and runtime synchronization behavior.
What KnOwl Solves
- Design event and command contracts with versioned payload schemas.
- Model commands with a required request schema and optional reply schema.
- Promote versions through lifecycle states and generate immutable artifacts.
- Distribute deployed artifacts from a Control Plane to one or more Runtime hosts.
- Expose deployed schemas through split event and command catalog endpoints.
- Navigate reusable Web UI screens with card-based browsing, searchable operational lists, and version details.
- Browse Markdown documentation spaces, topics, pages, and page versions from the Control Plane UI.
- Render Documentation Markdown with a navigable page index, in-page search, and Mermaid diagrams with zoom, pan, and expanded-view controls.
- Theme Control Plane and Runtime hosts with light and dark palettes, custom titles, icons, and sidebar branding.
- Keep host-specific database migrations outside the reusable NuGet libraries.
Packages
Install only the layer your host needs:
| Package | Purpose |
|---|---|
KnOwl.Contracts |
Shared DTOs for artifacts, delivery, catalog responses, and distribution credential primitives. |
KnOwl.ControlPlane |
Control Plane domain model and repository contracts. |
KnOwl.ControlPlane.Application |
Control Plane services for design, lifecycle, artifacts, releases, and delivery. |
KnOwl.ControlPlane.Api |
Minimal API endpoints for Control Plane automation and external integrations. |
KnOwl.ControlPlane.Storage.EntityFramework |
Provider-agnostic EF Core storage for Control Plane state. |
KnOwl.ControlPlane.WebUI |
Reusable Razor UI for Control Plane hosts. |
KnOwl.ControlPlane.Bootstrap |
ASP.NET Core composition for Control Plane hosts. |
KnOwl.Runtime |
Runtime domain model and repository contracts. |
KnOwl.Runtime.Application |
Runtime catalog, deployment, pull, and connection credential services. |
KnOwl.Runtime.Api |
Minimal API endpoints for Runtime administration and artifact consumption. |
KnOwl.Runtime.Storage.EntityFramework |
Provider-agnostic EF Core storage for Runtime state. |
KnOwl.Runtime.WebUI |
Reusable Razor UI for Runtime hosts. |
KnOwl.Runtime.Bootstrap |
ASP.NET Core composition for Runtime hosts. |
KnOwl.WolfAuth |
Optional WolfAuth authentication integration and login shell for KnOwl hosts. |
All packages target net9.0 and net10.0.
The *.Storage.EntityFramework and bootstrap packages depend on EF Core relational APIs, not on a concrete database provider. Hosts choose the provider by configuring the DbContext options, the same way they would configure EF Core directly.
Getting Started
1. Create a Control Plane host
dotnet new web -n MyCompany.Contracts.ControlPlane
cd MyCompany.Contracts.ControlPlane
dotnet add package KnOwl.ControlPlane.Bootstrap
dotnet add package KnOwl.ControlPlane.Storage.EntityFramework
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
Use the bootstrap package in Program.cs:
using KnOwl.ControlPlane.Bootstrap;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
var migrationsAssembly = typeof(Program).Assembly.GetName().Name!;
var connectionString = builder.Configuration.GetConnectionString("KnOwlDb");
builder.Services.AddKnOwlControlPlane(builder.Configuration, options =>
{
options.MigrationsAssembly = migrationsAssembly;
options.ConfigureStorage = db => db.UseSqlServer(
connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
options.Theme.Title = "My Contracts";
options.Theme.Mode = KnOwl.ControlPlane.WebUI.KnOwlThemeMode.Dark;
options.Theme.IconImageUrl = "/img/company-icon.png";
options.Theme.Light.PrimaryColor = "#2563eb";
options.Theme.Light.PrimaryHoverColor = "#1d4ed8";
options.Theme.Light.SidebarBackgroundColor = "#0f2a44";
options.Theme.Light.SidebarBrandBackgroundColor = "#0b1f33";
options.Theme.Light.SidebarTextColor = "#ffffff";
options.Theme.Light.SidebarMutedTextColor = "#bfdbfe";
options.Theme.Dark.PrimaryColor = "#60a5fa";
options.Theme.Dark.PrimaryHoverColor = "#93c5fd";
options.Theme.Dark.SidebarBackgroundColor = "#0f172a";
options.Theme.Dark.SidebarBrandBackgroundColor = "#0b1220";
options.Theme.Dark.SidebarTextColor = "#f8fafc";
options.Theme.Dark.SidebarMutedTextColor = "#bfdbfe";
});
var app = builder.Build();
app.MapKnOwlControlPlane();
app.Run();
Add configuration:
{
"ConnectionStrings": {
"KnOwlDb": "Server=localhost;Database=KnOwlControlPlane;Trusted_Connection=True;TrustServerCertificate=True"
}
}
Create migrations in the host project:
dotnet ef migrations add InitialKnOwlControlPlane `
--context KnOwlDbContext `
--output-dir Migrations
dotnet ef database update --context KnOwlDbContext
Run the host and open the Control Plane UI. From there you can create data types, custom metadata fields, events, commands, versions, artifacts, runtime environments, runtime nodes, and releases. Control Plane list and detail screens include query-string search for contracts, versions, artifacts, releases, environments, and runtime node setup, so teams can filter large catalogs without custom host code. Documentation pages include rendered-text search with highlighted matches and previous/next navigation. Mermaid diagrams render directly from fenced Markdown blocks and include zoom out, reset, zoom in, and expanded-view controls without requiring host-specific JavaScript.
The bootstrap package also maps the Control Plane REST API at /api/v1/control-plane.
Theme configuration is optional. When omitted, the reusable Web UI uses KnOwl's default purple and white light palette plus its default dark palette. Hosts can override the title, icon, initial mode, and separate light/dark colors from AddKnOwlControlPlane without changing package assets.
The Control Plane UI uses the same card-based navigation patterns across contracts, distribution, documentation, and administrative views so hosts get a complete management experience without rebuilding screens.
To use a different EF Core provider, install that provider in the host and configure storage with that provider:
using KnOwl.ControlPlane.Bootstrap;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddKnOwlControlPlane(builder.Configuration, options =>
{
options.ConfigureStorage = db => db.UseNpgsql(
builder.Configuration.GetConnectionString("KnOwlDb"),
provider => provider.MigrationsAssembly(typeof(Program).Assembly.GetName().Name));
});
2. Create a Runtime host
dotnet new web -n MyCompany.Contracts.Runtime
cd MyCompany.Contracts.Runtime
dotnet add package KnOwl.Runtime.Bootstrap
dotnet add package KnOwl.Runtime.Storage.EntityFramework
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
Use the runtime bootstrap in Program.cs:
using KnOwl.Runtime.Bootstrap;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
var migrationsAssembly = typeof(Program).Assembly.GetName().Name!;
var connectionString = builder.Configuration.GetConnectionString("KnOwlRuntimeDb")
?? builder.Configuration.GetConnectionString("KnOwlDb");
builder.Services.AddKnOwlRuntime(builder.Configuration, options =>
{
options.MigrationsAssembly = migrationsAssembly;
options.ConfigureStorage = db => db.UseSqlServer(
connectionString,
sql => sql.MigrationsAssembly(migrationsAssembly));
options.Theme.Title = "My Runtime";
options.Theme.Subtitle = "Contract cache";
options.Theme.Mode = KnOwl.Runtime.WebUI.KnOwlThemeMode.Dark;
options.Theme.IconImageUrl = "/img/company-icon.png";
options.Theme.Light.PrimaryColor = "#2563eb";
options.Theme.Light.PrimaryHoverColor = "#1d4ed8";
options.Theme.Light.SidebarBackgroundColor = "#0f2a44";
options.Theme.Light.SidebarBrandBackgroundColor = "#0b1f33";
options.Theme.Light.SidebarTextColor = "#ffffff";
options.Theme.Light.SidebarMutedTextColor = "#bfdbfe";
options.Theme.Dark.PrimaryColor = "#60a5fa";
options.Theme.Dark.PrimaryHoverColor = "#93c5fd";
options.Theme.Dark.SidebarBackgroundColor = "#0f172a";
options.Theme.Dark.SidebarBrandBackgroundColor = "#0b1220";
options.Theme.Dark.SidebarTextColor = "#f8fafc";
options.Theme.Dark.SidebarMutedTextColor = "#bfdbfe";
});
var app = builder.Build();
app.MapKnOwlRuntime();
app.Run();
Add configuration:
{
"ConnectionStrings": {
"KnOwlRuntimeDb": "Server=localhost;Database=KnOwlRuntime;Trusted_Connection=True;TrustServerCertificate=True"
},
"Runtime": {
"ArtifactPull": {
"Enabled": true,
"InitialDelaySeconds": 5,
"IntervalSeconds": 30
}
}
}
Create runtime migrations in the host project:
dotnet ef migrations add InitialKnOwlRuntime `
--context KnOwlRuntimeDbContext `
--output-dir Migrations/RuntimeStorage
dotnet ef database update --context KnOwlRuntimeDbContext
The bootstrap package also maps the Runtime REST API at /api/v1/runtime.
Runtime theme configuration is optional and follows the same host-owned pattern as the Control Plane. Hosts can set the sidebar title, subtitle, icon, initial mode, and separate light/dark palettes directly on options.Theme.
If SidebarBrandBackgroundColor is not set in a palette, the Runtime sidebar header falls back to that palette's SidebarBackgroundColor so the host theme remains consistent.
The Runtime UI includes Control Plane-aligned navigation, searchable Control Plane connections, and artifact catalog filters for deployed contract caches.
3. Connect Runtime to Control Plane
- In the Runtime UI, create a Control Plane connection.
- Generate or import the connection credentials.
- In the Control Plane UI, register the Runtime node and credentials.
- Release deployed artifacts from the Control Plane.
- Let the Runtime pull pending artifacts, or push artifacts to the Runtime delivery endpoint.
The sample hosts show the intended shape:
samples/KnOwl.ControlPlaneHost.Samplesamples/KnOwl.RuntimeHost.Sample
The sample design-time DbContext factories target the same sample databases used at runtime. This keeps dotnet ef database update aligned with the hosts you run locally.
Contract Catalog
Control Plane hosts expose deployed source artifacts only when their artifact status is deployed:
GET /contracts/artifactsGET /contracts/events/{eventKey}/versions/{versionNumber}GET /contracts/commands/{commandKey}/versions/{versionNumber}
Runtime hosts expose deployed local artifacts:
GET /runtime/contracts/artifactsGET /runtime/contracts/events/{eventKey}/versions/{versionNumber}GET /runtime/contracts/commands/{commandKey}/versions/{versionNumber}
Event responses return one artifact. Command responses return both sides of the command version:
{
"commandKey": "inventories.reserve",
"version": "1.0.0",
"requestArtifact": {
"artifactType": "CommandRequest",
"payloadSchema": {}
},
"replyArtifact": {
"artifactType": "CommandReply",
"payloadSchema": {}
}
}
replyArtifact is optional. Request artifacts are required.
REST API
KnOwl includes Minimal API packages for automation, CI tooling, portals, and custom hosts that need to drive KnOwl without using the Razor UI.
Control Plane hosts expose:
GET /api/v1/control-plane/schema-typesPOST /api/v1/control-plane/schema-typesGET /api/v1/control-plane/metadata-fieldsPOST /api/v1/control-plane/metadata-fieldsGET /api/v1/control-plane/eventsPOST /api/v1/control-plane/eventsPOST /api/v1/control-plane/events/{id}/versionsPOST /api/v1/control-plane/events/{id}/versions/{versionId}/transitionGET /api/v1/control-plane/commandsPOST /api/v1/control-plane/commandsPOST /api/v1/control-plane/commands/{id}/versionsPOST /api/v1/control-plane/commands/{id}/versions/{versionId}/transitionGET /api/v1/control-plane/artifactsPOST /api/v1/control-plane/artifacts/events/{versionId}/buildPOST /api/v1/control-plane/artifacts/commands/{versionId}/buildGET /api/v1/control-plane/runtime-environmentsGET /api/v1/control-plane/runtime-nodesPOST /api/v1/control-plane/runtime-nodes/{id}/credentials/generatePOST /api/v1/control-plane/runtime-nodes/{id}/credentials/importPOST /api/v1/control-plane/runtime-nodes/{id}/connect/validateGET /api/v1/control-plane/releasesPOST /api/v1/control-plane/releasesPOST /api/v1/control-plane/releases/{id}/planPOST /api/v1/control-plane/releases/{id}/execute
Runtime hosts expose:
GET /api/v1/runtime/statusGET /api/v1/runtime/artifactsGET /api/v1/runtime/artifacts/events/{eventKey}/versions/{versionNumber}GET /api/v1/runtime/artifacts/commands/{commandKey}/versions/{versionNumber}GET /api/v1/runtime/control-planesPOST /api/v1/runtime/control-planesPOST /api/v1/runtime/control-planes/{id}/credentials/generatePOST /api/v1/runtime/control-planes/{id}/credentials/importPOST /api/v1/runtime/control-planes/{id}/connect/validateGET /api/v1/runtime/control-planes/{sourceKey}/artifacts/pendingPOST /api/v1/runtime/control-planes/{sourceKey}/artifacts/{releaseTargetId}/apply
Creating a command through the API captures both schemas in the first version:
POST /api/v1/control-plane/commands
{
"name": "Reserve Inventory",
"topic": "inventories.reserve",
"description": "Reserve stock before checkout.",
"versionNumber": "1.0.0",
"requestDefinitionJson": "{\"type\":\"object\",\"properties\":{\"sku\":{\"type\":\"string\"}}}",
"replyDefinitionJson": "{\"type\":\"object\",\"properties\":{\"accepted\":{\"type\":\"boolean\"}}}",
"comment": "Initial command contract."
}
Hosts remain responsible for authentication. The API packages do not force JWT, cookies, managed identity, or API-key infrastructure.
Authentication With WolfAuth
KnOwl delegates user authentication to WolfAuth. The host configures WolfAuth directly, including its provider, schemes, claims, and storage. KnOwl only adds the reusable login shell and middleware hooks needed by the Control Plane or Runtime UI.
WolfAuth integration is enabled by default when a host calls UseWolfAuth. Disable it per environment with KnOwl:WolfAuth:Enabled = false; when disabled, KnOwl skips the login gate and hides the top-bar user menu.
Typical Control Plane setup:
using KnOwl.ControlPlane.Bootstrap;
using KnOwl.WolfAuth;
using Microsoft.EntityFrameworkCore;
using WolfAuth.AspNetCore;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddWolfAuth(wolf =>
{
// Configure WolfAuth directly here: provider, claims mapping, persistence, and policies.
});
builder.Services
.AddKnOwlControlPlane(builder.Configuration, options =>
{
options.MigrationsAssembly = typeof(Program).Assembly.GetName().Name;
options.ConfigureStorage = db => db.UseSqlServer(
builder.Configuration.GetConnectionString("KnOwlDb"),
sql => sql.MigrationsAssembly(typeof(Program).Assembly.GetName().Name));
})
.UseWolfAuth(builder.Configuration.GetSection("KnOwl:WolfAuth"), options =>
{
options.ApplicationName = "My Contracts";
options.Subtitle = "Sign in to continue.";
options.LoginButtonText = "Login";
});
var app = builder.Build();
app.MapKnOwlControlPlane();
app.Run();
Configuration:
{
"KnOwl": {
"WolfAuth": {
"Enabled": true,
"LoginPath": "/auth/login",
"ChallengePath": "/auth/login/challenge",
"LogoutPath": "/auth/logout"
}
}
}
When UseWolfAuth is enabled, anonymous browser requests are redirected to /auth/login. That page renders a single Login button that triggers /auth/login/challenge, and the challenge uses the authentication scheme configured by the host through WolfAuth/ASP.NET Core authentication.
This phase covers authentication. KnOwl's previous in-package user security layer for subjects, roles, permissions, authentication, and security storage is deprecated in favor of WolfAuth as the central security layer. Distribution credential/token primitives used for Control Plane and Runtime artifact delivery remain part of KnOwl because they secure node-to-node distribution, not user sign-in.
Local Development
Build and test:
dotnet restore KnOwl.slnx
dotnet build KnOwl.slnx --no-restore --configuration Release
dotnet test KnOwl.slnx --no-build --configuration Release
The test suite is intentionally granular. It includes focused unit coverage for public contract shapes, API mappers, token providers, page models, WolfAuth integration, distribution credential security, storage repositories, distribution flows, Documentation rendering, and Runtime behavior. The current release validates 3,164 xUnit cases on net9.0 and 2,932 on net10.0 with 99%+ line coverage.
Pack the libraries:
Get-ChildItem src -Recurse -Filter *.csproj | ForEach-Object {
dotnet pack $_.FullName --configuration Release -o artifacts/packages
}
Run the distribution end-to-end test. This starts SQL Server in Docker, runs the Control Plane and Runtime samples, and validates SQL Server storage plus push/pull artifact distribution for both target frameworks.
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/run-knowl-distribution-e2e.ps1
Release
The release workflow builds, tests, packs, creates the GitHub release, and publishes NuGet packages. Production releases are driven by .release and CHANGELOG.md.
Current release: 2.3.0
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0 is compatible. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. 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. |
-
net10.0
- No dependencies.
-
net9.0
- No dependencies.
NuGet packages (12)
Showing the top 5 NuGet packages that depend on KnOwl.Contracts:
| Package | Downloads |
|---|---|
|
KnOwl.Runtime
Domain model and repository contracts for KnOwl runtime contract metadata. |
|
|
KnOwl.ControlPlane
Domain model and repository contracts for KnOwl control plane design and distribution. |
|
|
KnOwl.ControlPlane.Application
Application services for KnOwl control plane design, promotion, distribution, and security workflows. |
|
|
KnOwl.Runtime.Application
Application services for KnOwl runtime catalog, deployment, pull, and security workflows. |
|
|
KnOwl.ControlPlane.Storage.EntityFramework
Entity Framework Core storage for KnOwl control plane design and distribution metadata. |
GitHub repositories
This package is not used by any popular GitHub repositories.