Gestione dei segreti
Conservi i segreti in modo sicuro usando .NET User Secrets durante lo sviluppo e Azure Key Vault o variabili d'ambiente in produzione.
Gestione dei segreti è una lezione C# Academy gratuita su CoddyKit. Questa è la lezione 4 di 4. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento C# Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso C# Academy include 4 lezioni in totale.
I segreti non sono configurazione
Password, chiavi API, stringhe di connessione e chiavi di firma JWT non devono mai essere archiviate in appsettings.json né inserite nel controllo del codice sorgente. .NET offre diversi meccanismi progettati appositamente per la gestione dei segreti.
User Secrets (sviluppo)
User Secrets archivia i segreti di sviluppo al di fuori della directory del progetto, in un file locale al computer. I segreti vengono caricati automaticamente nell'ambiente Development e non vengono mai distribuiti insieme al codice sorgente.
# 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.jsonCaricamento esplicito di User Secrets
Host.CreateApplicationBuilder carica automaticamente User Secrets in Development. È anche possibile caricarli esplicitamente negli scenari non-Development o nei progetti di test.
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();Variabili d'ambiente per la produzione
In produzione, inietti i segreti come variabili d'ambiente: vengono letti dal sistema operativo o dall'orchestratore dei container a runtime e non vengono mai salvati su disco in testo non crittografato insieme al codice.
# 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 }Integrazione con Azure Key Vault
Azure Key Vault è un archivio gestito di segreti per la produzione. Il provider ufficiale carica i segreti direttamente nel sistema di configurazione: l'applicazione li legge come qualsiasi altro valore di configurazione.
// 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
Su AWS, utilizzi Amazon.Extensions.Configuration.SystemsManager oppure Secrets Manager direttamente per iniettare i segreti nella pipeline di configurazione di .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
HashiCorp Vault offre segreti dinamici, rotazione dei segreti e controllo granulare degli accessi. Utilizzi la libreria della community VaultSharp o un provider di configurazione per integrarlo con .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;Protezione dei segreti in memoria
Anche in memoria, i segreti devono essere gestiti con attenzione. Utilizzi SecureString o ne limiti l'ambito con blocchi using, evitando di registrare nei log i valori dei segreti.
// 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
}Segreti in CI/CD
Le pipeline CI/CD (GitHub Actions, Azure DevOps, Jenkins) forniscono archivi di variabili segrete. Inietti i segreti come variabili d'ambiente al momento della compilazione o della distribuzione: non li codifichi mai direttamente nello YAML della pipeline.
# 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 plaintextCaso reale: strategia dei segreti per sviluppo e produzione
Una strategia completa per i segreti: User Secrets durante lo sviluppo, Azure Key Vault in produzione e variabili d'ambiente come alternativa di riserva.
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 rapida
Perché i segreti non devono mai essere archiviati in appsettings.json?
Riepilogo: gestione dei segreti
Concetti chiave:
- Non archivi mai i segreti in
appsettings.json: viene inserito nel controllo del codice sorgente - Sviluppo: utilizzi User Secrets (
dotnet user-secrets), archiviato al di fuori del progetto - Produzione: variabili d'ambiente, Azure Key Vault, AWS Secrets Manager o HashiCorp Vault
- CI/CD: archivi i segreti nell'archivio dei segreti della pipeline e iniettali come variabili d'ambiente
- Non registri mai nei log i valori grezzi dei segreti; utilizzi suggerimenti o mascheramenti
- Combini le strategie: User Secrets nello sviluppo + Key Vault in produzione + variabili d'ambiente come sovrascrittura
Domande Frequenti
La lezione «Gestione dei segreti» è gratuita?
Sì — il testo completo di «Gestione dei segreti» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso C# Academy, passa a CoddyKit PRO. Il corso C# Academy include 4 lezioni in totale.
Cosa imparerò in «Gestione dei segreti»?
Conservi i segreti in modo sicuro usando .NET User Secrets durante lo sviluppo e Azure Key Vault o variabili d'ambiente in produzione. Eserciti C# Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare C# Academy?
Non è richiesta alcuna esperienza precedente. C# Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 4 di 4.
Quanto tempo richiede la lezione «Gestione dei segreti»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione C# Academy?
Sì. Ogni lezione C# Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Fonti e provider di configurazione
- Opzioni fortemente tipizzate con IOptions
- Convalida delle opzioni e opzioni denominate
- Gestione dei segreti