Skip to content

[Configuration] IConfigBuilder.Section<T> should not always register writable options by default #3004

@DevTKSS

Description

@DevTKSS

What would you like to be changed

IConfigBuilder.Section<T> currently always registers the section as IWritableOptions<T>, without providing a way to opt out.

Currently, every call to Section<T> implicitly registers IWritableOptions<T>:

.ConfigureServices((ctx, services) =>
{
var configPath = FilePath(ctx);
if (configPath is not { Length: > 0 })
{
return;
}
var section = configSection(ctx);
services.ConfigureAsWritable<TSettingsOptions>(section, configPath, configurationSection);
}

The default behaviour of Section<T> should be to register this section as read-only options only, unless writable behavior is explicitly requested.

Why is this needed

1. Principle of Least Privilege (PoLP)

Registering all sections as writable options introduces unnecessary elevated access by default.

As soon as IWritableOptions<T> is injected anywhere in DI, the corresponding configuration becomes mutable at runtime — even for options that are intended to be critical, security-relevant, or immutable by design.

Examples:

  • Authentication / authorization - you would also not have all Users as Admin by default for a good reason
  • Feature flags that should be read-only after startup
  • Environment- or deployment-critical configuration

In professional and business environments, the default should be minimum required access, not maximum possible access.

2. Accidental misuse risk

Because writable options are registered implicitly:

  • Developers may inject IWritableOptions<T> without realizing that mutation is must not be enabled on this Options Type used
  • Configuration mutability becomes a hidden side effect of calling Section<T>()
  • This increases the risk of unintended runtime configuration changes

3. API consistency & intent clarity

A good comparison is the Uno SDK feature registration:

  • Features are explicitly opted into
  • Not everything that could be enabled is enabled by default

Configuration mutability should follow the same principle:

Writable configuration should be explicit, not implicit.

Suggested solutions

Option A — Explicit opt-in parameter

Add an optional parameter to Section<T>:

Section<T>(..., bool registerWritable = false)

Pros

  • Clear intent at call site
  • Minimal API surface increase

Cons

  • Adds another parameter to an already commonly used method

Option B — Separate explicit extension (preferred if API surface is a concern)

Keep the current Section<T> behavior read-only by default, and provide a dedicated extension for writable registration, e.g.:

WritableSection<T>(...)

and by that:

provide access to the IServiceCollection.ConfigureAsWritable<T> in the IConfigBuilder where we are registring our Uno Configuration

or as extension:

Section<T>(...).AsWritable()

Pros

  • No breaking mental model
  • Clear separation of responsibility
  • Strongly signals elevated access

Platform impact

  • All platforms

Anything else we need to know?

This is not about removing functionality — only about making configuration mutability an explicit architectural decision for the consumer of this Extension, aligned with established security and clean-code principles.

Metadata

Metadata

Assignees

No one assigned

    Labels

    kind/enhancementNew feature or request.triage/untriagedIndicates an issue requires triaging or verification.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions