DOTNET Contents

Secrets Management for .NET Apps

Secrets are not config values. Learn how to manage connection strings, API keys, and signing secrets securely using environment isolation, secret stores, and rotation strategies.

On this page

Secrets Leak by Default

Connection strings. JWT signing keys. API tokens. Database passwords. If you treat them like normal configuration: - they end up in source control - they end up in logs - they end up in crash dumps - they end up in CI artifacts Production rule: Secrets must never live in code or static config files.

Real Production Incident

Symptoms: - Unexpected external API usage spike. - Billing alert triggered. - Investigation finds API key exposed in public Git repository. Root cause: - API key hardcoded in appsettings.json. - File committed to repository. - Repository mirrored publicly. This is not rare. It is common.

Symptom → Cause → Diagnosis → Fix

Symptom: - unauthorized third-party access - leaked credentials detected by scanners - production compromise via stolen secret Cause: - secrets stored in source control - secrets shared via chat/email - no rotation plan - no environment separation Diagnosis: - scan repositories for secrets. - audit CI logs and artifacts. - check appsettings.* files for credentials. - review environment variable usage. Fix: - move secrets to secure secret store. - inject secrets via environment or managed identity. - rotate exposed credentials immediately. - implement secret scanning in CI.

Anti-Pattern: appsettings.json With Secrets

{
  "ConnectionStrings": {
    "Default": "Server=...;User Id=...;Password=SuperSecret123"
  }
}
This will leak. Even if private repo: - backups - logs - contractor access - misconfiguration Production rule: appsettings.json must not contain production secrets.

Correct Pattern: Environment + Secret Store

Options: - Environment variables - Cloud secret managers - Kubernetes secrets (with caution) - Managed identity / workload identity Conceptual usage:
builder.Configuration
    .AddEnvironmentVariables();
And inject:
var connectionString = builder.Configuration["ConnectionStrings:Default"];
But: Environment variables are transport, not storage security. Use them to inject secrets from a secure store.

Rotation Strategy

Secrets expire. Keys rotate. Credentials get compromised. If you cannot rotate without downtime, you have operational debt. Best practice: - support overlapping keys (old + new) - update secret store first - deploy app using new secret - remove old secret after confirmation Production rule: Rotation must be testable and automated.

Do Not Log Secrets

Common leak vector: - logging full connection string - logging configuration dump - logging request headers (Authorization) Mitigation: - redact sensitive config values - never log raw tokens - use structured logging filters Production rule: Logs are semi-public. Treat them as such.

Secrets in Containers

If using containers: - do not bake secrets into image - inject at runtime - avoid writing secrets to disk if possible Kubernetes: - prefer external secret stores - avoid plain-text secrets in manifests - use RBAC to restrict secret access

Managed Identity / Federated Identity

Prefer: - identity-based access (e.g., workload identity) - avoid static credentials Instead of: - storing database password Use: - managed identity with role-based access Production rule: Static secrets are last resort.

Security Notes

- Enable secret scanning in CI. - Rotate secrets after any suspected exposure. - Limit blast radius (different secrets per environment). - Do not reuse secrets across services. Defense in depth: - secret store - environment injection - least privilege - monitoring access

Operational Notes

Monitoring: - track secret access events (if supported). - alert on unusual secret retrieval patterns. - audit configuration changes. Rollout: - test secret rotation in staging. - canary new secret before decommissioning old one. Rollback: - if new secret breaks connectivity, revert to previous valid secret quickly. - maintain versioned secret entries. Governance: - maintain secret inventory. - define ownership per secret. - define rotation interval per sensitivity level.

Checklist

- No production secrets stored in source code or appsettings files. - Secrets injected via environment or secure store. - Secret rotation strategy documented and tested. - Logs do not contain sensitive values. - Secrets separated per environment. - CI includes secret scanning. - Secret access monitored and auditable. - Secret changes are canaried and rollbackable.