ConfigVault.Client 1.0.6

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

ConfigVault

.NET License NuGet Buy Me A Coffee

A configuration management platform with versioning, encryption, rollback support, role-based access control, and full audit logging. Includes a React frontend dashboard and a .NET API backend.

Features

  • 🔐 User Authentication — Identity API with registration, login, JWT tokens, 2FA, and password management
  • 👥 Role-Based Access Control — Global roles (Admin, User, CreateApplications, etc.) plus granular per-application and per-environment permissions (Read, Write, Delete, Rollback, Tag, RegenerateKey, Decrypt)
  • 🔒 Encryption — Encrypt sensitive configuration values using the Data Protection API
  • 📜 Version History — Every change creates a new version, maintaining full history
  • Rollback — Rollback to any previous version, point in time, or tagged version (single key or entire environment)
  • 🏷️ Tagging — Tag individual versions or entire environments as "stable", "last-known-good", etc.
  • 📊 Audit Logging — Complete audit trail of all changes with user, IP, and user agent tracking
  • 🌍 Multi-Environment — Support for Development, Staging, Production, and custom environments
  • 📱 Multi-Application — Manage configs for multiple applications under one instance
  • 🔌 Client API — Simple API for applications to fetch configs using API keys
  • 📤 Import/Export — Bulk import and export configurations per environment
  • 📋 Environment Copy — Copy configurations between environments
  • 🖥️ Frontend Dashboard — React + TypeScript + Material UI management interface

Images

<img width="3207" height="1864" alt="image" src="https://github.com/user-attachments/assets/01651c4e-55d4-45a5-ba24-bead2cdb13ea" /> <img width="3827" height="2259" alt="image" src="https://github.com/user-attachments/assets/0cbf9e7a-799b-44fa-9165-3ff0d6f74800" /> <img width="1461" height="1461" alt="image" src="https://github.com/user-attachments/assets/73639142-7809-4efd-8755-c93e78b33440" /> <img width="2672" height="1504" alt="image" src="https://github.com/user-attachments/assets/830915c9-3dea-4c7a-9a8b-63c09a67aecc" /> <img width="1171" height="1083" alt="image" src="https://github.com/user-attachments/assets/ba458d4d-b9fa-425f-9553-b6dc580f394b" /> <img width="1093" height="2051" alt="image" src="https://github.com/user-attachments/assets/d6caf54e-185e-4bd3-83bb-19ae115f2d0b" /> <img width="3827" height="2259" alt="image" src="https://github.com/user-attachments/assets/fb1dbfb9-8a9d-46c3-8978-990ede716aab" />

Architecture

ConfigVault/
├── src/
│   ├── ConfigVault.Api/          # ASP.NET Core API (.NET 10)
│   ├── ConfigVault.Core/         # Domain entities, services, interfaces
│   └── ConfigVault.Client/       # .NET IConfiguration provider (NuGet package)
│   └── ConfigVault.FrontEnd/     # React + Vite + TypeScript + MUI dashboard
├── docker-compose.yml
└── Dockerfile

Tech Stack

Backend: ASP.NET Core (.NET 10), Entity Framework Core, PostgreSQL, ASP.NET Identity, Data Protection API, Swagger/OpenAPI 3.1

Frontend: React 19, TypeScript, Vite, Material UI 7, React Router 7, TanStack React Query, Axios (auto-generated API client from Swagger), Topiray Auth

Quick Start

Backend — Using Docker Compose (with PostgreSQL)

docker-compose up -d

The API will be available at http://localhost:8080. Swagger UI is available in development mode at the root URL.

Backend — Local Development

cd src/ConfigVault.Api
dotnet run

Frontend

cd frontend
cp _env .env        # Configure your environment variables
npm install
npm run dev

To regenerate the typed API client from the backend's Swagger spec:

npm run generate-api

Environment Variables

The backend uses the following environment variables for initial setup:

Variable Description Default
ADMIN_EMAIL Email for the auto-created admin user admin@localhost
ADMIN_PASSWORD Password for the admin user (required to create)
ADMIN_USERNAME Display name for the admin user Administrator
ConnectionStrings__DefaultConnection PostgreSQL connection string
CorsHosts Comma-separated allowed CORS origins
FrontEndHost Base URL of the frontend app, used to rewrite email links to frontend routes (/confirm-email, /confirm-password-reset) http://localhost:5173
EmailSettings__Host SMTP server hostname
EmailSettings__Port SMTP server port
EmailSettings__EnableSsl Whether to use SSL for SMTP
EmailSettings__Username SMTP username (also used as the sender address)
EmailSettings__Password SMTP password
DataProtection__StorageType Where to persist Data Protection keys: Database, AzureBlobStorage, or AwsSystemsManager Database
DataProtection__ProtectionType How to encrypt keys at rest: None, AzureKeyVault, AwsKms, or Certificate None
DataProtection__AzureBlobStorage__ConnectionString Azure Storage connection string
DataProtection__AzureBlobStorage__ContainerName Blob container name dataprotection
DataProtection__AzureBlobStorage__BlobName Blob name for the key file keys.xml
DataProtection__AwsSystemsManager__KeyPrefix SSM parameter path prefix /DataProtection/ConfigVault/
DataProtection__AwsSystemsManager__Region AWS region override (optional)
DataProtection__AzureKeyVault__KeyIdentifier Full Key Vault key URI (e.g. https://myvault.vault.azure.net/keys/dataprotection)
DataProtection__AzureKeyVault__TenantId Azure AD tenant ID for DefaultAzureCredential (optional)
DataProtection__AwsKms__KeyId KMS key ID, ARN, or alias (e.g. alias/configvault-dp)
DataProtection__Certificate__Thumbprint Certificate thumbprint (looked up in CurrentUser/My store)
DataProtection__Certificate__Path Path to a .pfx file (alternative to Thumbprint)
DataProtection__Certificate__Password Password for the .pfx file

These can also be set via appsettings.json:

{
  "FrontEndHost": "http://localhost:5173",
  "EmailSettings": {
    "Host": "smtp.example.com",
    "Port": 587,
    "EnableSsl": true,
    "Username": "no-reply@example.com",
    "Password": "your-smtp-password"
  },
  "DataProtection": {
    "StorageType": "Database",
    "ProtectionType": "None"
  }
}

Authorization Model

ConfigVault uses a layered permission system.

Global Roles control platform-level actions: Admin, User, CreateApplications, EditApplications, DeleteApplications.

Application Roles are flag-based and can be assigned at two levels:

Role Description
Read View configs and history
Write Create and update configs
Delete Delete configs
Rollback Rollback configs or environments
Tag Add/remove tags on versions
RegenerateKey Regenerate the application's API key
Decrypt View decrypted values of encrypted configs

Permissions can be granted globally for an application (all environments) or scoped to specific environments. Effective permissions are the union of application-level and environment-level grants. Admins bypass all permission checks.

API Overview

Authentication (/api/auth)

Method Endpoint Description
POST /api/auth/register Register a new user
POST /api/auth/login Login and get access + refresh tokens
POST /api/auth/refresh Refresh access token
GET /api/auth/confirmEmail Confirm email address
POST /api/auth/forgotPassword Request password reset
POST /api/auth/resetPassword Reset password
POST /api/auth/manage/2fa Manage two-factor authentication
GET /api/auth/manage/info Get user info

Application Management (/api/applications)

Method Endpoint Description
GET /api/applications List accessible applications
GET /api/applications/{name} Get application details
POST /api/applications Create new application (returns API key)
PUT /api/applications/{name} Update application
DELETE /api/applications/{name} Delete application and all configs
POST /api/applications/{name}/regenerate-key Regenerate API key

Configuration Management (/api/apps/{appName}/envs/{env}/configs)

Method Endpoint Description
GET /configs List all configs (optional ?keyPrefix=)
GET /configs/key/{key} Get config value
GET /configs/key/{key}/decrypt Get decrypted value
PUT /configs/key/{key} Create or update config
DELETE /configs/key/{key} Delete config
GET /configs/key/{key}/history Get version history
GET /configs/key/{key}/versions/{version} Get specific version
GET /configs/key/{key}/at?pointInTime=... Get config at point in time
GET /configs/key/{key}/diff?fromVersion=1&toVersion=2 Compare two versions
POST /configs/key/{key}/rollback Rollback config
POST /configs/key/{key}/versions/{v}/tag Add tag to version
DELETE /configs/key/{key}/versions/{v}/tag Remove tag

Environment Operations (/api/apps/{appName}/envs/{env})

Method Endpoint Description
GET /export Export all configs as JSON
POST /import Import configs from JSON
POST /rollback Rollback entire environment to a point in time
POST /rollback/tag/{tag} Rollback environment to a tagged snapshot
POST /copy-to/{targetEnv} Copy configs to another environment
POST /tag Tag all current configs in environment
DELETE /tag/{tag} Remove a tag from all configs
GET /tags List all tags used in environment

User Management (/api/users)

Method Endpoint Description
GET /me Get current user info, roles, and accesses
GET /me/applications Get current user's application accesses
GET /me/environments Get current user's environment accesses
GET /me/permissions/{appName}/{env} Get effective permissions
GET / List all users (Admin)
GET /{userId} Get user by ID (Admin)
POST / Create user (Admin)
PUT /{userId} Update user (Admin)
DELETE /{userId} Delete user (Admin)
PATCH /{userId}/active?isActive= Activate/deactivate user (Admin)
GET /{userId}/roles Get user's global roles (Admin)
POST /{userId}/roles/{role} Add global role (Admin)
DELETE /{userId}/roles/{role} Remove global role (Admin)
POST /{userId}/applications/{appName} Grant app access (Admin)
PUT /{userId}/applications/{appName} Update app access (Admin)
DELETE /{userId}/applications/{appName} Revoke app access (Admin)
POST /{userId}/applications/{appName}/environments/{env} Grant env access (Admin)
PUT /{userId}/applications/{appName}/environments/{env} Update env access (Admin)
DELETE /{userId}/applications/{appName}/environments/{env} Revoke env access (Admin)
GET /by-application/{appName} Get users with app access (Admin)

Client API (/api/client) — For Applications

Method Endpoint Description
GET /api/client/{appName}/{env} Get all configs (requires X-Api-Key header)
GET /api/client/{appName}/{env}/key/{key} Get specific config

Audit Logs (/api/audit)

Method Endpoint Description
GET /api/audit Query audit logs with filtering

Health Check

Method Endpoint Description
GET /health Health check endpoint

Configuration Key Conventions

ConfigVault uses the standard .NET configuration key format — colon-separated segments — which maps naturally to structured JSON when consumed by the .NET client. Understanding this convention lets you model objects, nested objects, and arrays as flat key-value pairs.

Objects

Use : to separate property levels. Each segment becomes a level of nesting in JSON.

Key Value
Smtp:Host smtp.example.com
Smtp:Port 587
Smtp:EnableSsl true

This is equivalent to:

{
  "Smtp": {
    "Host": "smtp.example.com",
    "Port": "587",
    "EnableSsl": "true"
  }
}

Nested Objects

Additional : segments create deeper nesting.

Key Value
Logging:LogLevel:Default Information
Logging:LogLevel:Microsoft Warning

Resolves to:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning"
    }
  }
}

Arrays / Lists

Use numeric indices (starting from 0) as the final key segment to represent array elements.

Key Value
AllowedHosts:0 example.com
AllowedHosts:1 api.example.com
AllowedHosts:2 cdn.example.com

Resolves to:

{
  "AllowedHosts": [
    "example.com",
    "api.example.com",
    "cdn.example.com"
  ]
}

Arrays of Objects

Combine numeric indices with named properties to create arrays of complex objects.

Key Value
DatabaseCluster:Nodes:0:Host db-primary.internal
DatabaseCluster:Nodes:0:Port 5432
DatabaseCluster:Nodes:0:Role primary
DatabaseCluster:Nodes:1:Host db-replica.internal
DatabaseCluster:Nodes:1:Port 5432
DatabaseCluster:Nodes:1:Role replica

Resolves to:

{
  "DatabaseCluster": {
    "Nodes": [
      { "Host": "db-primary.internal", "Port": "5432", "Role": "primary" },
      { "Host": "db-replica.internal", "Port": "5432", "Role": "replica" }
    ]
  }
}

Binding to C# Classes

Because ConfigVault's .NET client feeds directly into IConfiguration, you can bind these structured keys to strongly-typed options classes as usual:

public class SmtpOptions
{
    public string Host { get; set; }
    public int Port { get; set; }
    public bool EnableSsl { get; set; }
}

// In Program.cs
builder.Services.Configure<SmtpOptions>(builder.Configuration.GetSection("Smtp"));

Tip: When using the ?keyPrefix= query parameter on the list endpoint, you can fetch just a subtree of your config — for example ?keyPrefix=Smtp returns only keys starting with Smtp:.

Usage Examples

1. Register and Login

# Register
curl -X POST http://localhost:8080/api/auth/register \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@example.com", "password": "SecurePass123"}'

# Login
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "admin@example.com", "password": "SecurePass123"}'
# Returns: {"accessToken": "...", "refreshToken": "...", ...}

2. Create an Application

curl -X POST http://localhost:8080/api/applications \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-web-app",
    "description": "My Web Application",
    "allowedEnvironments": ["Development", "Staging", "Production"]
  }'
# Returns: {"applicationName": "my-web-app", "apiKey": "cv_...", ...}

3. Create Configuration Values

# Plain text config
curl -X PUT http://localhost:8080/api/apps/my-web-app/envs/Production/configs/key/Smtp:Host \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": "smtp.example.com", "changeReason": "Initial configuration"}'

# Encrypted config
curl -X PUT http://localhost:8080/api/apps/my-web-app/envs/Production/configs/key/Smtp:Password \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"value": "super-secret-password", "encrypt": true, "changeReason": "Setting SMTP password"}'

4. Rollback

# Rollback to specific version
curl -X POST http://localhost:8080/api/apps/my-web-app/envs/Production/configs/key/Smtp:Host/rollback \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"toVersion": 1, "reason": "Reverting due to issue"}'

# Rollback to point in time
curl -X POST ... \
  -d '{"toPointInTime": "2024-01-15T10:00:00Z", "reason": "Reverting to last known good state"}'

# Rollback to tagged version
curl -X POST ... \
  -d '{"toTag": "stable", "reason": "Reverting to stable version"}'

5. Tag a Version

curl -X POST http://localhost:8080/api/apps/my-web-app/envs/Production/configs/key/Smtp:Host/versions/3/tag \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tag": "stable"}'

6. Tag an Entire Environment

curl -X POST http://localhost:8080/api/apps/my-web-app/envs/Production/tag \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"tag": "release-v2.1", "reason": "Pre-deployment snapshot"}'

7. Client Application Reading Configs

# Get all configs
curl http://localhost:8080/api/client/my-web-app/Production \
  -H "X-Api-Key: cv_YOUR_API_KEY"
# Returns: {"Smtp:Host": "smtp.example.com", "Smtp:Password": "super-secret-password", ...}

# Get specific config
curl http://localhost:8080/api/client/my-web-app/Production/key/Smtp:Host \
  -H "X-Api-Key: cv_YOUR_API_KEY"
# Returns: {"key": "Smtp:Host", "value": "smtp.example.com"}

8. Bulk Import/Export

# Export
curl http://localhost:8080/api/apps/my-web-app/envs/Development/export \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Import
curl -X POST http://localhost:8080/api/apps/my-web-app/envs/Staging/import \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"Smtp:Host": "smtp.staging.example.com", "Smtp:Port": "587"}'

# Copy environment
curl -X POST "http://localhost:8080/api/apps/my-web-app/envs/Development/copy-to/Staging?overwrite=true" \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

9. User & Permission Management (Admin)

# Create a user
curl -X POST http://localhost:8080/api/users \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"email": "dev@example.com", "password": "DevPass123!", "roles": ["User"]}'

# Grant app-level Read + Write access
curl -X POST http://localhost:8080/api/users/{userId}/applications/my-web-app \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roles": 3}'

# Grant environment-specific access (e.g. Read only on Production)
curl -X POST http://localhost:8080/api/users/{userId}/applications/my-web-app/environments/Production \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"roles": 1}'

.NET Client Integration

ConfigVault ships a .NET IConfiguration provider for seamless integration. It supports automatic refresh and reads configs directly into your app's configuration pipeline.

// Basic usage
builder.Configuration.AddConfigVault(
    baseUrl: "http://localhost:8080",
    applicationName: "my-web-app",
    environment: builder.Environment.EnvironmentName,
    apiKey: Environment.GetEnvironmentVariable("CONFIGVAULT_API_KEY")!
);

// With options
builder.Configuration.AddConfigVault(
    baseUrl: "http://localhost:8080",
    applicationName: "my-web-app",
    environment: "Production",
    apiKey: "cv_...",
    configure: options =>
    {
        options.RefreshInterval = TimeSpan.FromMinutes(5);
        options.ThrowOnLoadFailure = true;
        options.HttpTimeout = TimeSpan.FromSeconds(30);
    }
);

// From existing configuration (reads ConfigVault:* keys)
builder.Configuration.AddConfigVault(builder.Configuration);

Data Protection Key Management

ConfigVault uses ASP.NET Core Data Protection to encrypt sensitive configuration values. By default, the encryption keys are stored in the database alongside your data. For production deployments, you can configure both where keys are stored and how they are protected at rest.

Storage and protection are independent — you can mix and match any storage provider with any protection provider (with the exception that AWS KMS protection requires AWS Systems Manager storage, since KMS encryption is applied through the SSM persistence layer).

Storage Providers

StorageType Description Required Config
Database Persisted to PostgreSQL via EF Core (default) None
AzureBlobStorage Stored in an Azure Blob Storage container AzureBlobStorage section
AwsSystemsManager Stored as AWS Systems Manager Parameter Store entries AwsSystemsManager section

Protection Providers

ProtectionType Description Required Config
None Keys stored unencrypted (default, suitable for development) None
AzureKeyVault Keys encrypted with an Azure Key Vault key AzureKeyVault section
AwsKms Keys encrypted with AWS KMS (requires AwsSystemsManager storage) AwsKms section
Certificate Keys encrypted with an X.509 certificate Certificate section

Example Configurations

Database + no protection (default / development):

{
  "DataProtection": {
    "StorageType": "Database",
    "ProtectionType": "None"
  }
}

Azure Blob Storage + Azure Key Vault:

{
  "DataProtection": {
    "StorageType": "AzureBlobStorage",
    "ProtectionType": "AzureKeyVault",
    "AzureBlobStorage": {
      "ConnectionString": "DefaultEndpointsProtocol=https;AccountName=...",
      "ContainerName": "dataprotection",
      "BlobName": "keys.xml"
    },
    "AzureKeyVault": {
      "KeyIdentifier": "https://myvault.vault.azure.net/keys/dataprotection"
    }
  }
}

Azure Key Vault authentication uses DefaultAzureCredential, which supports Managed Identity, Azure CLI, environment variables, and more. Optionally set TenantId to pin a specific tenant.

AWS Systems Manager + KMS:

{
  "DataProtection": {
    "StorageType": "AwsSystemsManager",
    "ProtectionType": "AwsKms",
    "AwsSystemsManager": {
      "KeyPrefix": "/DataProtection/ConfigVault/"
    },
    "AwsKms": {
      "KeyId": "alias/configvault-dataprotection"
    }
  }
}

AWS credentials are resolved through the default SDK credential chain (IAM role, environment variables, ~/.aws/credentials, etc.).

Database + Certificate protection:

{
  "DataProtection": {
    "StorageType": "Database",
    "ProtectionType": "Certificate",
    "Certificate": {
      "Path": "/etc/certs/dataprotection.pfx",
      "Password": "cert-password"
    }
  }
}

Alternatively, reference a certificate already installed in the CurrentUser/My store by thumbprint:

{
  "DataProtection": {
    "StorageType": "Database",
    "ProtectionType": "Certificate",
    "Certificate": {
      "Thumbprint": "A1B2C3D4..."
    }
  }
}

Database

PostgreSQL is the supported database, used with Entity Framework Core and automatic migrations on startup.

Connection string format:

Host=localhost;Database=configvault;Username=postgres;Password=yourpassword

Security Considerations

  1. API Keys — Store application API keys securely (environment variables, secrets manager). Keys are hashed before storage.
  2. Data Protection Keys — By default, encryption keys are stored unprotected in the database. For production, configure a protection provider (Azure Key Vault, AWS KMS, or a certificate) via the DataProtection config section. See Data Protection Key Management above.
  3. HTTPS — Always use HTTPS in production.
  4. CORS — Configure CorsHosts to restrict allowed origins.
  5. Admin Seeding — The first admin user is created from environment variables on startup only if no users exist.
  6. Password Policy — Requires 8+ characters with uppercase, lowercase, and digit. Account lockout after 5 failed attempts.

License

MIT License

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  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 is compatible.  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 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. 
.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.0.6 31 2/8/2026
1.0.5 36 2/8/2026
1.0.4 39 2/8/2026
0.0.0-alpha.0.66 35 2/8/2026