Feedemy.KeyManagement
2.5.1
See the version list below for details.
dotnet add package Feedemy.KeyManagement --version 2.5.1
NuGet\Install-Package Feedemy.KeyManagement -Version 2.5.1
<PackageReference Include="Feedemy.KeyManagement" Version="2.5.1" />
<PackageVersion Include="Feedemy.KeyManagement" Version="2.5.1" />
<PackageReference Include="Feedemy.KeyManagement" />
paket add Feedemy.KeyManagement --version 2.5.1
#r "nuget: Feedemy.KeyManagement, 2.5.1"
#:package Feedemy.KeyManagement@2.5.1
#addin nuget:?package=Feedemy.KeyManagement&version=2.5.1
#tool nuget:?package=Feedemy.KeyManagement&version=2.5.1
Feedemy.KeyManagement
Enterprise-grade key management library for .NET applications with versioned encryption, automatic rotation, distributed caching, and comprehensive audit logging.
Overview
Feedemy.KeyManagement provides a production-ready solution for managing cryptographic keys and sensitive configuration in .NET applications. It combines platform-specific secure storage with advanced features like automatic key rotation, version management, distributed caching, health monitoring, and full audit trails.
Key Features
- Versioned Encryption Format (v2.3.0+): Auto-decryption with version detection, backward compatibility
- Generic String-Based Keys: No hardcoded key names - fully application-agnostic
- Automatic Key Rotation: Background service with configurable intervals and health monitoring
- Asymmetric Key Support: RSA (2048/3072/4096-bit) and ECDSA (P-256/P-384/P-521) for signing and encryption
- Multi-Platform Secure Storage: Windows DPAPI, Linux AES-256-GCM, Azure Key Vault, InMemory
- High-Performance Caching: Redis/Memory cache with multi-layer strategy (< 1ms cache hits)
- Distributed Cache Invalidation: Pub/sub pattern for multi-server synchronization
- Database Persistence: SQL Server and PostgreSQL support with automatic migrations
- Master Key Encryption: Envelope encryption for sensitive keys
- Health Monitoring: Built-in ASP.NET Core health checks
- Fallback Storage: Multi-provider redundancy with automatic synchronization
- Audit Trail: Complete audit logging for compliance
- Roslyn Analyzers: 48 compile-time rules for security and best practices
- OpenTelemetry Integration: Metrics, traces, and structured logging
Production-Ready
- 100% Test Coverage: 450+ unit tests, 120+ integration tests
- Benchmark Tested: < 1ms cached retrieval, < 100ms rotation operations
- Battle-Tested: Used in production environments
- .NET 10.0: Latest framework support
Quick Start
Installation
# Core library
dotnet add package Feedemy.KeyManagement
# Persistence providers (choose one)
dotnet add package Feedemy.KeyManagement.Providers.EntityFramework # SQL Server
dotnet add package Feedemy.KeyManagement.Providers.Npgsql # PostgreSQL
# Optional: Analyzers for compile-time checks
dotnet add package Feedemy.KeyManagement.Analyzers
Basic Setup (Development)
using Feedemy.KeyManagement.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add KeyManagement with in-memory providers (development only)
builder.Services.AddKeyManagement(options =>
{
options.EnableAutoRotation = true;
options.RotationCheckInterval = TimeSpan.FromHours(6);
options.DefaultRotationDays = 90;
});
var app = builder.Build();
app.Run();
Production Setup (SQL Server + Redis + Azure Key Vault)
using Feedemy.KeyManagement.Extensions;
using StackExchange.Redis;
var builder = WebApplication.CreateBuilder(args);
// Configure Redis
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect("localhost:6379"));
// Add KeyManagement with production providers
builder.Services.AddKeyManagement(options =>
{
options.EnableAutoRotation = true;
options.RotationCheckInterval = TimeSpan.FromHours(6);
options.DefaultRotationDays = 90;
// Storage: Azure Key Vault
options.Storage.ProviderType = StorageProviderType.AzureKeyVault;
options.Storage.AzureKeyVaultUrl = "https://your-vault.vault.azure.net/";
// Cache: Redis with distributed invalidation
options.Cache.ProviderType = CacheProviderType.Redis;
options.Cache.RedisConnectionString = "localhost:6379";
})
.UseEntityFramework() // SQL Server persistence
.AddHealthChecks(); // ASP.NET Core health checks
// Add health check endpoint
builder.Services.AddHealthChecks()
.AddKeyManagementHealthCheck(
name: "key_management",
failureStatus: HealthStatus.Unhealthy,
tags: new[] { "security", "keys" });
var app = builder.Build();
app.MapHealthChecks("/health");
app.Run();
Basic Usage
public class MyService
{
private readonly IKeyManagementService _keyService;
private readonly IKeyManagementAdminService _adminService;
public MyService(
IKeyManagementService keyService,
IKeyManagementAdminService adminService)
{
_keyService = keyService;
_adminService = adminService;
}
// Create a new encryption key (admin operation)
public async Task CreateEncryptionKeyAsync()
{
var result = await _adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "MyEncryptionKey",
Description = "AES-256 encryption key for sensitive data",
AutoGenerate = true,
KeySize = 32, // 256 bits
RotationIntervalDays = 90,
AutoRotationEnabled = true,
MaxVersionsToRetain = 5,
Category = KeyCategory.Encryption,
SourceType = KeySourceType.Generated,
CreatedBy = "Admin"
});
if (result.Success)
{
Console.WriteLine($"Key created: {result.Data.KeyName} v{result.Data.CurrentVersion}");
}
}
// Retrieve key (cache-first, extremely fast)
public async Task<byte[]> GetEncryptionKeyAsync()
{
return await _keyService.RetrieveKeyAsync("MyEncryptionKey");
}
// Get key metadata
public async Task<KeyMetadata> GetKeyInfoAsync()
{
var metadata = await _keyService.GetKeyMetadataAsync("MyEncryptionKey");
Console.WriteLine($"Current Version: {metadata.CurrentVersion}");
Console.WriteLine($"Next Rotation: {metadata.NextRotationDue}");
Console.WriteLine($"Auto Rotation: {metadata.AutoRotationEnabled}");
return metadata;
}
// Check key health
public async Task MonitorKeyHealthAsync()
{
var health = await _keyService.GetKeyHealthAsync("MyEncryptionKey");
if (health.Status == KeyHealthStatus.NeedsRotation)
{
Console.WriteLine("WARNING: Key needs immediate rotation!");
}
else if (health.Status == KeyHealthStatus.Warning)
{
Console.WriteLine($"Key approaching rotation: {health.DaysUntilRotation} days remaining");
}
}
}
Core Features
1. Generic String-Based Keys (v3.0+)
The library is fully generic - no hardcoded key names. Applications define their own key names as strings.
// Create any key with any name
await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "MyCustomKey", // Any string you want
Description = "Application-specific key",
AutoGenerate = true,
KeySize = 32,
RotationIntervalDays = 90,
CreatedBy = "Admin"
});
// Retrieve by name
var key = await keyService.RetrieveKeyAsync("MyCustomKey");
Migration from v2.x: If you used hardcoded KeyName enums, replace them with strings:
KeyName.EncryptionKey→"EncryptionKey"keyName.ToKeyString()→ Direct string usage
2. Versioned Encryption Format
Auto-decryption with version detection for backward compatibility.
// Encrypt data (automatically adds version header)
var encryptedData = await encryptionService.EncryptAsync(plaintext, "MyKey");
// Decrypt (auto-detects version and decrypts accordingly)
var decryptedData = await encryptionService.DecryptAsync(encryptedData, "MyKey");
// Works even if key has been rotated - automatically uses correct version
Format: [VERSION_BYTE][ENCRYPTED_CONTENT]
- Version 1 (legacy): No version byte
- Version 2 (v2.3.0+):
0x01prefix + versioned encryption
3. Asymmetric Key Support (RSA & ECDSA)
Full support for digital signatures, JWT signing, and public key encryption.
Creating Asymmetric Keys
// RSA key for JWT signing
var rsaResult = await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "JwtSigningKey",
KeyType = KeyType.AsymmetricRSA,
RsaKeySize = RsaKeySize.Rsa2048,
Category = KeyCategory.Signing,
Description = "RSA key for JWT RS256 tokens",
AutoRotationEnabled = true,
RotationIntervalDays = 180,
CreatedBy = "System"
});
// ECDSA key for document signing
var ecdsaResult = await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "DocumentSigningKey",
KeyType = KeyType.AsymmetricECDSA,
EcdsaCurve = EcdsaCurve.P256,
Category = KeyCategory.Signing,
Description = "ECDSA key for document signatures",
CreatedBy = "Admin"
});
Using Asymmetric Keys
public class JwtService
{
private readonly IAsymmetricKeyOperations _asymmetricOps;
public JwtService(IAsymmetricKeyOperations asymmetricOps)
{
_asymmetricOps = asymmetricOps;
}
// Sign JWT token
public async Task<string> CreateJwtTokenAsync(Dictionary<string, object> claims)
{
var payload = JsonSerializer.SerializeToUtf8Bytes(claims);
// Sign with RS256
var signature = await _asymmetricOps.SignAsync(
"JwtSigningKey",
payload,
HashAlgorithmName.SHA256);
return EncodeJwt(payload, signature);
}
// Verify JWT token
public async Task<bool> VerifyJwtTokenAsync(string token)
{
var (payload, signature) = DecodeJwt(token);
// Verify using cached public key (very fast - ~0.15ms)
return await _asymmetricOps.VerifyAsync(
"JwtSigningKey",
payload,
signature,
HashAlgorithmName.SHA256);
}
// Export public key for clients
public async Task<string> GetPublicKeyPemAsync()
{
// Safe to expose publicly
return await _asymmetricOps.GetPublicKeyPemAsync("JwtSigningKey");
}
}
Supported Algorithms:
| Algorithm | Key Sizes | Use Case | Performance |
|---|---|---|---|
| RSA | 2048, 3072, 4096-bit | Signing, Encryption | Sign: ~1.2ms, Verify: ~0.15ms |
| ECDSA | P-256, P-384, P-521 | Signing (compact) | Sign: ~0.35ms, Verify: ~0.12ms |
4. Automatic Key Rotation
Background service automatically rotates keys based on configured intervals.
// Enable in configuration
builder.Services.AddKeyManagement(options =>
{
options.EnableAutoRotation = true;
options.RotationCheckInterval = TimeSpan.FromHours(6);
options.DefaultRotationDays = 90;
});
// Per-key configuration
await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "ApiKey",
RotationIntervalDays = 90, // Rotate every 90 days
AutoRotationEnabled = true, // Enable auto-rotation
MaxVersionsToRetain = 5, // Keep last 5 versions
// ...
});
// Monitor rotation status
var status = await adminService.GetRotationServiceStatusAsync();
Console.WriteLine($"Keys Pending Rotation: {status.KeysPendingRotation.Count}");
Rotation Flow:
- Background service checks every
RotationCheckInterval - Identifies keys where
NextRotationDue <= Now - Generates new key content
- Saves to storage and database
- Invalidates all cache layers
- Triggers cache warming
- Logs audit entry
5. Health Monitoring
Built-in ASP.NET Core health checks for monitoring system health.
// Add health checks
builder.Services.AddHealthChecks()
.AddKeyManagementHealthCheck(
name: "key_management",
failureStatus: HealthStatus.Unhealthy,
tags: new[] { "security", "keys" });
// Map endpoint
app.MapHealthChecks("/health");
Health Status Levels:
- Healthy: All keys operational, > 30 days until rotation
- Degraded: Warning keys detected (7-30 days until rotation)
- Unhealthy: Critical keys (rotation overdue) or system failure
Response Example:
{
"status": "Healthy",
"totalKeys": 15,
"healthyKeys": 13,
"warningKeys": 2,
"criticalKeys": 0,
"storageProvider": "Azure Key Vault",
"storageAvailable": true,
"checks": {
"key_management": {
"status": "Healthy",
"description": "Key management system is healthy"
}
}
}
6. Distributed Caching with Redis
Multi-layer caching with distributed invalidation for multi-server deployments.
// Configure Redis
builder.Services.AddSingleton<IConnectionMultiplexer>(
ConnectionMultiplexer.Connect("localhost:6379"));
builder.Services.AddKeyManagement(options =>
{
options.Cache.ProviderType = CacheProviderType.Redis;
options.Cache.RedisConnectionString = "localhost:6379";
});
// Configure cache invalidation options
builder.Services.Configure<KeyManagementCacheOptions>(options =>
{
options.EnableDistributedInvalidation = true;
options.InvalidationChannel = "keymanagement:invalidation";
options.EnableCacheWarming = true;
options.MaxConcurrentWarmingTasks = 5;
});
Cache Layers:
- Content Cache:
key:{KeyName}:content:v{Version}(1-hour TTL) - Metadata Cache:
key:{KeyName}:metadata(5-min TTL) - Version Cache:
key:{KeyName}:versions(5-min TTL)
Invalidation Flow:
- Server 1 rotates key
- Publishes invalidation message to Redis pub/sub
- All servers receive notification
- Each server clears local cache
- Cache warming preloads critical keys
7. Database Persistence
SQL Server and PostgreSQL support with automatic migrations.
SQL Server (EntityFramework)
builder.Services.AddKeyManagement(options => { /* ... */ })
.UseEntityFramework();
// Migrations are applied automatically on startup
// Tables created: KeyMetadata, KeyVersions, KeyAuditLogs, SchemaVersion
PostgreSQL (Npgsql)
builder.Services.AddKeyManagement(options => { /* ... */ })
.UseNpgsql("Host=localhost;Database=mydb;Username=user;Password=pass");
// Automatic migrations for PostgreSQL
Database Tables:
KeyManagement.KeyMetadata: Key configuration and current versionKeyManagement.KeyVersions: Version history with content hashesKeyManagement.KeyAuditLogs: Complete audit trailKeyManagement.SchemaVersion: Migration tracking
8. Platform-Specific Storage
Automatic selection of the best storage provider for your platform.
Windows DPAPI
builder.Services.AddKeyManagement(options =>
{
options.Storage.ProviderType = StorageProviderType.WindowsCredentialManager;
});
- Location:
%LOCALAPPDATA%\Feedemy\Keys - Encryption: Windows Data Protection API (DPAPI)
- Scope: CurrentUser
- Security: Protected by Windows ACLs + DPAPI encryption
Linux AES-256-GCM
builder.Services.AddKeyManagement(options =>
{
options.Storage.ProviderType = StorageProviderType.LinuxKeyring;
});
- Location:
~/.feedemy-keys/ - Encryption: AES-256-GCM with machine-specific key
- Key Derivation: PBKDF2-SHA256 (100,000 iterations) from
/etc/machine-id - File Permissions: 600 (owner read/write only)
Azure Key Vault
builder.Services.AddKeyManagement(options =>
{
options.Storage.ProviderType = StorageProviderType.AzureKeyVault;
options.Storage.AzureKeyVaultUrl = "https://your-vault.vault.azure.net/";
});
- Authentication: DefaultAzureCredential (Managed Identity or Client Secret)
- Retry Policy: 3 attempts with exponential backoff
- Security: Managed by Azure, hardware security modules (HSM) optional
Auto-Detection
builder.Services.AddKeyManagement(options =>
{
options.Storage.ProviderType = StorageProviderType.Auto; // Default
});
Automatically selects Windows DPAPI on Windows, Linux AES-GCM on Linux.
9. Fallback Storage
Multi-provider redundancy with automatic synchronization.
builder.Services.AddKeyManagement(options =>
{
options.Storage.ProviderType = StorageProviderType.Fallback;
options.Storage.Fallback.PrimaryProvider = StorageProviderType.AzureKeyVault;
options.Storage.Fallback.FallbackProvider = StorageProviderType.WindowsCredentialManager;
options.Storage.Fallback.EnableAutoSync = true;
options.Storage.Fallback.SyncOnStartup = true;
});
Benefits:
- Automatic failover if primary storage fails
- Background synchronization between providers
- Zero-downtime migrations
10. Master Key Encryption
Envelope encryption for sensitive keys.
// Create master encryption key
await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "EncryptionKey", // Master key
AutoGenerate = true,
KeySize = 32,
RotationIntervalDays = 90,
CreatedBy = "System"
});
// Create encrypted key
await adminService.CreateKeyAsync(new CreateKeyRequest
{
KeyName = "DatabaseEncryptionKey",
RequiresMasterKeyEncryption = true, // Encrypted with master key
AutoGenerate = true,
KeySize = 32,
CreatedBy = "System"
});
Re-encryption after master key rotation:
// Detect version mismatches
var mismatches = await adminService.GetEnvKeysWithVersionMismatchAsync();
// Re-encrypt automatically handled by rotation service
Advanced Features
Version Management
// Get all versions
var versions = await keyService.GetKeyVersionsAsync("ApiKey");
foreach (var version in versions)
{
Console.WriteLine($"Version {version.Version}: {version.Status}");
}
// Retrieve specific version
var oldKey = await keyService.RetrieveKeyByVersionAsync("ApiKey", version: 3);
// Rollback to previous version
var rollbackResult = await adminService.RollbackToVersionAsync(
keyName: "ApiKey",
targetVersion: 3,
reason: "Revert after incident",
performedBy: "Admin");
Audit Logging
// Get audit history
var logs = await adminService.GetAuditLogsAsync(
keyName: "ApiKey",
fromDate: DateTime.UtcNow.AddMonths(-1));
foreach (var log in logs)
{
Console.WriteLine($"{log.Timestamp}: {log.Action} by {log.PerformedBy}");
Console.WriteLine($" Reason: {log.Reason}");
}
Audit Operations Tracked:
- KeyCreated
- KeyUpdated
- KeyRotated
- KeyDeactivated
- KeyReactivated
- VersionDeactivated
- VersionReactivated
- RollbackPerformed
- ConfigurationUpdated
Cache Warming
// Configure cache warming
builder.Services.Configure<KeyManagementCacheOptions>(options =>
{
options.EnableCacheWarming = true;
options.MaxConcurrentWarmingTasks = 5;
});
// Manually warm cache for specific keys
await keyService.WarmCacheAsync(new[] { "ApiKey", "JwtSigningKey" });
Roslyn Analyzers
48 compile-time rules for security and best practices.
dotnet add package Feedemy.KeyManagement.Analyzers
Example Rules:
- KM0001: Empty key name (Error)
- KM0002: Invalid rotation interval (Warning)
- KM0101: Hardcoded key content (Warning)
- KM0103: Key exposure in logs (Warning)
- KM0104: Insecure storage in production (Warning)
- KM0203: Key retrieval in loop (Warning)
Disable specific rules:
#pragma warning disable KM0101
var key = new byte[] { ... };
#pragma warning restore KM0101
See ANALYZER_RULES.md for complete list.
Configuration
KeyManagementOptions
builder.Services.AddKeyManagement(options =>
{
// Auto-rotation
options.EnableAutoRotation = true;
options.RotationCheckInterval = TimeSpan.FromHours(6);
options.DefaultRotationDays = 90;
// Master key name (default: "EncryptionKey")
options.MasterEncryptionKeyName = "EncryptionKey";
// Storage
options.Storage.ProviderType = StorageProviderType.Auto;
options.Storage.AzureKeyVaultUrl = "https://your-vault.vault.azure.net/";
// Cache
options.Cache.ProviderType = CacheProviderType.Redis;
options.Cache.RedisConnectionString = "localhost:6379";
// Persistence
options.Persistence.ProviderType = PersistenceProviderType.EntityFramework;
// Initialization
options.Initialization.EnableAutoInitialization = true;
options.Initialization.ExternalKeysJsonPath = "keys.json";
});
KeyManagementCacheOptions
builder.Services.Configure<KeyManagementCacheOptions>(options =>
{
// Distributed invalidation
options.EnableDistributedInvalidation = true;
options.InvalidationChannel = "keymanagement:invalidation";
options.PubSubTimeoutSeconds = 5;
// Cache warming
options.EnableCacheWarming = true;
options.MaxConcurrentWarmingTasks = 5;
// Retry
options.MaxInvalidationRetries = 3;
options.RetryDelayMilliseconds = 100;
});
Environment Variables
# Core settings
KeyManagement__EnableAutoRotation=true
KeyManagement__RotationCheckInterval=06:00:00
KeyManagement__DefaultRotationDays=90
# Storage
KeyManagement__Storage__ProviderType=AzureKeyVault
KeyManagement__Storage__AzureKeyVaultUrl=https://your-vault.vault.azure.net/
# Cache
KeyManagement__Cache__ProviderType=Redis
KeyManagement__Cache__RedisConnectionString=localhost:6379
# Cache options
KeyManagementCache__EnableDistributedInvalidation=true
KeyManagementCache__InvalidationChannel=keymanagement:invalidation
Performance
Benchmark Results (BenchmarkDotNet)
| Method | Mean | Allocated |
|---------------------------|------------|-----------|
| RetrieveKey_Cached | 0.85 μs | 96 B |
| RetrieveKey_CacheMiss | 12.3 ms | 1.2 KB |
| GetMetadata_Cached | 0.62 μs | 48 B |
| GetCurrentVersion_Cached | 0.58 μs | 32 B |
| CreateKey | 85.2 ms | 4.5 KB |
| RotateKey | 95.7 ms | 5.2 KB |
| SignData_RSA2048 | 1.2 ms | 512 B |
| VerifySignature_RSA2048 | 0.15 ms | 256 B |
| SignData_ECDSA_P256 | 0.35 ms | 384 B |
| VerifySignature_ECDSA_P256| 0.12 ms | 192 B |
Run benchmarks:
cd benchmarks/Feedemy.KeyManagement.Benchmarks
dotnet run -c Release
Testing
Unit Tests (450+)
cd tests/Feedemy.KeyManagement.Tests
dotnet test
Coverage:
- Core services (KeyManagementService, KeyManagementAdminService)
- Domain services (Health, Validation, Versioning, Encryption)
- Cache services (Multi-layer, Invalidation, Warming)
- Storage coordination
- Repository patterns
- Background services
Integration Tests (120+)
cd tests/Feedemy.KeyManagement.IntegrationTests
dotnet test
Coverage:
- End-to-end workflows
- Cache invalidation propagation
- Automatic rotation
- Rollback scenarios
- Provider integration (SQL Server, PostgreSQL, Redis, Azure KV)
- Asymmetric key operations (RSA, ECDSA)
Architecture
See ARCHITECTURE.md for detailed architecture diagrams, component descriptions, and data flow.
High-Level Architecture
┌─────────────────────────────────────────────────────────┐
│ APPLICATION LAYER │
│ Controllers / Services / Background Jobs │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────┴──────────────┐
│ │
┌───────▼─────────┐ ┌─────────▼────────────┐
│ IKeyManagement │ │ IKeyManagementAdmin │
│ Service │ │ Service │
│ (Read Ops) │ │ (Write Ops) │
└───────┬─────────┘ └─────────┬────────────┘
│ │
└──────────────┬──────────────┘
│
┌──────────────────────▼──────────────────────────────────┐
│ DOMAIN SERVICES LAYER │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Health │ │ Validation │ │ Versioning │ │
│ │ Calculator │ │ Service │ │ Service │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Encryption │ │ Rotation │ │ Storage │ │
│ │Orchestrator│ │ Service │ │Coordinator │ │
│ └────────────┘ └────────────┘ └────────────┘ │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────────────────▼──────────────────────────────────┐
│ INFRASTRUCTURE SERVICES LAYER │
│ ┌────────────┬────────────┬────────────┐ │
│ │ Cache │ Storage │ Persistence│ │
│ │ - Redis │ - DPAPI │ - SQL │ │
│ │ - Memory │ - Azure KV │ - Postgres │ │
│ │ - Invalidation│ - Linux AES│ - InMemory│ │
│ └────────────┴────────────┴────────────┘ │
└─────────────────────────────────────────────────────────┘
Migration Guides
From v2.x to v3.0
Breaking Changes:
- Removed
KeyNameenum - use strings instead - Removed
ToKeyString()andToKeyName()extension methods WarmCriticalKeysAsync()now requiresstring[]parameter
Migration Steps:
// Before (v2.x)
await keyService.RetrieveKeyAsync(KeyName.EncryptionKey);
var keyString = KeyName.EncryptionKey.ToKeyString();
// After (v3.0)
await keyService.RetrieveKeyAsync("EncryptionKey");
var keyString = "EncryptionKey"; // Direct string usage
See MIGRATION_GUIDE.md for complete migration instructions.
Documentation
- Architecture Guide - System architecture and data flows
- Migration Guide - Version migration instructions
- Analyzer Rules - Complete list of Roslyn analyzer rules
- Telemetry - OpenTelemetry integration guide
NuGet Packages
| Package | Version | Description |
|---|---|---|
| Feedemy.KeyManagement | 2.5.0 | Core library |
| Feedemy.KeyManagement.Providers.EntityFramework | 2.5.0 | SQL Server persistence |
| Feedemy.KeyManagement.Providers.Npgsql | 2.5.0 | PostgreSQL persistence |
| Feedemy.KeyManagement.Analyzers | 2.5.0 | Roslyn analyzers |
Roadmap
- HashiCorp Vault provider
- AWS Secrets Manager provider
- Multi-region replication
- Key import/export utilities
- Grafana dashboard templates
- Performance profiling tools
Contributing
Contributions are welcome! Please follow these guidelines:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Ensure all tests pass:
dotnet test - Submit a pull request
Code Style:
- Follow .NET coding conventions
- Use nullable reference types
- Add XML documentation for public APIs
- Write unit tests for business logic
- Write integration tests for workflows
License
MIT License - see LICENSE file for details.
Copyright (c) 2025 Feedemy
Support
- Documentation: GitHub Wiki
- Issues: GitHub Issues
- Discussions: GitHub Discussions
Acknowledgments
Built with:
| Product | Versions 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. |
-
net10.0
- Azure.Identity (>= 1.17.1)
- Azure.Security.KeyVault.Secrets (>= 4.8.0)
- Microsoft.Data.SqlClient (>= 6.1.3)
- Microsoft.EntityFrameworkCore.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Caching.Memory (>= 10.0.0)
- Microsoft.Extensions.DependencyInjection.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Diagnostics.HealthChecks (>= 10.0.0)
- Microsoft.Extensions.Hosting.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Logging.Abstractions (>= 10.0.0)
- Microsoft.Extensions.Options (>= 10.0.0)
- OpenTelemetry.Api (>= 1.14.0)
- Polly (>= 8.6.5)
- StackExchange.Redis (>= 2.10.1)
NuGet packages (3)
Showing the top 3 NuGet packages that depend on Feedemy.KeyManagement:
| Package | Downloads |
|---|---|
|
Feedemy.KeyManagement.Providers.Npgsql
PostgreSQL (Npgsql) persistence provider for Feedemy.KeyManagement. Provides PostgreSQL storage for key metadata, versions, and audit logs with migrations support. Platform-independent alternative to SQL Server. |
|
|
Feedemy.KeyManagement.Providers.EntityFramework
Entity Framework Core persistence provider for Feedemy.KeyManagement. Provides SQL Server storage for key metadata, versions, and audit logs with migrations support. Fully tested with 56/56 integration tests passing. |
|
|
Feedemy.KeyManagement.Providers.Sqlite
SQLite persistence provider for Feedemy.KeyManagement. Provides lightweight, file-based storage for key metadata, versions, and audit logs. Ideal for development, testing, and single-server deployments. |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 3.1.0 | 84 | 3/9/2026 | |
| 3.0.6 | 73 | 3/9/2026 | |
| 3.0.5 | 90 | 3/9/2026 | |
| 3.0.4 | 80 | 3/9/2026 | |
| 3.0.3 | 111 | 3/9/2026 | |
| 3.0.2 | 99 | 3/9/2026 | |
| 3.0.1 | 110 | 2/27/2026 | |
| 2.5.10 | 230 | 1/21/2026 | |
| 2.5.9 | 154 | 1/10/2026 | |
| 2.5.8 | 106 | 1/10/2026 | |
| 2.5.7 | 104 | 1/9/2026 | |
| 2.5.6 | 101 | 1/9/2026 | |
| 2.5.5 | 132 | 1/6/2026 | |
| 2.5.4 | 133 | 1/4/2026 | |
| 2.5.3 | 239 | 1/3/2026 | |
| 2.5.2 | 1,424 | 12/1/2025 | |
| 2.5.1 | 1,051 | 12/1/2025 | |
| 2.5.0 | 1,043 | 12/1/2025 |
v3.0.0 - Generic Library Refactor (BREAKING CHANGES)
BREAKING CHANGES:
- Removed KeyName enum - library is now fully generic and string-based
- Removed all KeyName enum overloads from interfaces (IKeyManagementService, IKeyManagementAdminService, IKeyRotationService)
- Removed KeyNameExtensions (ToKeyString(), ToKeyName())
- Removed KeyConfigurationExtensions with application-specific key configurations
- Applications must now provide their own key names as strings
- WarmCriticalKeysAsync() now requires string[] parameter (no default hardcoded keys)
MIGRATION GUIDE:
- Replace: KeyName.AKey → "AKey" (or your custom key name)
- Replace: keyName.ToKeyString() → keyName (direct string usage)
- Replace: KeyName.EncryptionKey → "EncryptionKey"
- Provide your own KeyConfiguration for each key instead of using GetKeyConfiguration()
- Pass critical key names to WarmCriticalKeysAsync(string[] criticalKeyNames)
WHY THIS CHANGE:
- Library was not truly generic - contained application-specific business logic
- Hardcoded key names (AKey, CKey, OKey, LidioDeliverySecrets, NetGSM_AppKey, etc.)
- Applications can now use ANY key names without library modifications
- Follows true library design principles - zero business logic coupling
IMPORTANT: This is a major version bump due to breaking API changes. Review migration guide before upgrading.