mirror of
https://github.com/aliasvault/aliasvault.git
synced 2026-05-12 01:13:30 -04:00
Update DataProtectionExtensions to load secrets from file when running under docker (#1098)
This commit is contained in:
committed by
Leendert de Borst
parent
3125eb3751
commit
c174a6bfb4
@@ -28,17 +28,8 @@ public static class DataProtectionExtensions
|
||||
this IServiceCollection services,
|
||||
string applicationName)
|
||||
{
|
||||
var certPassword = Environment.GetEnvironmentVariable("DATA_PROTECTION_CERT_PASS")
|
||||
?? throw new KeyNotFoundException("DATA_PROTECTION_CERT_PASS is not set in configuration or environment variables.");
|
||||
var certPath = $"../../certificates/app/{applicationName}.DataProtection.pfx";
|
||||
if (certPassword == "Development")
|
||||
{
|
||||
certPath = Path.Combine(AppContext.BaseDirectory, $"{applicationName}.DataProtection.Development.pfx");
|
||||
}
|
||||
|
||||
// Use different protection methods for containerized environments
|
||||
var isContainer = Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true" ||
|
||||
Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") == "Production";
|
||||
// Determine if running in a container
|
||||
var isContainer = Environment.GetEnvironmentVariable("DOTNET_RUNNING_IN_CONTAINER") == "true";
|
||||
|
||||
var dataProtectionBuilder = services.AddDataProtection()
|
||||
.PersistKeysToDbContext<AliasServerDbContext>()
|
||||
@@ -46,35 +37,77 @@ public static class DataProtectionExtensions
|
||||
|
||||
if (isContainer)
|
||||
{
|
||||
// When running in containers, don't use certificate-based key protection due to Linux keystore limitations
|
||||
// Keys are protected by database access controls, TLS, and container isolation
|
||||
dataProtectionBuilder
|
||||
.UseCryptographicAlgorithms(new Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration()
|
||||
{
|
||||
EncryptionAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC,
|
||||
ValidationAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256,
|
||||
})
|
||||
.SetDefaultKeyLifetime(TimeSpan.FromDays(90));
|
||||
ConfigureContainerDataProtection(dataProtectionBuilder);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use certificate-based protection for development
|
||||
var certificateFlags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable;
|
||||
|
||||
X509Certificate2 cert;
|
||||
if (!File.Exists(certPath))
|
||||
{
|
||||
cert = CertificateGenerator.GeneratePfx($"{applicationName}.DataProtection", certPassword);
|
||||
CertificateGenerator.SaveCertificateToFile(cert, certPassword, certPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
cert = X509CertificateLoader.LoadPkcs12FromFile(certPath, certPassword, certificateFlags);
|
||||
}
|
||||
|
||||
dataProtectionBuilder.ProtectKeysWithCertificate(cert);
|
||||
ConfigureDevelopmentDataProtection(dataProtectionBuilder, applicationName);
|
||||
}
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure data protection for container environments.
|
||||
/// </summary>
|
||||
/// <param name="dataProtectionBuilder">The data protection builder.</param>
|
||||
private static void ConfigureContainerDataProtection(IDataProtectionBuilder dataProtectionBuilder)
|
||||
{
|
||||
// In container, load password from file
|
||||
var certPassPath = "/secrets/data_protection_cert_pass";
|
||||
if (!File.Exists(certPassPath))
|
||||
{
|
||||
throw new KeyNotFoundException($"Certificate password file not found at {certPassPath}.");
|
||||
}
|
||||
|
||||
var certPassword = File.ReadAllText(certPassPath).Trim();
|
||||
if (string.IsNullOrEmpty(certPassword))
|
||||
{
|
||||
throw new KeyNotFoundException($"Certificate password file at {certPassPath} is empty.");
|
||||
}
|
||||
|
||||
// When running in containers, don't use certificate-based key protection due to Linux keystore limitations
|
||||
// Keys are protected by database access controls, TLS, and container isolation
|
||||
dataProtectionBuilder
|
||||
.UseCryptographicAlgorithms(new Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorConfiguration()
|
||||
{
|
||||
EncryptionAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.EncryptionAlgorithm.AES_256_CBC,
|
||||
ValidationAlgorithm = Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ValidationAlgorithm.HMACSHA256,
|
||||
})
|
||||
.SetDefaultKeyLifetime(TimeSpan.FromDays(90));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configure data protection for development environments.
|
||||
/// </summary>
|
||||
/// <param name="dataProtectionBuilder">The data protection builder.</param>
|
||||
/// <param name="applicationName">The application name.</param>
|
||||
private static void ConfigureDevelopmentDataProtection(IDataProtectionBuilder dataProtectionBuilder, string applicationName)
|
||||
{
|
||||
// Not in container, require environment variable
|
||||
var certPassword = Environment.GetEnvironmentVariable("DATA_PROTECTION_CERT_PASS")
|
||||
?? throw new KeyNotFoundException("DATA_PROTECTION_CERT_PASS is not set in configuration or environment variables.");
|
||||
|
||||
var certPath = $"../../certificates/app/{applicationName}.DataProtection.pfx";
|
||||
if (certPassword == "Development")
|
||||
{
|
||||
certPath = Path.Combine(AppContext.BaseDirectory, $"{applicationName}.DataProtection.Development.pfx");
|
||||
}
|
||||
|
||||
// Use certificate-based protection for development
|
||||
var certificateFlags = X509KeyStorageFlags.MachineKeySet | X509KeyStorageFlags.PersistKeySet | X509KeyStorageFlags.Exportable;
|
||||
|
||||
X509Certificate2 cert;
|
||||
if (!File.Exists(certPath))
|
||||
{
|
||||
cert = CertificateGenerator.GeneratePfx($"{applicationName}.DataProtection", certPassword);
|
||||
CertificateGenerator.SaveCertificateToFile(cert, certPassword, certPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
cert = X509CertificateLoader.LoadPkcs12FromFile(certPath, certPassword, certificateFlags);
|
||||
}
|
||||
|
||||
dataProtectionBuilder.ProtectKeysWithCertificate(cert);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user