Clustron.Keyvus.Stores.File 1.1.0

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

Keyvus

Host-neutral identity, authentication, and RBAC for .NET services.

Keyvus is an embeddable library (SDK) — not a service, daemon, or app. It has no UI, no CLI, and no process, port, or config file of its own. A host product declares its own permissions and roles; Keyvus authenticates callers and answers one question at every enforcement point: "may this caller do X on Y?" — against a role-based access-control model, with tokens verified offline.

Everything product-specific (which operations exist, where policy lives, which endpoints enforce) sits on the host side of a small, fixed set of seams. Keyvus supplies the machinery; the host supplies the vocabulary. Its first consumer is Clustron DKV (a distributed key/value store), and it is built to be adopted by unrelated products — a queue, a cache, a gateway — each with a completely different vocabulary.

  • Version: 0.23.0
  • Targets: the core libraries target netstandard2.0 (usable from .NET Framework 4.8 and .NET 8+); the ASP.NET Core adapter and tests target net8.0.
  • License: Apache-2.0.

The model in one paragraph

A Permission is an opaque, host-owned operation id ("product.delete"). A Role is a set of permissions. A RoleBinding grants a role to a principal at a ResourceScope — a hierarchical, prefix-matched path (market:store:acme), where a grant at one level implies the levels beneath it. A caller is authenticated into an AccessPrincipal (subject + roles + claims) from a bearer JWT that is verified offline against the issuer's JWKS. Authorization is then a pure function: does any effective (role, scope) binding for this principal include the required permission at the required scope?deny by default. Policy is data, cached at each enforcement point with a change-watch, so a grant or revocation propagates in seconds without a per-request central call.


How a request is authorized

flowchart LR
    C["Caller"] -->|"Bearer JWT"| MW["Keyvus middleware<br/>(or host seam)"]
    MW -->|"verify offline vs JWKS"| V["Token validator<br/>built-in / OIDC"]
    V --> P["AccessPrincipal<br/>subject + roles + claims"]
    P --> A{"Authorizer.Check<br/>permission @ scope"}
    CAT[["Catalog<br/>permissions + roles"]] --> A
    POL[["Policy store<br/>role bindings"]] --> A
    A -->|"allow"| OK["handler runs"]
    A -->|"deny by default"| NO["403 / Unauthorized"]
    A -. "audit allow + deny" .-> AUD[["IAuditSink<br/>(host persists)"]]

The host owns the two data sources on the left of the decision: the catalog (what operations and preset roles exist) and the policy store (who is granted what, where). Keyvus owns the decision.


Packages

Package Target Contents
Clustron.Keyvus.Abstractions netstandard2.0 Core POCOs (AccessPrincipal, Permission, ResourceScope, AccessDecision) and every seam interface. Pure contracts.
Clustron.Keyvus.Rbac netstandard2.0 RBAC engine, catalog, in-memory policy store, policy admin, first-admin bootstrap, and the one-call AddKeyvus DI.
Clustron.Keyvus.Tokens netstandard2.0 Built-in JWT issuer/validator (RS256/ES256), JWKS, signing-key rotation, secret stores.
Clustron.Keyvus.Oidc netstandard2.0 External-IdP token validation and group-to-role mapping (federation).
Clustron.Keyvus.AspNetCore net8.0 Middleware plus the .RequirePermission("…") endpoint ergonomic for HTTP hosts.
Clustron.Keyvus.Stores.File netstandard2.0 Durable file-backed IPolicyStore (JSON, atomic writes, change-watch) for single-node hosts.
Clustron.Keyvus.Stores.EntityFrameworkCore net8.0 Database-backed IPolicyStore (SQL Server / PostgreSQL / SQLite / …) with version-polling change-watch — the reference cluster policy store.

The smallest useful integration is Abstractions + Rbac; a host adds only what it needs.


Quick start

Declaring your vocabulary and wiring Keyvus is one call; enforcing is one line.

// 1. Declare your vocabulary and wire Clustron.Keyvus.
services.AddKeyvus(cat =>
{
    cat.Permission("store.stop", plane: Plane.Control, appliesTo: "store");
    cat.Permission("data.write", plane: Plane.Data,    appliesTo: "store");
    cat.PresetRole("StoreOperator", scopeLevel: "store", "store.stop");
    cat.PresetRole("DataWriter",    scopeLevel: "store", "data.write");
});
services.AddKeyvusBuiltInIssuer(t => t.Issuer = "keyvus://acme");  // optional: issue your own JWTs
services.AddKeyvusAspNetCore();                                    // optional: HTTP adapter

// 2a. Enforce over HTTP.
app.UseKeyvus();  // resolves the caller principal from the bearer token
app.MapPost("/stores/{store}/stop", StopStore)
   .RequirePermission("store.stop", "acme:store:{store}");        // deny -> 403

// 2b. …or anywhere (e.g. a raw-socket data plane), enforce directly.
var decision = authorizer.Check(principal, "data.write", ResourceScope.Parse($"acme:store:{store}"));
if (!decision.Allowed) return Unauthorized(decision.Reason);

// 3. Manage who can do what — all API, no Keyvus UI.
await policyAdmin.GrantAsync("bob@acme.com", "DataWriter",
    ResourceScope.Parse("acme:store:orders"), grantedBy: "alice@acme.com");

Integrate now, enforce later: register .AllowAllForDevelopment() first — byte-for-byte your current unauthenticated behaviour, with a loud startup warning — then switch to the real engine through DI alone, with no call-site changes.

Full references: docs/API_REFERENCE.md, docs/CONFIGURATION.md, and — for shared signing keys and a shared policy store across nodes — docs/MULTI_NODE_DEPLOYMENT.md.


Sample: Keyvus Market

samples/KeyvusMarket is a complete, runnable ASP.NET Core app — a multi-store marketplace — that consumes Keyvus as NuGet packages and exercises every feature: built-in tokens, OIDC federation, both at once, scoped cross-store denial, runtime roles and grants, audit, the file policy store, first-admin bootstrap, break-glass recovery, and AllowAll dev mode.

./pack-local.sh                       # pack the Clustron.Keyvus.* packages into ./nuget-local
cd samples/KeyvusMarket
dotnet run --urls http://localhost:5080

Then open http://localhost:5080/swagger and follow the numbered guides. A typical first run:

  1. The app logs a single-use bootstrap token on startup (there are no default credentials).
  2. POST /auth/login with a seeded user returns a JWT; click Authorize in Swagger and paste it.
  3. GET /stores/acme/products succeeds for a StoreManager granted on acme
  4. … and the same call on a store they were not granted returns 403 — scopes in action.
  5. GET /admin/audit shows the allow/deny decisions Keyvus emitted for each check.

Swap behaviour without code changes via Market__AuthMode (BuiltIn | Oidc | Both | AllowAll) and Market__PolicyStore (InMemory | File).


How it works

  • Authentication. Callers present a short-lived JWT — from the built-in issuer or a federated OIDC provider — as Authorization: Bearer …. Every token is verified offline against the issuer's JWKS; there is no per-request round-trip to an auth server. Service-to-service callers may use X.509 certificates instead.
  • Authorization. Deny by default. Access is granted only when some effective (role, scope) binding for the principal contains the required permission at (or above) the required scope.
  • Policy is data. Bindings live in an IPolicyStore (in-memory, file, or EF Core), cached at each enforcement point with a change-watch, so revocations and new grants take effect in seconds.
  • The host provides the encrypted transport (Keyvus assumes it) and an IAuditSink (Keyvus emits decisions; the host persists them). Operability is built in: first-admin bootstrap (single-use token, no default credentials) and break-glass recovery (host-initiated, gated on local machine access, audited).

Build and test

Requires the .NET 8 SDK (the core libraries also target netstandard2.0).

dotnet build Clustron.Keyvus.sln -c Release
dotnet test  Clustron.Keyvus.sln -c Release        # 167 tests across six test projects
./pack-local.sh                           # pack all Clustron.Keyvus.* packages into ./nuget-local

CI (.github/workflows/ci.yml) builds, tests, and packs on both Windows and Linux on every push and PR.

Clustron.Keyvus.Stores.Truth and its tests are intentionally excluded from Clustron.Keyvus.sln because they reference a sibling repository; build them explicitly if you need the Truth-backed store.


Documentation


License

Apache-2.0 — see LICENSE. A security framework earns trust and contributions by being freely reusable.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  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 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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.1.0 91 8/16/2026
0.9.0 89 8/5/2026