Gerenciamento de segredos
Armazene segredos com segurança usando User Secrets do .NET no desenvolvimento e Azure Key Vault ou variáveis de ambiente em produção.
Gerenciamento de segredos é uma aula grátis de C# Academy no CoddyKit. Esta é a aula 4 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de C# Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de C# Academy inclui 4 aulas no total.
Segredos não são configuração
Senhas, chaves de API, cadeias de conexão e chaves de assinatura JWT nunca devem ser armazenadas em appsettings.json nem enviadas ao controle de código-fonte. O .NET fornece vários mecanismos específicos para o gerenciamento de segredos.
Segredos do usuário (desenvolvimento)
Os Segredos do usuário armazenam segredos de desenvolvimento fora do diretório do projeto, em um arquivo local da máquina. Eles são carregados automaticamente no ambiente Development e nunca acompanham o código-fonte.
# Initialize (adds UserSecretsId to .csproj):
dotnet user-secrets init
# Set secrets:
dotnet user-secrets set "Database:Password" "dev-pass-123"
dotnet user-secrets set "Jwt:SigningKey" "dev-jwt-key-abc"
dotnet user-secrets set "OpenAI:ApiKey" "sk-..."
# List / remove:
dotnet user-secrets list
dotnet user-secrets remove "OpenAI:ApiKey"
# Stored at:
# macOS/Linux: ~/.microsoft/usersecrets/{id}/secrets.json
# Windows: %APPDATA%\Microsoft\UserSecrets\{id}\secrets.jsonCarregamento explícito dos Segredos do usuário
Host.CreateApplicationBuilder carrega automaticamente os Segredos do usuário em Development. Você também pode carregá-los explicitamente em cenários que não sejam Development ou em projetos de teste.
var builder = Host.CreateApplicationBuilder(args);
// Automatic (Development only) — already done by default
// Equivalent manual call:
if (builder.Environment.IsDevelopment())
builder.Configuration.AddUserSecrets<Program>();
// In test projects (no ASPNETCORE_ENVIRONMENT):
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: true)
.AddUserSecrets<Program>() // loads secrets.json
.AddEnvironmentVariables()
.Build();Variáveis de ambiente para produção
Em produção, injete os segredos como variáveis de ambiente — eles são lidos do sistema operacional ou do orquestrador de contêineres durante a execução e nunca são persistidos em texto simples no disco junto ao código.
# docker-compose.yml — inject secrets:
services:
api:
image: myapp:latest
environment:
- Database__Password=${DB_PASSWORD} # from .env file
- Jwt__SigningKey=${JWT_KEY}
- ConnectionStrings__Default=Server=db;Password=${DB_PASSWORD}
# Kubernetes Secret:
kubectl create secret generic app-secrets \
--from-literal=Database__Password=secret123 \
--from-literal=Jwt__SigningKey=verylongkey
# Reference in pod spec:
# env:
# - name: Database__Password
# valueFrom:
# secretKeyRef: { name: app-secrets, key: Database__Password }Integração com o Azure Key Vault
O Azure Key Vault é um armazenamento gerenciado de segredos para produção. O provedor oficial carrega os segredos diretamente no sistema de configuração — seu aplicativo os lê como qualquer outro valor de configuração.
// dotnet add package Azure.Extensions.AspNetCore.Configuration.Secrets
// dotnet add package Azure.Identity
var builder = WebApplication.CreateBuilder(args);
if (!builder.Environment.IsDevelopment())
{
var kvUri = new Uri(builder.Configuration["Azure:KeyVaultUri"]!);
// Uses Managed Identity / workload identity in production:
builder.Configuration.AddAzureKeyVault(kvUri, new DefaultAzureCredential());
}
// Secrets named "Database--Password" in Key Vault
// are accessible as builder.Configuration["Database:Password"]
// (Key Vault uses -- as the : separator)AWS Secrets Manager
Na AWS, use Amazon.Extensions.Configuration.SystemsManager ou o Secrets Manager diretamente para injetar segredos no processo de configuração do .NET.
// dotnet add package Amazon.Extensions.Configuration.SystemsManager
builder.Configuration.AddSystemsManager(
path: "/myapp/production", // parameter store prefix
optional: false,
reloadAfter: TimeSpan.FromMinutes(30));
// Or Secrets Manager directly:
using Amazon.SecretsManager;
using Amazon.SecretsManager.Model;
var client = new AmazonSecretsManagerClient();
var response = await client.GetSecretValueAsync(new GetSecretValueRequest
{
SecretId = "myapp/production/db-password"
});
var secret = response.SecretString; // JSON string
// Parse and inject into configHashiCorp Vault
O HashiCorp Vault fornece segredos dinâmicos, rotação de segredos e controle de acesso detalhado. Use a biblioteca comunitária VaultSharp ou um provedor de configuração para integrá-lo ao .NET.
// dotnet add package VaultSharp
using VaultSharp;
using VaultSharp.V1.AuthMethods.Token;
var authMethod = new TokenAuthMethodInfo("vault-token");
var vaultClient = new VaultClient(
new VaultClientSettings("https://vault.example.com:8200", authMethod));
// Read a secret:
var kv = await vaultClient.V1.Secrets.KeyValue.V2
.ReadSecretAsync(path: "myapp/database", mountPoint: "secret");
var password = kv.Data.Data["password"].ToString();
// Then store in configuration or pass to IOptions:
builder.Configuration["Database:Password"] = password;Proteção de segredos na memória
Mesmo na memória, os segredos devem ser tratados com cuidado. Use SecureString ou limite o escopo com blocos using, e evite registrar valores de segredos.
// NEVER log secrets:
_logger.LogInformation("API Key: {Key}", apiKey); // WRONG!
_logger.LogInformation("API Key configured: {HasKey}", !string.IsNullOrEmpty(apiKey)); // CORRECT
// Mask in diagnostics:
public string KeyHint => apiKey.Length > 8
? $"{apiKey[..4]}...{apiKey[^4..]}"
: "****";
// Scope the secret:
void ProcessWithSecret()
{
var secret = LoadSecret();
try { UseSecret(secret); }
finally { secret = string.Empty; } // clear reference
}Segredos em CI/CD
Os processos de CI/CD (GitHub Actions, Azure DevOps, Jenkins) fornecem armazenamentos de variáveis secretas. Injete os segredos como variáveis de ambiente no momento da compilação ou implantação — nunca os codifique diretamente no YAML do processo.
# GitHub Actions — store in Settings > Secrets:
# name: Deploy
# on: push
# jobs:
# deploy:
# runs-on: ubuntu-latest
# env:
# Database__Password: ${{ secrets.DB_PASSWORD }}
# Jwt__SigningKey: ${{ secrets.JWT_KEY }}
# steps:
# - name: Run migration
# run: dotnet ef database update
# Azure Pipelines:
# variables:
# - group: my-app-secrets # from Azure DevOps Variable Group
# The secrets are masked in logs and never stored in plaintextExemplo do mundo real: estratégia de segredos para desenvolvimento e produção
Uma estratégia completa de segredos: Segredos do usuário no desenvolvimento, Azure Key Vault em produção e variáveis de ambiente como alternativa.
var builder = WebApplication.CreateBuilder(args);
if (builder.Environment.IsDevelopment())
{
// Dev: local secrets.json, never committed
builder.Configuration.AddUserSecrets<Program>();
}
else
{
// Production: Azure Key Vault via Managed Identity
var kvUri = builder.Configuration["Azure:KeyVaultUri"];
if (!string.IsNullOrEmpty(kvUri))
builder.Configuration.AddAzureKeyVault(
new Uri(kvUri), new DefaultAzureCredential());
}
// Always load env vars (works in all environments + containers):
// Already loaded by CreateBuilder — they override Key Vault
// Bind secrets to strongly typed options:
builder.Services
.AddOptions<JwtOptions>()
.BindConfiguration("Jwt")
.ValidateDataAnnotations()
.ValidateOnStart();Verificação rápida
Por que os segredos nunca devem ser armazenados em appsettings.json?
Recapitulação: gerenciamento de segredos
Principais conclusões:
- Nunca armazene segredos em
appsettings.json— ele é enviado ao controle de código-fonte - Desenvolvimento: use os Segredos do usuário (
dotnet user-secrets) — armazenados fora do projeto - Produção: variáveis de ambiente, Azure Key Vault, AWS Secrets Manager ou HashiCorp Vault
- CI/CD: armazene os segredos no armazenamento de segredos do processo e injete-os como variáveis de ambiente
- Nunca registre valores brutos de segredos; use dicas ou máscaras
- Combine estratégias: Segredos do usuário no desenvolvimento + Key Vault em produção + variáveis de ambiente como substituição
Perguntas Frequentes
A aula “Gerenciamento de segredos” é grátis?
Sim — o texto completo de “Gerenciamento de segredos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de C# Academy, atualize para CoddyKit PRO. O curso de C# Academy inclui 4 aulas no total.
O que vou aprender em “Gerenciamento de segredos”?
Armazene segredos com segurança usando User Secrets do .NET no desenvolvimento e Azure Key Vault ou variáveis de ambiente em produção. Você pratica C# Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.
Preciso ter experiência prévia para começar C# Academy?
Nenhuma experiência prévia é necessária. C# Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 4 de 4.
Quanto tempo leva a aula “Gerenciamento de segredos”?
A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.
Posso escrever e executar código nesta aula de C# Academy?
Sim. Cada aula de C# Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.
Todas as aulas deste curso
- Fontes e provedores de configuração
- Options fortemente tipadas com IOptions
- Validação de Options e Options nomeadas
- Gerenciamento de segredos