Chapter 24 · Security, Raw SQL, Secrets, Authorization Boundaries, and Abuse Resistance

Protect Connection Strings and Credentials with Environment Configuration and Secret Stores

Separate configuration from secrets, keep database credentials out of source and diagnostics, use .NET User Secrets only for local development, and adopt deployment-specific secret stores or identity-based authentication without making cloud services mandatory for the course lab.

Advanced180–240 minutessecrets/configuration labEF Core 10.0.11 · Microsoft.EntityFrameworkCore.Sqlite 10.0.11 · dotnet-ef 10.0.11 · .NET 10.0.11 · SDK 10.0.400Mandatory free local SQLite path · SQL Server/Azure SQL RLS and managed identity optional/provider-specificSecurity/package/platform status reviewed: August 27, 2026

Learning outcomes

01

Separate ordinary configuration values from secrets and identify which connection-string components create credential risk.

02

Use .NET User Secrets for local development without mistaking it for encrypted or production-grade storage.

03

Use environment variables carefully and explain why they are configuration transport, not guaranteed secret isolation.

04

Integrate deployment secret stores or identity-based authentication where available while preserving a free local path.

05

Rotate credentials and connection pools deliberately without logging raw connection strings.

06

Build tests and startup diagnostics that prove configuration source/shape without exposing secret values.

1. The connection string is part configuration, part authority

A database connection string may contain a server address, database name, encryption settings, application name, pool options, user name, password, access token mode, or local file path. Some fields are operational configuration; others are credentials. Treating the whole string as ordinary text risks committing secrets to Git, printing them in logs, copying production passwords into tests, or leaking them through exception diagnostics.

Threat model

Assume source repositories, build logs, support bundles, crash reports, test artifacts and developer chat transcripts may be seen by more people than the production database credential should be.

2. Keep committed appsettings free of credentials

appsettings.json · safe shape only
{  "ConnectionStrings": {    "ServiceHub": "Data Source=servicehub-lab.db"  },  "Database": {    "Provider": "Sqlite"  }}

The mandatory local SQLite path needs no password, which makes it ideal for course labs. For a server provider, commit only non-secret defaults or a configuration key name—never a production password, token, private key, or connection string containing one.

3. User Secrets: useful for development, intentionally not a vault

The .NET Secret Manager keeps development secrets outside the project tree so they are not normally checked into source control. Microsoft explicitly states that User Secrets values are not encrypted and the mechanism is for development only. The next snippet uses ASP.NET Core’s WebApplicationBuilder, which combines .NET configuration with dependency-injection registration; a console/worker host can consume the same configuration keys with the generic host/configuration packages.

CLI · local development secret
dotnet user-secrets initdotnet user-secrets set "ConnectionStrings:ServiceHubSqlServer"   "Server=localhost,1433;Database=ServiceHub;User Id=servicehub_dev;Password=local-dev-only;Encrypt=True;TrustServerCertificate=True"
C# · consume through configuration, never print the secret
var builder = WebApplication.CreateBuilder(args);var connectionString = builder.Configuration    .GetConnectionString("ServiceHubSqlServer")    ?? throw new InvalidOperationException("Database connection is not configured.");builder.Services.AddDbContext<ServiceHubContext>(options =>    options.UseSqlServer(connectionString));

Do not call Console.WriteLine(connectionString) to “verify” configuration. Instead, log a safe provider/environment label or perform a health check that reports success/failure without returning credentials.

4. Environment variables can override configuration, but may still be visible

.NET configuration uses environment variables naturally, including the cross-platform double-underscore separator. This avoids embedding a secret in the app package, but Microsoft warns that environment variables are commonly stored as plain text and can be read if the host/process is compromised.

Shell · deployment configuration example
export ConnectionStrings__ServiceHub="${SERVICEHUB_DB_CONNECTION}"export Database__Provider="PostgreSql"

Treat the environment as a transport mechanism whose security depends on the orchestrator/host. Restrict who can inspect deployment configuration and prefer a managed secret service when the platform provides one.

5. Production secret stores and managed identity are deployment choices

A production secret store centralizes secret access, audit, rotation and access policy. Azure Key Vault is one example; other clouds and on-premises platforms have equivalents. Identity-based database authentication can sometimes remove the database password from application configuration entirely—for example, Azure SQL with Microsoft Entra/managed identity—but that is provider/platform-specific and not mandatory for this course.

Environment Recommended pattern Important limitation
Local SQLite lab no credential; disposable file file contents/path may still be sensitive
Local server development .NET User Secrets or dedicated local secret tooling User Secrets are not encrypted
Container/CI CI secret injection + test-only credential avoid production secrets; mask logs/artifacts
Cloud production managed secret store and/or workload identity platform-specific setup and permissions
On-prem production enterprise secret manager / integrated auth where supported rotation and service identity must be operationally owned

6. Deliberate failure: “temporarily” commit the password and rely on deletion later

JSON · WRONG: credential in committed config
{  "ConnectionStrings": {    "ServiceHub": "Server=db.prod;Database=ServiceHub;User Id=app;Password=P@ssw0rd!"  }}

Deleting the line in a later commit does not erase repository history, forks, build logs, caches, screenshots, or copied artifacts. Treat an accidentally committed secret as compromised: revoke/rotate it, review access logs, then remove it from active configuration. History rewriting may reduce future exposure but does not make the old credential trustworthy again.

7. Rotation and pool behavior need an operational plan

Server-provider connection pools can keep physical connections alive after configuration changes. Rotating a credential therefore requires more than updating a secret store: deploy/reload safely, ensure new connections authenticate, and retire/clear old pooled connections according to the provider’s supported mechanism. Do not teach an arbitrary “restart everything” rule; test the chosen provider and hosting model.

Rotation runbook evidence
1. create/enable new credential or identity grant2. update secret reference / identity policy3. canary opens new connection successfully4. deploy/recycle according to provider pool behavior5. revoke old credential6. confirm authentication failures did not spike7. audit that old credential is no longer accepted

8. Safe startup and support diagnostics

Startup logs should record which provider/configuration mode is active, not the secret. A sanitized connection descriptor may include a known environment name and database logical name only if your threat model permits it. For SQLite, even a file path can reveal usernames or tenant locations, so classify it before logging.

C# · safe configuration status
logger.LogInformation(    "Database configured. Provider={Provider}; Environment={Environment}",    providerName,    app.Environment.EnvironmentName);// Never:// logger.LogInformation("Database={ConnectionString}", connectionString);

9. Mandatory lab: move a credential out of source and prove it stays out

  1. Keep the mandatory SQLite lab as the zero-secret baseline.
  2. Create a test-only server-provider connection string using a local account, never production credentials.
  3. Initialize .NET User Secrets and store the connection string there.
  4. Load it through IConfiguration; run a connectivity/migration-status probe without printing the string.
  5. Verify git diff/git grep over the exercise project contains no password/token.
  6. Override the same configuration key via an environment variable and explain the host-visibility risk.
  7. Write a rotation checklist for the chosen provider and remove the local test secret when finished.

10. Production judgment and bridge

Secrets management is lifecycle management: creation, delivery, use, logging discipline, rotation, revocation and audit. EF Core consumes a configured connection; it does not secure the credential store. Lesson 4 asks a more important question: once the application is connected, how much authority should that runtime identity actually have?

Check your understanding

  1. Why are .NET User Secrets not a production vault?
  2. Are environment variables automatically secure secret storage?
  3. What should happen after a credential is committed to Git?
  4. Why avoid logging a full connection string?
  5. What can managed identity change?
  6. Why does credential rotation interact with connection pooling?
Review the answers

1. They are development-only and are not encrypted; their purpose is to keep secrets outside the project tree/source control.

2. No. They can be plain text and may be visible to a compromised process/host or privileged operators.

3. Treat it as compromised: rotate/revoke it and investigate exposure; deleting the line later is insufficient.

4. It may contain passwords/tokens and can expose hosts, database names or filesystem paths useful to attackers.

5. Where supported, it can replace stored database passwords with identity-based authentication, but it is provider/platform-specific.

6. Existing physical connections can outlive a configuration change, so rotation must account for provider pool/reconnect behavior and verify new authentication.

Authoritative references

Keep knowledge open

Help the academy stay free and grow.

If these tutorials save you time, a small donation supports new lessons, technical review, diagrams, examples, and long-term maintenance.

ETHEthereum / ERC-20 only
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0

Send only Ethereum or ERC-20 compatible assets to this address.

\n