Modern .NET Development

Configuration and Feature Flags in ASP.NET Core

Configuration describes how a deployment should run; feature flags control which behaviour is exposed. Mixing them creates runtime changes the application cannot safely apply and flags that never die.

Feature flag rollout architecture

Not every setting should change at runtime

ASP.NET Core can combine JSON, environment variables, command-line values, secret stores and remote providers. That flexibility does not mean every value is reloadable. A timeout can affect future calls; changing a database schema assumption, encryption key or queue identity may require coordinated migration and restart.

Classify settings by owner, sensitivity, scope and change semantics. Startup-critical configuration should be validated before readiness. Runtime configuration needs an atomic update and failure policy. Product flags need rollout, observation and retirement.

Separate four different control planes

ControlExampleOwner
Deployment configurationEndpoint, timeout, regionPlatform/operations
SecretCredential or signing keySecurity/operations
Release flagExpose new checkoutEngineering/product
EntitlementCustomer purchased moduleCommercial domain

An entitlement is not a temporary feature flag and must be auditable business data. A secret is not ordinary configuration merely because both are read through an options class. Keeping the concepts separate gives changes appropriate approval and lifetime.

Application features switching on gradually
A safe rollout has deterministic targeting, observable outcomes, a kill path and a date when the flag disappears.

Options binding needs validation and ownership

Bind focused options around a capability, not one giant application settings object. Use data annotations or custom validators for required values, ranges and combinations, and validate critical options on start. A healthy process with an invalid payment endpoint is not ready.

IOptions<T> provides a stable value, snapshots are scoped, and monitors support change notification for long-lived services. Choose according to the consumer lifetime and whether the subsystem can genuinely react. A singleton cannot consume scoped snapshots safely.

A bound object can contain syntactically valid but operationally unusable values. Startup probes should not call every remote dependency, but configuration validation can parse URIs, enforce allowed schemes and reject impossible combinations without network access.

Provider precedence is part of the contract

Later configuration providers override earlier ones. Document the intended precedence so an environment variable does not silently defeat centrally managed production configuration. Log which provider supplied a non-secret setting where diagnosis requires it, but never log secret values.

Environment variable key syntax and array binding can behave differently across hosts. Test the packaged application with production-style inputs. Do not rely on a developer's local JSON file that is absent from the deployed artifact.

Fail on unknown or misspelled critical settings where practical. A typo that creates an unused key while the real option takes a default is more dangerous than a startup failure.

Secret rotation is a protocol

A secret store protects storage and access; it does not make rotation automatic. The application and downstream system may need an overlap in which old and new credentials both work. Cached tokens, connection pools and long-lived clients can retain old material.

Define rotation order, propagation delay, rollback and revocation. Use managed identity where available to avoid distributing credentials. Ensure secret values never appear in options validation errors, health responses or configuration dumps.

Feature flags are temporary branches in production

Each flag doubles a behavioural dimension in the code it controls. Nested flags multiply combinations that tests and operators must understand. Give every flag an owner, purpose, creation date, expected removal date and safe default. Remove the losing branch after rollout rather than building a permanent museum of old behaviour.

Evaluate a flag at a stable boundary and pass the decision through the operation. Re-evaluating halfway through a transaction can produce a hybrid workflow if configuration changes. For background jobs, persist the relevant variant or version when work is accepted if later execution must preserve the original decision.

Targeting must be deterministic and privacy-conscious

Percentage rollout needs a stable hash of flag and subject so the same user remains in one cohort. Random evaluation on each request creates flicker and makes failures irreproducible. Changing the hash key or algorithm can reshuffle the whole population.

Tenant targeting often fits business software better than user targeting because workflows and support operate at tenant scope. Avoid sending sensitive attributes to a flag service unnecessarily. Record the evaluated variant in traces without turning user identifiers into high-cardinality metrics.

Always define behaviour when the flag provider is unavailable. A remote call on every request makes product availability depend on the control plane. Cache evaluated configuration with a bounded age and choose fail-open or fail-closed per flag risk.

Kill switches are not release flags

A kill switch disables a risky dependency or behaviour during an incident. It needs a tested fast path, restricted authority and clear degraded experience. If switching it merely causes every request to fail differently, it is not operational resilience.

Security-sensitive controls should generally fail closed, while optional recommendations may fail open or disappear. Document the decision. Audit flag changes with actor, previous value, scope and reason; a flag can alter production behaviour as materially as a deployment.

Database migrations cannot be hidden by a flag

A flag can delay use of a new schema, but rolling deployments require old and new code to coexist. Apply additive schema first, deploy compatible code, enable behaviour gradually, then remove old fields later. Turning off the flag does not roll back destructive data migration.

Separate deployment from release, but keep rollback honest. If the new path has emitted events or transformed data, restoring old UI behaviour may not reverse those effects.

Test variants without testing every theoretical combination

Unit-test both branches while a flag exists. Add integration tests around the evaluation boundary and critical targeting rules. Pairwise or risk-based coverage is more practical than the full Cartesian product, but prohibit deeply nested flags that make combinations unknowable.

Production telemetry should compare completion, correctness, latency and error codes by variant. Decide success and abort thresholds before rollout. A percentage number is not evidence; outcomes are.

Production checklist

  • Classify configuration, secrets, release flags and entitlements separately.
  • Validate critical options before readiness.
  • Document provider precedence and production key syntax.
  • Reload only settings the subsystem can apply safely.
  • Give every flag ownership and removal criteria.
  • Use deterministic cohorts and stable evaluation boundaries.
  • Define provider-outage and safe-default behaviour.
  • Audit changes and restrict production authority.
  • Use expand-and-contract for schema-dependent releases.
  • Measure business and service outcomes per variant.

Related C3 Software guides

Frequently asked questions

Should ASP.NET Core configuration reload automatically?

Only when the consuming subsystem can apply the change atomically and safely. Many structural settings require restart or migration.

What should a feature flag default to during an outage?

Choose per risk: fail closed for sensitive controls and degrade safely for optional features. Do not leave the decision implicit.

Are customer entitlements feature flags?

No. Entitlements are durable auditable business data; temporary flags control release or operational behaviour.

When should a feature flag be removed?

As soon as rollout concludes and the fallback window closes. Removal criteria should exist when the flag is created.

Control change without creating permanent complexity

C3 Software Limited has built and supported business software in the UK since 2001. If runtime settings and flags are becoming hard to reason about, talk to C3 Software about a deployment review.