C# Academy · Oppitunti

Salaisuuksien hallinta

Tallentakaa salaisuudet turvallisesti .NET User Secretsillä kehitysympäristössä sekä Azure Key Vaultilla tai ympäristömuuttujilla tuotannossa.

Oppitunti 4/412 vaihetta

Salaisuuksien hallinta on ilmainen C# Academy-oppitunti CoddyKitissä. Tämä on oppitunti 4/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu C# Academy-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. C# Academy-kurssilla on yhteensä 4 oppituntia.

Salaisuudet eivät ole konfiguraatiota

Salasanoja, API-avaimia, yhteysmerkkijonoja ja JWT-allekirjoitusavaimia ei saa koskaan tallentaa appsettings.json-tiedostoon tai viedä lähdekoodinhallintaan. .NET tarjoaa useita erityisesti salaisuuksien hallintaan suunniteltuja mekanismeja.

User Secrets (kehitys)

User Secrets säilyttää kehitysympäristön salaisuudet projektihakemiston ulkopuolella konekohtaisessa tiedostossa. Ne ladataan automaattisesti Development-ympäristössä, eivätkä ne koskaan kulje lähdekoodin mukana.

# 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

User Secrets -salaisuuksien lataaminen erikseen

Host.CreateApplicationBuilder lataa User Secrets -salaisuudet automaattisesti Development-ympäristössä. Voitte ladata ne myös erikseen muissa kuin Development-ympäristöissä tai testiprojekteissa.

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

Ympäristömuuttujat tuotannossa

Tuotannossa salaisuudet kannattaa välittää ympäristömuuttujina. Ne luetaan suorituksen aikana käyttöjärjestelmästä tai konttien orkestroijasta, eikä niitä tallenneta selväkielisinä levylle koodin yhteyteen.

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

Azure Key Vault -integraatio

Azure Key Vault on tuotantoon tarkoitettu hallittu salaisuuksien säilö. Virallinen provider lataa salaisuudet suoraan konfiguraatiojärjestelmään, joten sovellus lukee ne kuten minkä tahansa muun konfiguraatioarvon.

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

AWS-ympäristössä voitte käyttää Amazon.Extensions.Configuration.SystemsManager-pakettia tai suoraan Secrets Manageria salaisuuksien välittämiseen .NET-konfiguraatioputkeen.

// 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 tarjoaa dynaamisia salaisuuksia, salaisuuksien kierrätystä ja yksityiskohtaisen käyttöoikeuksien hallinnan. Integroikaa se .NETiin käyttämällä yhteisön VaultSharp-kirjastoa tai konfiguraatioprovideria.

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

Salaisuuksien suojaaminen muistissa

Salaisuuksia on käsiteltävä huolellisesti myös muistissa. Käyttäkää SecureString-tyyppiä tai rajoittakaa niiden näkyvyysaluetta using-lohkoilla ja välttäkää salaisuuksien arvojen kirjaamista lokiin.

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

Salaisuudet CI/CD-putkissa

CI/CD-putket (GitHub Actions, Azure DevOps, Jenkins) tarjoavat salaisuuksien muuttujasäilöjä. Välittäkää salaisuudet ympäristömuuttujina koonti- tai käyttöönottovaiheessa – älkää koskaan kirjoittako niitä kiinteästi putken YAML-tiedostoon.

# 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

Käytännössä: kehitys- ja tuotantoympäristön salaisuusstrategia

Täydellinen salaisuusstrategia: User Secrets kehityksessä, Azure Key Vault tuotannossa ja ympäristömuuttujat vararatkaisuna.

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

Pikatarkistus

Miksi salaisuuksia ei saa koskaan tallentaa appsettings.json-tiedostoon?

Yhteenveto: salaisuuksien hallinta

Tärkeimmät asiat:

  • Älkää koskaan tallentako salaisuuksia appsettings.json-tiedostoon – se viedään lähdekoodinhallintaan
  • Kehityksessä: käyttäkää User Secrets -salaisuuksia (dotnet user-secrets), jotka tallennetaan projektin ulkopuolelle
  • Tuotannossa: käyttäkää ympäristömuuttujia, Azure Key Vaultia, AWS Secrets Manageria tai HashiCorp Vaultia
  • CI/CD: tallentakaa salaisuudet putken salaisuussäilöön ja välittäkää ne ympäristömuuttujina
  • Älkää koskaan kirjatko raakoja salaisuuksien arvoja lokiin; käyttäkää vihjeitä tai peitteitä
  • Yhdistäkää strategiat: User Secrets kehityksessä, Key Vault tuotannossa ja ympäristömuuttujat ohituksina
Aloita maksutta

Opi C# tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
93
Oppitunnit
346

Usein kysytyt kysymykset

Onko oppitunti ”Salaisuuksien hallinta” ilmainen?

Kyllä – oppitunnin ”Salaisuuksien hallinta” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko C# Academy-kurssin, päivitä CoddyKit PROhon. C# Academy-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Salaisuuksien hallinta”?

Tallentakaa salaisuudet turvallisesti .NET User Secretsillä kehitysympäristössä sekä Azure Key Vaultilla tai ympäristömuuttujilla tuotannossa. Harjoittelet C# Academy-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni C# Academy-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin C# Academy-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 4/4.

Kuinka kauan ”Salaisuuksien hallinta”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä C# Academy-oppitunnilla?

Kyllä. Jokainen C# Academy-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. Konfiguraatiolähteet ja -tarjoajat
  2. Vahvasti tyypitetyt asetukset IOptionsilla
  3. Asetusten validointi ja nimetyt asetukset
  4. Salaisuuksien hallinta
← Takaisin: C# Academy