0Pricing
C# Academy · Lekcja

Zarządzanie sekretami

Bezpiecznie przechowuj sekrety, używając .NET User Secrets w środowisku deweloperskim oraz Azure Key Vault lub zmiennych środowiskowych na produkcji.

Zarządzanie sekretami to bezpłatna lekcja C# Academy na CoddyKit. To lekcja 4 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej C# Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs C# Academy zawiera 4 lekcji w sumie.

Sekrety to nie konfiguracja

Haseł, kluczy API, parametrów połączeń i kluczy podpisujących JWT nigdy nie należy przechowywać w appsettings.json ani zatwierdzać w systemie kontroli wersji. .NET udostępnia kilka mechanizmów przeznaczonych do zarządzania sekretami.

User Secrets (programowanie)

User Secrets przechowuje sekrety używane podczas programowania poza katalogiem projektu, w lokalnym dla komputera pliku. Są one automatycznie ładowane w środowisku Development i nigdy nie są przesyłane wraz z kodem źródłowym.

# 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.json

Jawne ładowanie User Secrets

Host.CreateApplicationBuilder automatycznie ładuje User Secrets w środowisku Development. Można je również załadować jawnie w scenariuszach innych niż Development albo w projektach testowych.

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();

Zmienne środowiskowe w produkcji

W środowisku produkcyjnym przekazuj sekrety jako zmienne środowiskowe — są one odczytywane w czasie działania z systemu operacyjnego lub orkiestratora kontenerów i nigdy nie są zapisywane na dysku w postaci jawnego tekstu obok kodu.

# 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 }

Integracja z Azure Key Vault

Azure Key Vault to zarządzany magazyn sekretów przeznaczony do środowisk produkcyjnych. Oficjalny dostawca ładuje sekrety bezpośrednio do systemu konfiguracji — aplikacja odczytuje je tak samo jak każdą inną wartość konfiguracji.

// 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

W AWS użyj bezpośrednio Amazon.Extensions.Configuration.SystemsManager lub Secrets Manager, aby wstrzykiwać sekrety do potoku konfiguracji .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 config

HashiCorp Vault

HashiCorp Vault udostępnia dynamiczne sekrety, rotację sekretów i szczegółową kontrolę dostępu. Użyj biblioteki społecznościowej VaultSharp lub dostawcy konfiguracji, aby zintegrować ją z .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;

Ochrona sekretów w pamięci

Nawet w pamięci z sekretami należy obchodzić się ostrożnie. Używaj SecureString albo ograniczaj ich zakres za pomocą bloków using i unikaj rejestrowania wartości sekretów.

// 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
}

Sekrety w CI/CD

Potoki CI/CD (GitHub Actions, Azure DevOps, Jenkins) udostępniają magazyny zmiennych sekretów. Wstrzykuj sekrety jako zmienne środowiskowe podczas budowania lub wdrażania — nigdy nie umieszczaj ich na stałe w plikach YAML potoku.

# 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 plaintext

Praktyczny przykład: strategia sekretów dla środowisk deweloperskiego i produkcyjnego

Kompletna strategia zarządzania sekretami: User Secrets podczas programowania, Azure Key Vault w produkcji oraz zmienne środowiskowe jako rozwiązanie awaryjne.

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();

Szybkie sprawdzenie

Dlaczego sekretów nigdy nie należy przechowywać w appsettings.json?

Podsumowanie: zarządzanie sekretami

Najważniejsze informacje:

  • Nigdy nie przechowuj sekretów w appsettings.json — ten plik trafia do systemu kontroli wersji
  • Programowanie: używaj User Secrets (dotnet user-secrets) — są przechowywane poza projektem
  • Produkcja: zmienne środowiskowe, Azure Key Vault, AWS Secrets Manager lub HashiCorp Vault
  • CI/CD: przechowuj sekrety w magazynie sekretów potoku i wstrzykuj je jako zmienne środowiskowe
  • Nigdy nie rejestruj surowych wartości sekretów; używaj podpowiedzi lub masek
  • Łącz strategie: User Secrets podczas programowania + Key Vault w produkcji + zmienne środowiskowe jako nadpisanie

Często zadawane pytania

Czy lekcja „Zarządzanie sekretami” jest bezpłatna?

Tak — pełny tekst „Zarządzanie sekretami” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu C# Academy, przejdź na CoddyKit PRO. Kurs C# Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Zarządzanie sekretami”?

Bezpiecznie przechowuj sekrety, używając .NET User Secrets w środowisku deweloperskim oraz Azure Key Vault lub zmiennych środowiskowych na produkcji. Ćwiczysz C# Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć C# Academy?

Nie wymagamy żadnego doświadczenia. C# Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 4 z 4.

Ile czasu zajmuje lekcja „Zarządzanie sekretami”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji C# Academy?

Tak. Każda lekcja C# Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Źródła i dostawcy konfiguracji
  2. Silnie typowane opcje z IOptions
  3. Walidacja opcji i opcje nazwane
  4. Zarządzanie sekretami
← Powrót do C# Academy