- Criado DockerSecretsConfigurationProvider para ler secrets de /run/secrets/ - Removidas credenciais sensíveis do appsettings.Production.json - Adicionado indicador visual no rodapé (✓/✗) para verificar se secrets foram carregados - Atualizado deploy.yml para usar Docker Secrets no Swarm - Criado script create-docker-secrets.sh para gerenciar secrets - Criado template secrets.env.template para facilitar configuração - Documentação completa em DOCKER_SECRETS_SETUP.md Secrets gerenciados: - stripe_secret_key - stripe_webhook_secret - mongodb_connection_string - google_client_id / google_client_secret - microsoft_client_id / microsoft_client_secret IMPORTANTE: Após este deploy, é necessário criar os secrets no Swarm e recriar o service. Consulte DOCKER_SECRETS_SETUP.md. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
112 lines
3.9 KiB
C#
112 lines
3.9 KiB
C#
using Microsoft.Extensions.Configuration;
|
|
|
|
namespace QRRapidoApp.Configuration
|
|
{
|
|
/// <summary>
|
|
/// Configuration provider that reads Docker Secrets from /run/secrets/
|
|
/// Secrets are mounted as files in Swarm mode.
|
|
/// </summary>
|
|
public class DockerSecretsConfigurationProvider : ConfigurationProvider
|
|
{
|
|
private readonly string _secretsPath;
|
|
private readonly Dictionary<string, string> _secretKeyMappings;
|
|
|
|
public DockerSecretsConfigurationProvider(string secretsPath, Dictionary<string, string> secretKeyMappings)
|
|
{
|
|
_secretsPath = secretsPath;
|
|
_secretKeyMappings = secretKeyMappings;
|
|
}
|
|
|
|
public override void Load()
|
|
{
|
|
Data = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
|
|
|
if (!Directory.Exists(_secretsPath))
|
|
{
|
|
return;
|
|
}
|
|
|
|
var secretsLoaded = 0;
|
|
|
|
foreach (var mapping in _secretKeyMappings)
|
|
{
|
|
var secretFileName = mapping.Key;
|
|
var configKey = mapping.Value;
|
|
var secretFilePath = Path.Combine(_secretsPath, secretFileName);
|
|
|
|
if (File.Exists(secretFilePath))
|
|
{
|
|
try
|
|
{
|
|
var secretValue = File.ReadAllText(secretFilePath).Trim();
|
|
if (!string.IsNullOrEmpty(secretValue))
|
|
{
|
|
Data[configKey] = secretValue;
|
|
secretsLoaded++;
|
|
}
|
|
}
|
|
catch (Exception)
|
|
{
|
|
// Silently ignore read errors - will fall back to other config sources
|
|
}
|
|
}
|
|
}
|
|
|
|
// Set indicator that secrets were loaded from Docker
|
|
if (secretsLoaded > 0)
|
|
{
|
|
Data["App:SecretsLoaded"] = "true";
|
|
}
|
|
}
|
|
}
|
|
|
|
public class DockerSecretsConfigurationSource : IConfigurationSource
|
|
{
|
|
public string SecretsPath { get; set; } = "/run/secrets";
|
|
public Dictionary<string, string> SecretKeyMappings { get; set; } = new();
|
|
|
|
public IConfigurationProvider Build(IConfigurationBuilder builder)
|
|
{
|
|
return new DockerSecretsConfigurationProvider(SecretsPath, SecretKeyMappings);
|
|
}
|
|
}
|
|
|
|
public static class DockerSecretsConfigurationExtensions
|
|
{
|
|
/// <summary>
|
|
/// Adds Docker Secrets as a configuration source.
|
|
/// Maps secret file names to configuration keys.
|
|
/// </summary>
|
|
public static IConfigurationBuilder AddDockerSecrets(
|
|
this IConfigurationBuilder builder,
|
|
Action<DockerSecretsConfigurationSource>? configure = null)
|
|
{
|
|
var source = new DockerSecretsConfigurationSource
|
|
{
|
|
// Default mappings for QRRapido secrets
|
|
SecretKeyMappings = new Dictionary<string, string>
|
|
{
|
|
// Stripe
|
|
["stripe_secret_key"] = "Stripe:SecretKey",
|
|
["stripe_webhook_secret"] = "Stripe:WebhookSecret",
|
|
|
|
// MongoDB
|
|
["mongodb_connection_string"] = "ConnectionStrings:MongoDB",
|
|
|
|
// OAuth - Google
|
|
["google_client_id"] = "Authentication:Google:ClientId",
|
|
["google_client_secret"] = "Authentication:Google:ClientSecret",
|
|
|
|
// OAuth - Microsoft
|
|
["microsoft_client_id"] = "Authentication:Microsoft:ClientId",
|
|
["microsoft_client_secret"] = "Authentication:Microsoft:ClientSecret",
|
|
}
|
|
};
|
|
|
|
configure?.Invoke(source);
|
|
builder.Add(source);
|
|
return builder;
|
|
}
|
|
}
|
|
}
|