-
Notifications
You must be signed in to change notification settings - Fork 59
Description
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>:
uno.extensions/src/Uno.Extensions.Configuration/ConfigBuilderExtensions.cs
Lines 155 to 166 in 9e1337c
| .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.