int Priority { get; }
Source
Higher number means higher priority. When multiple providers provide the same key, the one with the highest priority wins.
Validates resolved Config{T} and ConfigStruct{T} values with DataAnnotations. The validator returns immediately for null values and scalar primitives, validates object and field annotations before initialization completes, and traverses nested members only when callers opt in with ValidateObjectMembersAttribute or ValidateEnumeratedItemsAttribute. Recursive traversal tracks the active object path by reference so cycles terminate while shared objects can still be reported at each reachable path. AppSurface owns this traversal and the ConfigurationValidationException shape; the custom validator type overloads on the Microsoft Options marker attributes are reported as unsupported failures rather than invoked.
void Validate(string key, Type configType, Type valueType, object? value)
Source
Validates a resolved configuration value and throws ConfigurationValidationException when DataAnnotations failures are found. Call this after provider/default resolution and before config initialization is considered complete. Null and scalar values short-circuit, recursive validation is marker-gated, and callers should catch ConfigurationValidationException to inspect the structured failures.
keyThe configuration key being initialized.configTypeThe concrete configuration wrapper type being initialized.valueTypeThe resolved value type that is being validated.valueThe resolved provider or default value.ConfigurationValidationExceptionThrown when the resolved value or an opted-in nested value violates DataAnnotations validation rules.Defines a provider that can retrieve configuration values.
T? GetValue<T>(string environment, string key)
Source
Retrieves a configuration value for a specific environment and key.
TThe type of the configuration value.environmentThe environment name (e.g., "Production").keyThe configuration key.The configuration value, or the default value of T if not found.
ConfigurationResolutionExceptionThrown by aggregating managers when a provider reports a terminal, display-safe diagnostic for the requested key.Plain providers return the default value of T when a key is absent. Aggregating managers such as IConfigManager may throw ConfigurationResolutionException instead when a fail-closed provider reports that it owns the key but cannot safely return a value, for example because a local secret store is locked, unavailable, unsupported, or disabled by posture. Catch that exception at host, command, or diagnostics boundaries when rendering provider guidance to users.
int Priority { get; }
Source
Higher number means higher priority. When multiple providers provide the same key, the one with the highest priority wins.
string Name { get; }
Source
Gets the name of the configuration provider.
Provides object-graph patching for configuration providers that can supply child values beneath a requested key.
This is an internal provider seam, not a consumer-facing configuration API. DefaultConfigManager uses it after direct provider resolution so hierarchical override sources can update only the supplied child values instead of replacing an entire options object.
bool TryPatch<T>(string environment, string key, T? currentValue, out T? patchedValue)
Source
Attempts to apply provider-owned child values beneath key to currentValue.
TThe requested configuration value type.environmentThe active environment name.keyThe configuration key whose child values may be present.currentValueThe value supplied by a lower-priority provider, or default.patchedValueWhen this method returns true, contains the patched value. Otherwise contains default.true when at least one child value was applied.
Converts textual configuration provider values into AppSurface configuration value types.
Providers that store text, such as local secret stores and remote secret managers, should use this helper so scalar, enum, Guid, and JSON object conversion stay consistent. The helper intentionally returns a boolean instead of exposing raw parse exception messages because provider diagnostics must not leak secret payloads.
bool TryConvert<T>(string raw, out T? value)
Source
Attempts to convert raw into T.
TThe requested configuration type.rawThe raw provider text.valueThe converted value when conversion succeeds.true when conversion succeeds.
bool TryConvert(string raw, Type targetType, out object? value)
Source
Attempts to convert raw into targetType.
rawThe raw provider text.targetTypeThe requested configuration type.valueThe converted value when conversion succeeds.true when conversion succeeds.
Produces structured configuration audit reports.
Reporters inspect known configuration keys, provider provenance, validation diagnostics, and redacted display values. Implementations should return a report with diagnostics for recoverable provider and wrapper failures rather than throwing after argument validation succeeds.
ConfigAuditReport GetReport(string environment)
Source
Builds a configuration audit report for environment.
environmentThe environment to audit.The completed audit report.
Default implementation that mirrors configuration resolution while preserving source and diagnostic metadata.
This internal reporter treats IEnvironmentConfigProvider as the override provider, excludes manager/internal provider registrations from the displayed provider list, and favors wrapper-discovered audit entries when duplicate keys are registered manually. Manual audit option assignments override wrapper-discovered options per property so callers can intentionally reset a wrapper default for one key. Provider failures are converted into diagnostics so one broken provider does not prevent operators from seeing the rest of the report.
Captures a provider's value resolution result before wrapper inspection and redaction.
KeyThe configuration key being resolved.StateThe provider-level resolution state.ValueThe resolved raw value, or null when missing or invalid.SourcesThe sources that contributed to the value.DiagnosticsDiagnostics emitted while resolving the value.The reporter uses this internal contract to keep value state, provenance, and diagnostics together while it walks providers in precedence order. Missing values should be represented with Missing(string).
ConfigValueResolution Missing(string key)
Source
Creates a missing resolution with a synthetic missing source record for key.
keyThe missing configuration key.A missing resolution that can still be rendered with provenance.
IReadOnlyList<ConfigAuditSourceRecord> AuditSources { get; init; }
Source
Gets the sources used for child-entry source selection.
ConfigAuditFactContext AuditFacts { get; init; }
Source
Gets internal provenance facts used to attach proof-limited diagnostics while traversing child entries.
Describes the result of tracing environment patches onto an existing provider value.
PatchedA value indicating whether any member was patched.ValueThe patched value, or the original/current value when unchanged.SourcesThe environment sources that successfully patched the value.DiagnosticsDiagnostics produced while reading patch candidates.IReadOnlyList<ConfigPatchProvenanceFact> Facts { get; init; }
Source
Gets internal patch-time provenance facts for child audit diagnostics.
Describes one environment patch fact before it is converted into public audit diagnostics.
ConfigPathThe source-style config path affected by the environment source.SourceThe environment source that supplied the value.ActionThe patch action that produced the final value.PriorPresenceThe lower-priority/provider presence evidence for the same config path.Indexes internal audit provenance facts by source-style config path for traversal.
IReadOnlyList<ConfigPatchProvenanceFact> GetFacts(string configPath)
Source
Gets all facts associated with configPath.
configPathThe source-style config path to inspect.Facts for the path, or an empty list when none are known.
ConfigAuditFactContext Empty { get; }
Source
Gets the shared immutable empty fact context for callers that have no provenance facts to report.
Use this instance to avoid allocations when traversal should emit no fact-derived child diagnostics. The context contains no path entries and is never modified after construction.
Describes wrapper inspection after provider resolution.
ValueThe value to display and expand after defaulting or validation.StateThe wrapper-adjusted state, or null to keep provider state.DefaultSourceThe default source when the wrapper supplied a fallback value.DiagnosticsValidation and wrapper diagnostics.Allows providers to expose audit-specific resolution details and report-level diagnostics.
Implementations should avoid throwing for expected parse or source errors and return diagnostics instead. The reporter catches unexpected exceptions and converts them into provider diagnostics.
ConfigValueResolution Resolve(string environment, string key, Type valueType, ConfigAuditSourceRole role)
Source
Resolves key for audit reporting without losing source metadata.
environmentThe environment being audited.keyThe configuration key.valueTypeThe expected value type.roleThe role the provider plays in final resolution.The provider-specific resolution result.
IReadOnlyList<ConfigAuditDiagnostic> GetReportDiagnostics(string environment)
Source
Gets diagnostics that apply to the whole report rather than one key.
environmentThe environment being audited.Report-level diagnostics. Return an empty list when there are none.
Allows providers to expose their effective keys for audit reporting.
This contract is internal in v1 so provider-specific enumeration semantics can settle before AppSurface exposes a public extension API. Implementations should enumerate the provider's effective view for the requested environment and return diagnostics instead of throwing for expected source problems.
IReadOnlyList<ConfigAuditProviderDiscoveredKey> EnumerateKeys(string environment)
Source
Enumerates effective provider-discovered configuration keys for environment.
environmentThe environment being audited.Discovered provider keys with redaction-ready scalar values and source metadata.
Describes one provider-discovered key before public classification and redaction.
KeyThe discovered configuration key.RawValueThe scalar CLR value used for display redaction, or null for object/array parents.ValueKindThe provider value shape.SourcesSources associated with the effective key.DiagnosticsDiagnostics specific to this discovered key.Carries the discovered-value display decision used while projecting provider-discovered keys.
DisplayValueThe formatted scalar value, or null when the value is omitted.IsRedactedWhether the formatted value came from a redaction decision.DisplayStateWhy the value is shown, redacted, or omitted.This helper keeps the formatted value, redaction flag, and ConfigAuditDiscoveredValueDisplayState synchronized before they enter ConfigAuditDiscoveredKey. DisplayValue may be null for omitted states, so callers must branch on DisplayState instead of inferring intent from nullability. Pitfall: a null display value is not an error, and renderers or logs must preserve the redaction and display-state decision ordering rather than recomputing value visibility.
Allows an override provider to trace member-level patches onto a base provider value.
The environment provider uses this to explain mixed provenance for object values without mutating the provider instance that supplied the base value.
ConfigPatchDiagnosticResult TracePatch(string environment, string key, object? currentValue, Type valueType)
Source
Traces patch candidates for key and returns a cloned patched value when possible.
environmentThe environment being audited.keyThe configuration key.currentValueThe lower-priority provider value to patch, when any.valueTypeThe expected value type.The patch result, including successful patch sources and diagnostics.
Allows config wrappers to add defaults and validation diagnostics to an audit entry.
Implementations receive the raw provider value and should return structured diagnostics rather than throwing for validation failures. Unexpected exceptions are caught by the wrapper implementations.
ConfigWrapperInspection Inspect(string key, object? rawValue, ConfigAuditEntryState resolutionState)
Source
Inspects a resolved value for defaults and validation.
keyThe configuration key.rawValueThe raw provider value, or null when missing.resolutionStateThe state determined during provider resolution.The wrapper inspection result.
Identifies how an environment source changed the final audited value.
Describes whether lower-priority provider evidence proved a path existed before the environment override.
Identifies the provider value shape used while building discovered-key reports.
Values are explicit and append-only so external provider audit enumerators can report inventory shape without exposing provider-private parser details.
Renders ConfigAuditDiffReport instances as deterministic, human-readable text.
The renderer only renders sanitized diff evidence. By default it summarizes file paths to reduce support-bundle exposure; set ConfigAuditDiffOptions.SourceDetail to ConfigAuditDiffSourceDetail.Full before comparing when operators need the full source details already present in the audit reports.
string Render(ConfigAuditDiffReport report)
Source
Renders a config audit diff report.
reportThe diff report to render.A deterministic text report.
Applies the built-in audit redaction and value formatting policy.
Matching is fragment based and case-insensitive across keys, config paths, applied paths, and environment variable names. Sensitive values are replaced with a fixed placeholder before rendering. Non-sensitive complex values, including collections, may produce a null display value so callers can rely on source records and supported child entries instead of an unsafe dump. Formatting failures are swallowed intentionally to keep audit generation best-effort.
ConfigAuditRedaction CreatePolicy(ConfigAuditDictionaryKeyCorrelationOptions? correlationOptions = null, bool dictionaryKeyCorrelationRequested = false)
Source
Creates a snapshot of the redaction policy applied to reports.
correlationOptionsThe dictionary key correlation options used to describe report metadata.dictionaryKeyCorrelationRequestedWhether at least one known entry requested dictionary key correlation.A policy snapshot with a copy of the sensitive fragments and the placeholder text.
RedactedValue FormatValue(string key, object? value, IReadOnlyList<ConfigAuditSourceRecord> sources, ConfigAuditSensitivity entrySensitivity = ConfigAuditSensitivity.Unknown)
Source
Formats value for display and redacts it when the key or sources look sensitive.
keyThe configuration key being formatted.valueThe resolved value, if any.sourcesThe sources that contributed to the value.entrySensitivityThe entry-level sensitivity classification for this value.The display value and whether it was replaced by the redaction placeholder.
Describes a formatted value after applying the redaction policy.
DisplayValueThe safe display value, or null for non-scalar objects.IsRedactedA value indicating whether the placeholder replaced the original value.Configures a config audit report comparison.
Options affect evidence wording, renderer detail, and whether unchanged items are retained. They do not cause provider resolution, host startup, or command execution.
ConfigAuditDiffEvidenceMode EvidenceMode { get; set; }
Source
Gets or sets the evidence mode for this comparison.
bool IncludeUnchangedItems { get; set; }
Source
Gets or sets a value indicating whether unchanged items should be included in ConfigAuditDiffReport.Items.
ConfigAuditDiffSourceDetail SourceDetail { get; set; }
Source
Gets or sets the source-detail level used by the text renderer.
Describes the result of comparing two sanitized config audit reports.
The report contains only evidence already present in the input audit reports plus comparison diagnostics. It is safe to serialize as a support artifact subject to the same sensitivity rules as ConfigAuditReport: source paths, provider names, environment names, and correlation identifiers may still be support-sensitive.
string BaselineEnvironment { get; init; }
Source
Gets the baseline report environment.
string TargetEnvironment { get; init; }
Source
Gets the target report environment.
DateTimeOffset GeneratedAt { get; init; }
Source
Gets the time when the diff report was generated.
ConfigAuditDiffEvidenceMode EvidenceMode { get; init; }
Source
Gets the evidence mode used for this comparison.
ConfigAuditDiffSourceDetail SourceDetail { get; init; }
Source
Gets the source-detail level requested for renderer output.
ConfigAuditDiffSummary Summary { get; init; }
Source
Gets aggregate item counts for this diff.
IReadOnlyList<ConfigAuditComparisonDiagnostic> Diagnostics { get; init; }
Source
Gets comparison diagnostics that apply to the whole diff.
IReadOnlyList<ConfigAuditDiffItem> Items { get; init; }
Source
Gets deterministic diff items retained for rendering or programmatic inspection.
Summarizes item counts for a config audit diff.
int Changed { get; init; }
Source
Gets the number of changed items.
int Added { get; init; }
Source
Gets the number of added items.
int Removed { get; init; }
Source
Gets the number of removed items.
int Unchanged { get; init; }
Source
Gets the number of unchanged items, even when unchanged items are not retained.
int Uncomparable { get; init; }
Source
Gets the number of uncomparable items.
int Diagnostics { get; init; }
Source
Gets the number of comparison diagnostics.
Describes one display-safe config audit comparison diagnostic.
Diagnostics explain uncertainty, duplicate evidence, default/manual enum values, and evidence-mode warnings. They are intended for rendering and support triage, not for leaking raw provider exception messages.
ConfigAuditDiagnosticSeverity Severity { get; init; }
Source
Gets the diagnostic severity.
string Code { get; init; }
Source
Gets the stable diagnostic code.
string Message { get; init; }
Source
Gets the display-safe diagnostic message.
string? Key { get; init; }
Source
Gets the affected item path or key, when available.
Describes one item in a config audit diff.
Items keep baseline and target evidence separate so renderers can explain uncertainty without implying raw equality. Empty source and diagnostic lists mean the original report did not provide that evidence for the item.
ConfigAuditDiffItemKind Kind { get; init; }
Source
Gets the kind of audit evidence represented by this item.
ConfigAuditDiffItemStatus Status { get; init; }
Source
Gets the comparison status.
ConfigAuditDiffSignificance Significance { get; init; }
Source
Gets the review significance.
string Key { get; init; }
Source
Gets the deterministic item key or path.
string Description { get; init; }
Source
Gets an operator-facing display-safe description.
string? BaselineDisplayValue { get; init; }
Source
Gets the baseline display value, when the audit report rendered one.
string? TargetDisplayValue { get; init; }
Source
Gets the target display value, when the audit report rendered one.
ConfigAuditDiffValueEvidence ValueEvidence { get; init; }
Source
Gets the value-evidence classification.
IReadOnlyList<ConfigAuditSourceRecord> BaselineSources { get; init; }
Source
Gets baseline source records attached to this item.
IReadOnlyList<ConfigAuditSourceRecord> TargetSources { get; init; }
Source
Gets target source records attached to this item.
IReadOnlyList<ConfigAuditComparisonDiagnostic> Diagnostics { get; init; }
Source
Gets item-level comparison diagnostics.
Selects how much trust the diff should attach to the two audit reports being compared.
Evidence mode changes diagnostics and wording only. ConfigAuditReportDiffer still compares two already-built ConfigAuditReport objects and never re-resolves configuration providers.
Identifies the comparison status for one diff item.
Values are explicit and append-only so serialized diff reports remain stable across releases.
Classifies how urgently an item should be reviewed.
Identifies the kind of audit evidence represented by a diff item.
Selects how source paths should be rendered by ConfigAuditDiffTextRenderer.
Explains how much value-level evidence is available for one compared item.
Describes a display-safe failure from ConfigAuditDiffCommandRunner.
Failures intentionally omit raw exception messages because provider, parser, and renderer exceptions can contain attempted values, file paths, or environment-specific details. Command wrappers should display these fields instead of printing the original exception.
string ToDisplayString()
Source
Formats this failure for command-line display.
A display-safe multiline failure message.
ConfigAuditDiffFailureStage Stage { get; }
Source
Gets the failure stage.
string Problem { get; }
Source
Gets the operator-facing problem summary.
string Cause { get; }
Source
Gets the display-safe cause summary.
string Fix { get; }
Source
Gets the suggested next action.
string DocsLink { get; }
Source
Gets the documentation link for this workflow.
string? ExceptionType { get; }
Source
Gets the exception type that caused the failure, when available.
Identifies the stage where ConfigAuditDiffCommandRunner could not complete.
Describes the outcome of a config audit diff command runner invocation.
A successful result means the diff report was produced and written. It does not mean the environments are equivalent: changed, added, removed, uncomparable, and warning items remain part of a successful inspection run. Command wrappers should use ExitCode only for process success or failure of the workflow itself.
string? BaselineEnvironment { get; }
Source
Gets the baseline environment when available.
string? TargetEnvironment { get; }
Source
Gets the target environment when available.
ConfigAuditDiffCommandFailure? Failure { get; }
Source
Gets the display-safe failure details when the diff workflow could not run.
bool Succeeded { get; }
Source
Gets a value indicating whether the diff was generated and written.
int ExitCode { get; }
Source
Gets the recommended process exit code for a command wrapper.
Requires a strongly typed configuration wrapper to resolve a value during initialization.
Apply this attribute to a concrete Config{T} or ConfigStruct{T} wrapper when startup should fail if provider/default resolution leaves the wrapper without a value. A Config{T}.DefaultValue or ConfigStruct{T}.DefaultValue satisfies the requirement because the requirement is resolved presence, not provider-source auditing.
This attribute is intentionally separate from scalar value validation attributes such as ConfigValueNotEmptyAttribute. Use ConfigKeyRequiredAttribute when absence should fail, and use value validation when a resolved value must satisfy shape or range rules.
Describes an external provider's audit resolution for one known configuration key.
This public shape is intentionally smaller than Config's internal audit resolution. It gives external providers a safe way to report value state, source records, and diagnostics without coupling packages to internal traversal or patching details. Value is still redacted by the audit reporter before display.
ConfigProviderAuditResolution Missing(string key)
Source
Creates a missing resolution for key.
keyThe logical AppSurface configuration key.A missing audit resolution.
string Key { get; }
Source
Gets the logical AppSurface configuration key.
ConfigAuditEntryState State { get; }
Source
Gets the audit state.
object? Value { get; }
Source
Gets the resolved value, if any.
IReadOnlyList<ConfigAuditSourceRecord> Sources { get; }
Source
Gets the source records that contributed to the value.
IReadOnlyList<ConfigAuditDiagnostic> Diagnostics { get; }
Source
Gets display-safe diagnostics for this key.
Allows a configuration provider to stop lower-priority resolution after a null value.
IConfigProvider.GetValue{T} uses null for both missing values and failed lookups. Providers that own fail-closed sources, such as local secret stores, implement this interface so IConfigManager can distinguish true absence from terminal conditions like locked stores, unsupported platforms, invalid identities, or posture-disabled environments.
When to implement: implement this interface when a provider wraps a fail-closed source that can distinguish "not found" from access denied, locked, unavailable, unsupported platform, invalid identity, or other claimed-key states that must not be masked by file defaults. Prefer a plain IConfigProvider when missing and unavailable values should both fall through.
Usage pattern: IConfigProvider.GetValue{T} returns null for the lookup, then IConfigManager calls TryGetTerminalDiagnostic with the same environment and key. Return true only when that last lookup produced a terminal diagnostic.
Pitfall: cache diagnostics by environment and key for the most recent lookup because TryGetTerminalDiagnostic is called after IConfigProvider.GetValue{T} has already returned. A common mistake is treating every null as terminal; only claimed-key failures should stop resolution, while true missing values must return false.
bool TryGetTerminalDiagnostic(string environment, string key, out ConfigProviderTerminalDiagnostic diagnostic)
Source
Attempts to get the terminal diagnostic for the most recent lookup of key.
environmentThe environment that was resolved.keyThe configuration key that was resolved.diagnosticThe display-safe terminal diagnostic when resolution must stop.true when lower-priority providers must not be queried.
Base class for AppSurface scalar configuration value validation attributes. Apply derived attributes to concrete Config{T} or ConfigStruct{T} wrapper types to validate resolved scalar values during configuration initialization.
Scalar validation runs after provider/default resolution and only when the resolved value is non-null. These attributes validate the value itself; they do not make a missing configuration key required. Use a default value or an application startup presence check when absence should fail.
Validation is intentionally strict about value types. Built-in scalar attributes return validation failures for unsupported runtime types instead of converting values. Use an options object with DataAnnotations when validation spans multiple members, needs nested object traversal, or should model required presence separately from value shape.
The validation context object is the concrete config wrapper and does not provide application dependency injection services. Override Config{T}.ValidateValue or ConfigStruct{T}.ValidateValue for scalar rules that cannot be expressed as reusable attributes.
Validates that a resolved scalar configuration value is not empty. Supported value types are string and Guid.
A null value is treated as successful validation so optional or missing scalar values remain optional. Non-null strings must contain non-whitespace characters, and non-null Guid values must not be Guid.Empty.
Runtime type matching is strict: only string and Guid are supported. Applying this attribute to a different scalar value type returns a validation failure rather than attempting a conversion. Use an options object with member-level DataAnnotations when required presence, cross-field rules, or richer object validation is part of the contract.
Validates that a resolved scalar numeric configuration value is inside an inclusive range. Supported value types are int and double.
A null value is treated as successful validation so optional or missing scalar values remain optional. Non-null values are compared against the inclusive minimum and maximum supplied to the constructor.
Range validation accepts resolved int and double values. Integer bounds are widened when validating a double value, so attribute arguments such as [ConfigValueRange(1, 5)] work for ConfigStruct<double> wrappers. Unsupported runtime types return validation failures instead of being converted. Use an options object when validation needs multiple numeric fields, required presence, or object-level DataAnnotations.
object Minimum { get; }
Source
Gets the inclusive minimum allowed value as a boxed int or double, matching the constructor overload used to create the attribute.
The integer constructor stores a boxed int, and the double constructor stores a boxed double. Callers should unbox this value according to the constructor overload they used. The attribute treats the bound as inclusive and may widen integer bounds when validating double values.
object Maximum { get; }
Source
Gets the inclusive maximum allowed value as a boxed int or double, matching the constructor overload used to create the attribute.
The integer constructor stores a boxed int, and the double constructor stores a boxed double. Callers should unbox this value according to the constructor overload they used. The attribute treats the bound as inclusive and may widen integer bounds when validating double values.
Validates that a resolved scalar string configuration value has at least the configured length.
A null value is treated as successful validation so optional or missing scalar values remain optional. Non-null strings must have a length greater than or equal to Length.
Runtime type matching is strict: only string values are supported. Applying this attribute to another scalar value type returns a validation failure rather than converting the value. Use an options object with DataAnnotations when string length is only one part of a larger model contract or when required presence should be represented separately.
int Length { get; }
Source
Gets the minimum allowed string length.
Configures scoped dictionary-key correlation identifiers for configuration audit reports.
These options are only used by entries whose ConfigAuditEntryOptions.DictionaryKeyCorrelationMode is ConfigAuditDictionaryKeyCorrelationMode.ScopedHmac. The secret key is never copied into reports. Reports may include KeyId, ApplicationScope, and derived correlation identifiers, which are still sensitive support metadata because they reveal key equality, churn, and absence across reports.
string? SecretKey { get; set; }
Source
Gets or sets the deployment-local HMAC secret used to derive correlation identifiers.
The value is interpreted as UTF-8 bytes and must contain at least 32 bytes. Store it in a secret manager or equivalent protected configuration source. Rotating this value intentionally breaks historical correlation.
string? KeyId { get; set; }
Source
Gets or sets the display-safe identifier for the active correlation key.
The key id appears in reports so operators can tell which secret produced a correlation identifier. It must be non-empty and can contain only ASCII letters, digits, ., _, and -.
string? ApplicationScope { get; set; }
Source
Gets or sets the application or product scope included in correlation derivation.
Use a stable public identifier for the app or product, not a secret. Changing this value intentionally breaks historical correlation and prevents ids from matching across unrelated apps that share a key.
Creates per-entry dictionary-key correlation contexts from deployment-level options.
This internal helper is used only when at least one audit entry requests ConfigAuditDictionaryKeyCorrelationMode.ScopedHmac. A context is available only when the configured secret is at least MinimumSecretBytes UTF-8 bytes, the key id is display-safe, and the application scope is present. Unavailable contexts preserve report generation and later emit config-audit-key-correlation-unavailable diagnostics at requested dictionary paths.
ConfigAuditDictionaryKeyCorrelationContext CreateContext(string environment, string rootKey)
Source
Creates an immutable context for one report environment and root audit key.
environmentThe report environment included in the scoped HMAC input.rootKeyThe root audit key included in the scoped HMAC input.An available context when all correlation options are valid; otherwise an unavailable context carrying the reason reported by config-audit-key-correlation-unavailable.
Available contexts derive ids in the form v1:{keyId}:{24-hex-chars}. The suffix is the first TruncatedBytes bytes (96 bits) of an HMAC-SHA256 digest over AlgorithmVersion, application scope, environment, root key, and raw dictionary key. Diff comparison ids derive a separate v1c:{keyId}:{24-hex-chars} value that omits the environment by design so captured reports from different environments can match the same redacted dictionary key.
string? NormalizeKeyId(string? keyId)
Source
Trims the configured key id before validation and report metadata rendering.
keyIdThe configured display-safe key id.The trimmed key id, or null when no value was configured.
string? NormalizeApplicationScope(string? applicationScope)
Source
Trims the configured application scope before validation and HMAC input construction.
applicationScopeThe configured application or product scope.The trimmed application scope, or null when no value was configured.
bool IsDisplaySafeKeyId(string keyId)
Source
Determines whether a key id is safe to render in report metadata and text output.
keyIdThe normalized key id to inspect.true when the key id contains only ASCII letters, digits, ., _, or -; otherwise false.
string ComputeCorrelationId(byte[] secretKey, string keyId, string applicationScope, string environment, string rootKey, string rawDictionaryKey)
Source
Computes the stable opaque id for a raw dictionary key within a fully scoped report context.
secretKeyThe UTF-8 encoded HMAC secret. The array is passed directly to avoid extra copies.keyIdThe display-safe key id rendered into the id.applicationScopeThe application or product scope included in the HMAC input.environmentThe report environment included in the HMAC input.rootKeyThe root audit key included in the HMAC input.rawDictionaryKeyThe unredacted dictionary key included in the HMAC input.A v1:{keyId}:{24-hex-chars} correlation id with a 96-bit truncated HMAC-SHA256 suffix.
string ComputeComparisonCorrelationId(byte[] secretKey, string keyId, string applicationScope, string rootKey, string rawDictionaryKey)
Source
Computes the stable opaque id for comparing a raw dictionary key across report environments.
secretKeyThe UTF-8 encoded HMAC secret. The array is passed directly to avoid extra copies.keyIdThe display-safe key id rendered into the id.applicationScopeThe application or product scope included in the HMAC input.rootKeyThe root audit key included in the HMAC input.rawDictionaryKeyThe unredacted dictionary key included in the HMAC input.A v1c:{keyId}:{24-hex-chars} comparison id with a 96-bit truncated HMAC-SHA256 suffix.
Carries the correlation state used while traversing one configured audit entry.
The context is internal because callers should configure correlation through ConfigAuditDictionaryKeyCorrelationOptions and per-entry ConfigAuditEntryOptions.DictionaryKeyCorrelationMode. Available contexts derive opaque ids for raw dictionary keys; unavailable contexts never throw during traversal and instead let consumers emit a warning diagnostic.
ConfigAuditDictionaryKeyCorrelationContext Available(byte[] secretKey, string keyId, string applicationScope, string environment, string rootKey)
Source
Creates a context that can derive scoped HMAC ids for dictionary keys in one report entry.
secretKeyThe UTF-8 encoded secret key to clone and retain for this report traversal.keyIdThe display-safe key id rendered into each correlation id.applicationScopeThe application or product scope included in the HMAC input.environmentThe report environment included in the HMAC input.rootKeyThe root audit key included in the HMAC input.An available correlation context.
string? CreateCorrelationId(string rawDictionaryKey)
Source
Derives the opaque correlation id for a raw dictionary key when this context is available.
rawDictionaryKeyThe unredacted dictionary key observed during traversal.A v1:{keyId}:{24-hex-chars} id containing a 96-bit truncated HMAC-SHA256 digest, or null when this context is unavailable.
string? CreateComparisonCorrelationId(string rawDictionaryKey)
Source
Derives the opaque comparison id for a raw dictionary key when this context is available.
rawDictionaryKeyThe unredacted dictionary key observed during traversal.A v1c:{keyId}:{24-hex-chars} id containing a 96-bit truncated HMAC-SHA256 digest, or null when this context is unavailable.
bool IsAvailable { get; }
Source
Gets a value indicating whether this context can derive correlation identifiers.
A context is unavailable when the secret key is absent or shorter than MinimumSecretBytes UTF-8 bytes, the key id is missing or not display-safe, or the application scope is missing.
Specifies the configuration key or path for a type.
string? ExtractKey(object obj)
Source
Extracts the configuration key from an object's type attribute.
objThe object to extract the key from.The configuration key, or null if not specified.
string? ExtractKey(Type type)
Source
Extracts the configuration key from a type's attribute.
typeThe type to extract the key from.The configuration key, or null if not specified.
string GetKeyPath(Type type)
Source
Computes the full configuration key path for a type, recursively including declaring types unless Root is true.
typeThe type to compute the path for.The computed configuration key path.
string Key { get; }
Source
Gets the configuration key or path for this type.
bool Root { get; }
Source
Gets a value indicating whether this key should be treated as a root key, ignoring the declaring type hierarchy.
Describes one external provider-discovered configuration key before public classification and redaction.
KeyThe discovered configuration key.RawValueThe scalar value used for redaction, or null for object or array parents.ValueKindThe provider value shape.SourcesSource records associated with the key.DiagnosticsDisplay-safe diagnostics specific to this key.string Key { get; init; }
Source
Gets the discovered configuration key.
IReadOnlyList<ConfigAuditSourceRecord> Sources { get; init; }
Source
Gets source records associated with the key.
IReadOnlyList<ConfigAuditDiagnostic> Diagnostics { get; init; }
Source
Gets display-safe diagnostics specific to this key.
Renders ConfigAuditReport instances as deterministic, human-readable text.
string Render(ConfigAuditReport report)
Source
Renders report as text.
reportThe report to render.A human-readable report.
Describes a display-safe failure from ConfigDiagnosticsCommandRunner.
Failures intentionally omit raw exception messages because provider and reporter exceptions can contain attempted configuration values, file paths, or other support-sensitive details. Command wrappers should display these fields instead of printing the original exception.
string ToDisplayString()
Source
Formats this failure for command-line display.
A display-safe multiline failure message.
string Problem { get; }
Source
Gets the operator-facing problem summary.
string Cause { get; }
Source
Gets the display-safe cause summary.
string Fix { get; }
Source
Gets the suggested next action.
string? ExceptionType { get; }
Source
Gets the exception type that caused the failure, when available.
The type name is retained for support triage while the raw exception message is intentionally omitted.
Allows external providers to expose effective keys for configuration audit inventory.
Enumeration should describe the provider's effective view for the requested environment. Providers that cannot enumerate safely, such as remote secret stores where inventory access is broader than value access, should not implement this interface.
IReadOnlyList<ConfigProviderAuditDiscoveredKey> EnumerateKeys(string environment)
Source
Enumerates effective provider keys for environment.
environmentThe environment being audited.Discovered keys with redaction-ready values and source metadata.
Describes the outcome of a configuration diagnostics command runner invocation.
A successful result means the audit report was generated and written. It does not mean every audited entry resolved successfully: entries with ConfigAuditEntryState.Missing or ConfigAuditEntryState.Invalid are still part of a successful inspection run. Command wrappers should treat ExitCode as the process result for this v1 inspect-only surface.
string? Environment { get; }
Source
Gets the active AppSurface environment that was audited, when it was available.
ConfigDiagnosticsCommandFailure? Failure { get; }
Source
Gets the display-safe failure details when diagnostics could not run.
bool Succeeded { get; }
Source
Gets a value indicating whether the report was generated and written.
int ExitCode { get; }
Source
Gets the recommended process exit code for a command wrapper.
Defines a configuration object that can be initialized using a configuration manager.
void Init(IConfigManager configManager, IEnvironmentProvider environmentProvider, string key)
Source
Initializes the configuration object, resolving its provider or default value and failing fast with ConfigurationValidationException when required presence is not satisfied or when the resolved value violates object DataAnnotations rules or scalar value validation rules. Exceptions thrown by scalar Config{T}.ValidateValue or ConfigStruct{T}.ValidateValue overrides are not wrapped, so callers that activate config wrappers during startup should let unexpected programming errors fail the startup path.
configManagerThe configuration manager to use for retrieving values.environmentProviderThe environment provider.keyThe root configuration key for this object.ConfigurationValidationExceptionThrown when the wrapper requires a value and no provider/default value resolves, or when the resolved provider value or default value violates object DataAnnotations or scalar validation rules.ExceptionThrown when a concrete scalar validation override throws; override exceptions are not wrapped.Represents a display-safe terminal configuration resolution failure.
The exception message is built from Diagnostic and intentionally omits raw provider exception messages and configuration values. Catch this exception at command or host boundaries when the app should render provider posture guidance instead of falling through to lower-priority configuration sources.
string EnvironmentName { get; }
Source
Gets the environment being resolved.
string Key { get; }
Source
Gets the configuration key being resolved.
string ProviderName { get; }
Source
Gets the provider that stopped lower-priority resolution.
ConfigProviderTerminalDiagnostic Diagnostic { get; }
Source
Gets the display-safe terminal diagnostic.
A configuration provider that retrieves values from environment variables.
string NormalizeSegment(string value)
Source
Converts a key/environment segment to uppercase (via string.ToUpperInvariant) and flattens separators by replacing '.' and '-' with a single '_'. Used for legacy flat environment-variable lookup.
string NormalizeHierarchicalKey(string value)
Source
Converts a key to uppercase (via string.ToUpperInvariant), splits on '.' and '-' as hierarchical delimiters, removes empty segments, and joins segments using "__". Used for hierarchical environment-variable lookup while preserving path boundaries.
A module that registers configuration management services and automatically discovers and registers configuration objects.
AppSurfaceConfigModule registers core configuration services immediately, including audit reporting, diagnostics, sanitized diff comparison, diff rendering, and command-runner helpers, then defers typed IConfig discovery through StartupContext.CustomRegistrations so all module dependencies are known first. The deferred scan inspects dependency module assemblies, the entry assembly, and the root module assembly. Pitfall: config dependencies should be registered before the custom registration callback runs; otherwise discovered config objects may activate before their supporting services are available.
void ConfigureServices(StartupContext context, IServiceCollection services)
Source
Registers AppSurface config services and schedules typed config discovery after module registration.
contextStartup context that supplies assemblies, dependency modules, and the custom registration log.servicesService collection that receives the default configuration services.ConfigureServices(StartupContext, IServiceCollection) adds the default manager, providers, audit reporter, audit redactor, text renderer, diagnostics runner, file-location provider, and sanitized diff services, then appends a StartupContext.CustomRegistrations callback. The diff registrations include ConfigAuditReportDiffer for pure typed snapshot comparison, ConfigAuditDiffTextRenderer for deterministic operator output, and ConfigAuditDiffCommandRunner for command-framework-agnostic same-host and captured-snapshot workflows. The custom callback scans dependency, entry, and root-module assemblies for concrete IConfig implementations and registers each as a singleton initialized from IConfigManager and IEnvironmentProvider. Wrappers decorated with ConfigAuditCollectionTraversalAttribute also contribute audit traversal options for their key.
Defines a configuration provider that also provides environment information.
IEnvironmentConfigProvider composes IConfigProvider with IEnvironmentProvider for implementations that need to resolve configuration and the active environment from the same source. Prefer the composite when environment-aware config lookup should be atomic or co-located in one implementation; use the separate interfaces when configuration and environment ownership differ. Implementations should be safe for repeated reads, define any caching or refresh behavior, and avoid assuming that all configuration is environment-exclusive. Disposal and lifetime follow the concrete provider registration.
Compares two existing ConfigAuditReport instances without resolving providers.
The differ is intentionally pure: it does not start hosts, read files, call providers, or depend on any command framework. Reports should already be sanitized by IConfigAuditReporter or by a trusted captured-report workflow. Redacted and omitted values remain uncertain; the diff exposes that uncertainty through ConfigAuditDiffItem.ValueEvidence instead of implying raw equality.
ConfigAuditDiffReport Compare(ConfigAuditReport baseline, ConfigAuditReport target)
Source
Compares two audit reports using default options.
baselineThe baseline report, often staging or the current known-good snapshot.targetThe target report, often production or the candidate snapshot.A typed diff report.
ConfigAuditDiffReport Compare(ConfigAuditReport baseline, ConfigAuditReport target, ConfigAuditDiffOptions? options)
Source
Compares two audit reports using the supplied options.
baselineThe baseline report, often staging or the current known-good snapshot.targetThe target report, often production or the candidate snapshot.optionsComparison options. Defaults are used when this value is null.A typed diff report whose item ordering is deterministic.
A base class for strongly-typed configuration objects. Values are resolved during IConfig.Init, then object-valued configuration models are validated with DataAnnotations and scalar values can be validated with AppSurface scalar attributes or ValidateValue. Invalid provider values and invalid defaults fail fast by throwing ConfigurationValidationException, so callers that activate config wrappers can catch that exception and surface its structured failures. Ensure defaults satisfy the same validation rules as configured values; an invalid default prevents initialization when no provider value exists. Apply ConfigKeyRequiredAttribute to require resolved provider/default presence.
TThe type of the configuration value.void Init(IConfigManager configManager, IEnvironmentProvider environmentProvider, string key)
Source
Resolves the configured value for key and validates the resolved provider value or DefaultValue before initialization completes.
configManagerThe configuration manager used to resolve the provider value.environmentProviderThe environment provider used to choose the active environment.keyThe configuration key to resolve.ConfigurationValidationExceptionThrown when the wrapper requires a value and no provider/default value resolves, or when the provider value or default value violates object DataAnnotations or scalar validation rules.IEnumerable<ValidationResult>? ValidateValue(T value, ValidationContext validationContext)
Source
Validates a resolved non-null scalar configuration value. Override this method when a scalar rule is too specific for the built-in AppSurface scalar attributes.
valueThe resolved provider or default scalar value.validationContextThe validation context for the concrete configuration wrapper.The validation results for value. Return null, an empty sequence, ValidationResult.Success, or null entries when validation succeeds.
bool HasValue { get; set; }
Source
Gets a value indicating whether the configuration has a value (either from source or default).
bool IsDefaultValue { get; set; }
Source
Gets a value indicating whether the current value is the default value.
T? Value { get; set; }
Source
Gets the configuration value.
T? DefaultValue { get; }
Source
Gets the default value for the configuration if none is found in the source.
Describes one validation failure found while initializing a strongly typed configuration value.
string Key { get; }
Source
Gets the configuration key being initialized.
Type ConfigType { get; }
Source
Gets the concrete configuration wrapper type being initialized.
Type ValueType { get; }
Source
Gets the resolved value type that was validated.
IReadOnlyList<string> MemberNames { get; }
Source
Gets the member names or paths associated with the failure. Object-level failures use an empty list rather than null; consumers should treat that empty collection as a valid failure payload. The returned list is an immutable snapshot owned by this instance.
string Message { get; }
Source
Gets the validation message.
A configuration provider that reads settings from JSON files (e.g., appsettings.json, config_*.json).
Maps JSON object member paths to conservative file source locations for audit provenance.
The map is advisory and intentionally narrower than JSON parsing: it records object property-name token locations, suppresses ambiguous case-insensitive paths, and omits array descendants so callers never receive a coordinate that is more specific than the file provider's merge/origin model.
ConfigFileSourceLocationMap Create(ReadOnlySpan<byte> fileBytes)
Source
Creates a source-location map from the raw file bytes used to initialize the file provider snapshot.
fileBytesThe raw JSON file bytes.A map of supported config paths to source locations, or an empty map when the bytes cannot be mapped.
ConfigAuditSourceLocation? GetLocation(string path)
Source
Gets the location for path when the path was mapped without ambiguity.
pathThe dotted config path used by the file provider origin record.The source location, or null when no truthful coordinate is available.
ConfigFileSourceLocationMap Empty { get; }
Source
Gets an empty map used when source coordinates are unavailable.
Allows external configuration providers to expose source-aware audit details without depending on Config internals.
Implement this interface when a provider can resolve a known audit key with richer provenance or diagnostics than the generic IConfigProvider.GetValue{T} fallback can provide, or when calling the generic path would lose provider-specific source records. Providers with ordinary scalar values and no custom diagnostics should rely on the generic audit path instead. Return display-safe diagnostics only: messages, source records, and metadata must not include raw configuration values, secret payloads, credentials, or raw provider exception messages. Expected provider failures, such as missing remote secrets or access-denied responses, should be returned as failed ConfigProviderAuditResolution instances so the reporter can preserve provider ownership. Throw only for unexpected programming or infrastructure failures that cannot be represented safely. The reporter invokes providers in priority order while building a point-in-time audit report, so implementations should avoid writes and other order-sensitive side effects.
ConfigProviderAuditResolution ResolveForAudit(string environment, string key, Type valueType, ConfigAuditSourceRole role)
Source
Resolves a known audit key with source metadata for a configuration audit report.
environmentThe environment being audited.keyThe logical AppSurface configuration key.valueTypeThe expected value type.roleThe role the provider plays in final resolution.The provider audit resolution.
Return a ConfigProviderAuditResolution whose key matches key. Failed claimed-key lookups should use ConfigAuditEntryState.Invalid with display-safe diagnostics instead of throwing when the failure is an expected provider outcome. Do not include raw secret values in diagnostics or source metadata.
IReadOnlyList<ConfigAuditDiagnostic> GetReportDiagnostics(string environment)
Source
Gets report-level diagnostics for environment.
environmentThe environment being audited.Display-safe diagnostics that are not tied to one key.
Use this for provider-wide warnings or failures that are not tied to one key. The returned diagnostics may be rendered before or after key-level diagnostics, so consumers must not depend on ordering for correctness.
The exception thrown when a strongly typed configuration value fails validation during initialization.
string Key { get; }
Source
Gets the configuration key being initialized.
Type ConfigType { get; }
Source
Gets the concrete configuration wrapper type being initialized.
Type ValueType { get; }
Source
Gets the resolved value type that was validated.
IReadOnlyList<ConfigurationValidationFailure> Failures { get; }
Source
Gets the validation failures returned for the configuration value.
Provides the base directory used to resolve AppSurface configuration files.
Implementations should return a stable absolute path that exists and is readable by the process. The default implementation returns AppContext.BaseDirectory. Callers should validate Directory before opening files and report a configuration error when it is null, empty, missing, unreadable, or unsuitable for the current platform. Paths should not depend on the current working directory; symlinks and platform separators are implementation details callers should normalize before comparison.
string Directory { get; }
Source
Gets the absolute directory path containing configuration files.
The value should be an absolute path without a required trailing slash. The provider does not own the directory lifetime and should not create, delete, or lock it. A typical consumer checks System.IO.Directory.Exists(provider.Directory) before resolving known config file names below that path and returns a clear validation failure when the directory is unavailable.
Provides the canonical scalar-type classification shared by configuration validation paths.
bool IsScalar(Type type)
Source
Returns whether type is treated as a scalar configuration value. Nullable wrappers are unwrapped before inspection. Supported scalar types are primitives, enums, string, decimal, DateTime, DateTimeOffset, TimeSpan, Guid, and Uri.
typeThe declared or runtime value type to inspect.true when type is a supported scalar type.
Runs the app-owned configuration diagnostics command workflow for the active AppSurface environment.
This runner belongs to the config package and intentionally has no dependency on CliFx, AppSurface Console, or any command-specific abstractions. Console applications should expose their own app-local command, pass that command's output writer to Run(TextWriter), and translate unsuccessful results into their command framework's failure type. V1 audits only IEnvironmentProvider.Environment from the already-built app host. It does not provide a command-level environment override, does not enumerate raw unknown environment variables, and cannot rescue apps that fail before the host and command service can run.
ConfigDiagnosticsCommandResult Run(TextWriter output)
Source
Writes the active environment's configuration audit report to output.
outputThe writer that receives the rendered report.A result whose ConfigDiagnosticsCommandResult.ExitCode is zero when the report was generated. Missing or invalid configuration entries remain successful inspection results.
Non-fatal runtime failures are converted to display-safe failure details. Raw exception messages are not exposed because provider and validation exceptions can contain attempted secret values or environment-specific paths.
A base class for strongly-typed configuration objects where the value is a struct. Values are resolved during IConfig.Init, then object-valued configuration models are validated with DataAnnotations and scalar values can be validated with AppSurface scalar attributes or ValidateValue. Invalid provider values and invalid defaults fail fast by throwing ConfigurationValidationException, so callers that activate config wrappers can catch that exception and surface its structured failures. Ensure defaults satisfy the same validation rules as configured values; an invalid default prevents initialization when no provider value exists. Apply ConfigKeyRequiredAttribute to require resolved provider/default presence.
TThe struct type of the configuration value.void IConfig.Init(IConfigManager configManager, IEnvironmentProvider environmentProvider, string key)
Source
Resolves the configured value for key and validates the resolved provider value or DefaultValue before initialization completes.
configManagerThe configuration manager used to resolve the provider value.environmentProviderThe environment provider used to choose the active environment.keyThe configuration key to resolve.ConfigurationValidationExceptionThrown when the wrapper requires a value and no provider/default value resolves, or when the provider value or default value violates object DataAnnotations or scalar validation rules.IEnumerable<ValidationResult>? ValidateValue(T value, ValidationContext validationContext)
Source
Validates a resolved non-null scalar configuration value. Override this method when a scalar rule is too specific for the built-in AppSurface scalar attributes.
valueThe resolved provider or default scalar value.validationContextThe validation context for the concrete configuration wrapper.The validation results for value. Return null, an empty sequence, ValidationResult.Success, or null entries when validation succeeds.
bool HasValue { get; set; }
Source
Gets a value indicating whether the configuration has a value.
bool IsDefaultValue { get; set; }
Source
Gets a value indicating whether the current value is the default value.
T? Value { get; set; }
Source
Gets the configuration value.
T? DefaultValue { get; }
Source
Gets the default value for the configuration if none is found in the source.
Default implementation of IConfigFileLocationProvider that uses the application's base directory.
DefaultConfigFileLocationProvider returns AppContext.BaseDirectory from Directory. This is appropriate for simple apps that keep configuration beside application binaries. Use a custom IConfigFileLocationProvider for environment-specific, user-scoped, container-mounted, or service-hosted configuration. Pitfall: AppContext.BaseDirectory is not necessarily System.IO.Directory.GetCurrentDirectory and can vary by deployment model, test runner, or host.
Describes the resolved configuration state for an AppSurface environment.
Reports are immutable snapshots from the caller's perspective: provider order, entries, diagnostics, and redaction policy describe one audit run and should not be treated as live configuration. Use Entries for machine inspection and DiscoveredKeys for effective provider-discovered configuration keys that are not necessarily represented by known entries. Use ConfigAuditTextRenderer when operators need a deterministic text dump.
string Environment { get; init; }
Source
Gets the environment this report describes.
DateTimeOffset GeneratedAt { get; init; }
Source
Gets the time when this report was generated.
IReadOnlyList<ConfigAuditProvider> Providers { get; init; }
Source
Gets the provider precedence used while producing this report.
IReadOnlyList<ConfigAuditEntry> Entries { get; init; }
Source
Gets the known configuration entries resolved for this environment.
IReadOnlyList<ConfigAuditDiscoveredKey> DiscoveredKeys { get; init; }
Source
Gets effective configuration keys discovered directly from enumerable providers.
Discovered keys describe the effective merged configuration visible to AppSurface providers that implement audit enumeration. They are not a complete raw inventory: providers that cannot enumerate keys are omitted, shadowed lower-priority file keys are not included, and environment variables or secret providers are not enumerated by the built-in v1 surface. ConfigAuditDiscoveredKey.DisplayValue is redacted or omitted before it enters the public report, but source metadata such as file paths, provider names, and config paths may still be support-sensitive.
IReadOnlyList<ConfigAuditDiagnostic> Diagnostics { get; init; }
Source
Gets report-level diagnostics that are not tied to a single entry.
ConfigAuditRedaction Redaction { get; init; }
Source
Gets the redaction policy applied before this report was returned.
Describes one effective provider-discovered configuration key in an audit report.
Classifications are relative to the AppSurface audit registry, not to all application code. An ConfigAuditDiscoveredKeyClassification.Unknown key can be a typo, stale setting, or a value consumed outside AppSurface's known-entry registry; it is not proof that no code uses the key. Use ValueDisplayState to distinguish shown, redacted, complex-omitted, and inventory-omitted values. The display state describes this report's rendering decision only; it is not a sensitivity or secrecy classification.
string Key { get; init; }
Source
Gets the discovered configuration key path.
ConfigAuditDiscoveredKeyClassification Classification { get; init; }
Source
Gets the key's relationship to the AppSurface audit registry.
string? DisplayValue { get; init; }
Source
Gets the display-safe value, or null when a non-sensitive value is omitted.
Exact registered scalar keys can include a display value. Non-sensitive object and array parent values are omitted instead of serialized, and non-sensitive provider-discovered inventory values that are not exact audit entries are omitted by default. Use ValueDisplayState instead of testing this property for null when consuming structured reports.
bool IsRedacted { get; init; }
Source
Gets a value indicating whether DisplayValue was replaced by the redaction placeholder.
ConfigAuditDiscoveredValueDisplayState ValueDisplayState { get; init; }
Source
Gets the display decision applied to DisplayValue for this discovered key.
This state explains how the public report rendered the discovered value. It is not a sensitivity label and does not prove whether a value is secret or safe outside the current report context. The default ConfigAuditDiscoveredValueDisplayState.Unspecified preserves compatibility for reports manually constructed before this property existed; reporter-produced instances always set an explicit state.
IReadOnlyList<ConfigAuditSourceRecord> Sources { get; init; }
Source
Gets source records associated with this effective discovered key.
IReadOnlyList<ConfigAuditDiagnostic> Diagnostics { get; init; }
Source
Gets diagnostics specific to this discovered key.
Describes one provider in the audit report precedence list.
Precedence is the display order used by audit reports. Environment providers are marked as overrides because they are checked before normal priority-ordered providers.
string Name { get; init; }
Source
Gets the provider name.
int Priority { get; init; }
Source
Gets the provider priority.
int Precedence { get; init; }
Source
Gets the precedence rank used by the configuration manager. Lower ranks are checked first.
bool IsOverride { get; init; }
Source
Gets a value indicating whether the manager treats this provider as an override outside normal priority order.
Describes one known configuration entry and its source records.
State summarizes the entry as a whole. Object entries can contain Children with more specific provenance, including nested ConfigAuditEntryState.PartiallyResolved states when descendants are patched. DisplayValue is already redacted and can be null for complex values, including collections whose elements are not dumped into parent display strings. Callers should inspect source records and available children instead of assuming a full object dump is available.
string Key { get; init; }
Source
Gets the configuration key.
string? DeclaredType { get; init; }
Source
Gets the declared value type name when known.
ConfigAuditEntryState State { get; init; }
Source
Gets the resolved entry state.
string? DisplayValue { get; init; }
Source
Gets the display-safe value. Sensitive values are already redacted, and collection parent values may be omitted so nested element data cannot leak through a serialized dump.
bool IsRedacted { get; init; }
Source
Gets a value indicating whether DisplayValue was redacted.
ConfigAuditElementIdentity? Element { get; init; }
Source
Gets collection element identity when this entry represents an array/list item or dictionary item.
Element labels are already display-safe. Sensitive dictionary keys are replaced before the report object is created, so callers must not expect ConfigAuditElementIdentity.KeyLabel to be reversible.
IReadOnlyList<ConfigAuditSourceRecord> Sources { get; init; }
Source
Gets the source records that contributed to this entry.
IReadOnlyList<ConfigAuditEntry> Children { get; init; }
Source
Gets child entries for object-valued configuration.
IReadOnlyList<ConfigAuditDiagnostic> Diagnostics { get; init; }
Source
Gets diagnostics specific to this entry.
Describes a source coordinate inside a configuration file.
Both values are one-based. ByteColumnNumber counts UTF-8 bytes from the start of the physical line, so it can differ from an editor's character column when a line contains non-ASCII characters before the source token.
int LineNumber { get; }
Source
Gets the one-based physical line number containing the source token.
int ByteColumnNumber { get; }
Source
Gets the one-based UTF-8 byte column containing the source token.
This is a byte coordinate over the UTF-8 file content, not a Unicode scalar, text element, or editor display column. A non-ASCII character earlier on the same line can increase this value by more than one.
Describes the collection element represented by a child audit entry.
Array and list entries use zero-based Index values. Dictionary entries use KeyLabel, which is either the non-sensitive key label, a display-suppressed placeholder, or an in-report redaction label such as [redacted-key-1]. Labels are intended for display and comparison within one report only. When configured, KeyCorrelationId is the separate environment-scoped opaque value for comparing dictionary keys inside one named environment's report history. Use ComparisonKeyCorrelationId for explicit cross-environment config diff matching.
ConfigAuditElementKind Kind { get; init; }
Source
Gets the collection element kind.
int? Index { get; init; }
Source
Gets the zero-based array or list index, when applicable.
string? KeyLabel { get; init; }
Source
Gets the display-safe dictionary key label, when applicable.
bool IsKeyRedacted { get; init; }
Source
Gets a value indicating whether the original dictionary key was redacted or intentionally hidden.
string? KeyCorrelationId { get; init; }
Source
Gets the opt-in opaque identifier for correlating the same dictionary key across reports.
This value is populated only when entry options enable dictionary key correlation and global correlation key material is valid. It includes the report environment in its derivation, is not reversible, is not part of the display path, and should still be treated as sensitive support metadata because it reveals equality and churn across reports from the same environment.
string? ComparisonKeyCorrelationId { get; init; }
Source
Gets the opt-in opaque identifier for matching the same dictionary key across compared environments.
This value is populated only when entry options enable dictionary key correlation and global correlation key material is valid. Unlike KeyCorrelationId, the environment name is deliberately omitted from the derivation so ConfigAuditReportDiffer can match captured staging and production reports without trusting report-local redacted labels. It is not reversible and should still be treated as support-sensitive equality metadata.
Describes one source that contributed to a configuration entry.
Source records identify where a value came from and how it was applied. File paths, environment variable names, and config paths are optional because not every provider exposes the same provenance. File sources can also include Location when the provider can truthfully map the parsed value back to an exact file coordinate. The source role is especially important for mixed values: a base source can be combined with patch sources from higher-priority providers.
ConfigAuditSourceKind Kind { get; init; }
Source
Gets the source kind.
string? ProviderName { get; init; }
Source
Gets the provider name when applicable.
int? ProviderPriority { get; init; }
Source
Gets the provider priority when applicable.
string? FilePath { get; init; }
Source
Gets the file path for file-sourced values.
string? EnvironmentVariableName { get; init; }
Source
Gets the environment variable name for environment-sourced values.
string? ConfigPath { get; init; }
Source
Gets the source config path.
string? AppliedToPath { get; init; }
Source
Gets the target config path affected by this source.
ConfigAuditSourceLocation? Location { get; init; }
Source
Gets the exact file coordinate for this source when the provider can prove one.
A null value means the source is still known but no truthful coordinate is available, such as for non-file sources, ambiguous case-insensitive file paths, unsupported paths, parser mismatches, or collection element descendants.
ConfigAuditSourceRole Role { get; init; }
Source
Gets the role this source played in resolution.
ConfigAuditSensitivity Sensitivity { get; init; }
Source
Gets the sensitivity classification supplied by the source.
Describes a diagnostic emitted while building a configuration audit report.
Diagnostic messages are intended to be display-safe and stable enough for operators. Use Code for programmatic handling, and use Source when a diagnostic can be tied to one provider, file, or environment variable.
ConfigAuditDiagnosticSeverity Severity { get; init; }
Source
Gets the diagnostic severity.
string Code { get; init; }
Source
Gets a stable diagnostic code.
string Message { get; init; }
Source
Gets the display-safe diagnostic message.
string? Key { get; init; }
Source
Gets the configuration key associated with the diagnostic, when any.
string? ConfigPath { get; init; }
Source
Gets the member/config path associated with the diagnostic, when any.
ConfigAuditSourceRecord? Source { get; init; }
Source
Gets the source associated with the diagnostic, when any.
Describes the redaction policy applied to a configuration audit report.
The built-in policy is always enabled and uses fragment matching before values are exposed through ConfigAuditEntry.DisplayValue. MatchedFragments is a snapshot for explanation, not a mutable policy hook. Dictionary key correlation metadata describes the configured report policy without exposing the secret key used for scoped HMAC derivation.
bool Enabled { get; init; }
Source
Gets a value indicating whether redaction was enabled.
IReadOnlyList<string> MatchedFragments { get; init; }
Source
Gets the sensitive fragments matched by the built-in redactor.
string Placeholder { get; init; }
Source
Gets the display placeholder used for redacted values.
ConfigAuditDictionaryKeyCorrelationMode DictionaryKeyCorrelationMode { get; init; }
Source
Gets the configured dictionary key correlation mode for the report.
string? DictionaryKeyCorrelationKeyId { get; init; }
Source
Gets the display-safe correlation key id when configured.
string? DictionaryKeyCorrelationApplicationScope { get; init; }
Source
Gets the configured application or product scope when configured.
Identifies how dictionary keys should receive cross-report correlation identifiers.
Values are explicit and append-only so serialized reports remain stable across releases.
Identifies the resolution state for an audited configuration entry.
Values are explicit and append-only so serialized reports remain stable across releases.
Identifies how a provider-discovered key relates to the AppSurface audit registry.
Values are explicit and append-only so serialized reports remain stable across releases. These classifications are registry-relative: Unknown does not mean globally unused, and KnownDescendant is based on dotted-path segment matching rather than schema validation of a wrapper type.
Identifies how a provider-discovered value appears in the public audit report.
Values are explicit and append-only so serialized reports remain stable across releases. This enum describes report display state only: it is not a sensitivity or secrecy classification, and source metadata may remain support-sensitive even when a value is omitted.
Identifies the kind of collection element represented by an audit child entry.
Values are explicit and append-only so serialized reports remain stable across releases.
Identifies the kind of configuration source.
Values are explicit and append-only so serialized reports remain stable across releases.
Identifies how a source contributed to the final value.
Values are explicit and append-only so serialized reports remain stable across releases.
Classifies source or value sensitivity.
Values are explicit and append-only so serialized reports remain stable across releases. For entry options, NonSensitive is a classification hint, not a redaction bypass; sensitive fragments, provider source sensitivity, and another registration's Sensitive classification still win.
Identifies diagnostic severity.
Values are explicit and append-only so serialized reports remain stable across releases.
Defines the central manager for configuration, which aggregates multiple IConfigProvider instances.
IConfigProvider.GetValue{T} preserves ordinary provider fallback for missing values, but it also honors fail-closed provider diagnostics. When a provider reports that resolution must stop, the manager throws ConfigurationResolutionException instead of querying lower-priority providers.
Describes a configuration entry known to AppSurface's audit system.
string Key { get; }
Source
Gets the configuration key.
Type? ConfigType { get; }
Source
Gets the config wrapper type, when this entry came from a wrapper.
Type ValueType { get; }
Source
Gets the declared value type.
ConfigAuditEntryOptions Options { get; }
Source
Gets a copy of the audit entry options captured for this known entry.
The returned options object is immutable. Configure options during registration by using ConfigAuditServiceCollectionExtensions.AddConfigAuditKey{T}(IServiceCollection,string,Action{ConfigAuditEntryOptionsBuilder}) or the constructor overload that accepts ConfigAuditEntryOptions.
Controls optional expansion behavior for one configuration audit entry.
Defaults preserve the original audit behavior: object members are reported, collection parent values remain opaque, and collection elements are not traversed unless TraverseCollectionElements is enabled. Instances are copied by ConfigAuditKnownEntry, so registration captures a stable snapshot. Use ConfigAuditEntryOptionsBuilder with the service-collection registration callback when mutable callback configuration is more convenient than an object initializer. When entries with the same key are merged, explicitly assigned manual options override wrapper-discovered options one property at a time.
ConfigAuditEntryOptions Normalize()
Source
Returns options with invalid traversal limits replaced by safe defaults.
Normalization preserves TraverseCollectionElements, DisplayDictionaryKeys, and AssignedOptions. Invalid Sensitivity values fail closed as ConfigAuditSensitivity.Sensitive after diagnostics have captured the bad value. It is intended for report generation after diagnostics have captured invalid inputs; it should not be used as a signal that an option was unassigned.
ConfigAuditEntryOptions ApplyAssignedOverrides(ConfigAuditEntryOptions overrides)
Source
Applies explicitly assigned option values from a later registration over this options snapshot.
overridesThe options whose assigned properties should override this snapshot.A new options snapshot containing merged values and the union of assignment flags.
Merging happens per property. A property in overrides wins only when its assignment flag is present, and it wins even when the overriding value equals the default. This preserves duplicate-registration precedence where wrapper-discovered options provide a complete policy, while manual provider options can intentionally reset any individual setting back to a default value.
ConfigAuditSensitivity MergeSensitivity(ConfigAuditSensitivity current, ConfigAuditSensitivity candidate)
Source
Merges two assigned entry sensitivity values using the most restrictive valid classification.
currentThe current sensitivity value.candidateThe candidate sensitivity value being merged in.The merged sensitivity value.
ConfigAuditSensitivity.Sensitive wins over ConfigAuditSensitivity.NonSensitive, and ConfigAuditSensitivity.NonSensitive wins over ConfigAuditSensitivity.Unknown. If either value is outside the known enum members, that invalid value is preserved so validation can emit an actionable diagnostic before normalization fails closed. This helper is pure and does not throw for invalid enum values.
ConfigAuditSensitivity NormalizeSensitivity(ConfigAuditSensitivity sensitivity)
Source
Returns a report-generation-safe sensitivity value.
sensitivityThe sensitivity value to normalize.sensitivity when it is valid; otherwise ConfigAuditSensitivity.Sensitive.
Valid values are returned unchanged. Invalid enum values normalize to ConfigAuditSensitivity.Sensitive so redaction fails closed after validation has captured the original value. This helper is pure and does not throw.
bool IsValidSensitivity(ConfigAuditSensitivity sensitivity)
Source
Determines whether a sensitivity value is one of the supported enum members.
sensitivityThe sensitivity value to inspect.true when sensitivity is a supported enum member.
ConfigAuditSensitivity.Unknown, ConfigAuditSensitivity.NonSensitive, and ConfigAuditSensitivity.Sensitive are valid. All other numeric values are invalid and should be reported before being normalized. This helper is pure and does not throw.
bool TraverseCollectionElements { get; init; }
Source
Gets a value indicating whether arrays, lists, and dictionaries should emit child element entries.
int MaxCollectionDepth { get; init; }
Source
Gets the maximum nested collection depth traversed when collection traversal is enabled.
int MaxCollectionElements { get; init; }
Source
Gets the maximum number of elements reported from any one traversed collection.
int MaxReportNodes { get; init; }
Source
Gets the maximum number of child nodes created for this entry before traversal stops.
bool DisplayDictionaryKeys { get; init; }
Source
Gets a value indicating whether non-sensitive dictionary keys may appear as element labels.
ConfigAuditSensitivity Sensitivity { get; init; }
Source
Gets the entry-level sensitivity classification used by audit redaction.
The default is ConfigAuditSensitivity.Unknown. ConfigAuditSensitivity.Sensitive redacts the root value, traversed child values, and value-derived dictionary labels before report models are returned. ConfigAuditSensitivity.NonSensitive is a classification hint only: it never disables redaction from sensitive key fragments, source metadata, provider metadata, or another registration that marks the same entry sensitive. Invalid enum values emit a config-audit-options-invalid diagnostic and fail closed as sensitive during report generation.
ConfigAuditDictionaryKeyCorrelationMode DictionaryKeyCorrelationMode { get; init; }
Source
Gets the opt-in persistent dictionary key correlation mode for this entry.
The default is ConfigAuditDictionaryKeyCorrelationMode.None, which keeps redacted dictionary key labels report-local. ConfigAuditDictionaryKeyCorrelationMode.ScopedHmac adds a separate ConfigAuditElementIdentity.KeyCorrelationId to dictionary element entries when global correlation key material is configured.
ConfigAuditEntryOptionAssignments AssignedOptions { get; init; }
Source
Gets the option properties that were intentionally assigned by the source registration.
Assignment tracking is independent from value comparison. For example, manually assigning MaxCollectionDepth to its default value still sets the corresponding flag and therefore overrides a wrapper attribute's custom depth during duplicate-registration merging.
Mutable builder used by registration callbacks to create immutable ConfigAuditEntryOptions.
The builder exists only for configuration ergonomics. AppSurface snapshots it into immutable options when registering the audit key, so later builder mutations cannot affect reports. Property setters are also tracked as explicit assignments, allowing manual registrations to override wrapper attribute options even when the assigned value is the option's default.
ConfigAuditEntryOptions ToOptions()
Source
Creates an immutable options snapshot from the current builder state.
The returned options copy current values and assignment flags. Later builder mutations do not affect the returned options, which is important because registrations are snapshotted before reports are built or serialized.
bool TraverseCollectionElements { get; set; }
Source
Gets or sets a value indicating whether arrays, lists, and dictionaries should emit child element entries.
int MaxCollectionDepth { get; set; }
Source
Gets or sets the maximum nested collection depth traversed when collection traversal is enabled.
int MaxCollectionElements { get; set; }
Source
Gets or sets the maximum number of elements reported from any one traversed collection.
int MaxReportNodes { get; set; }
Source
Gets or sets the maximum number of child nodes created for this entry before traversal stops.
bool DisplayDictionaryKeys { get; set; }
Source
Gets or sets a value indicating whether non-sensitive dictionary keys may appear as element labels.
ConfigAuditSensitivity Sensitivity { get; set; }
Source
Gets or sets the entry-level sensitivity classification used by audit redaction.
Use ConfigAuditSensitivity.Sensitive when the key's domain-specific value should redact even if the key name does not contain a built-in sensitive fragment. ConfigAuditSensitivity.NonSensitive documents intent but is not an opt-out from conservative redaction and never downgrades another sensitive signal.
ConfigAuditDictionaryKeyCorrelationMode DictionaryKeyCorrelationMode { get; set; }
Source
Gets or sets the opt-in persistent dictionary key correlation mode for this entry.
The default keeps redacted dictionary key labels report-local. Use ConfigAuditDictionaryKeyCorrelationMode.ScopedHmac only when operators need stable opaque dictionary key identifiers and global ConfigAuditDictionaryKeyCorrelationOptions are configured.
ConfigAuditEntryOptionAssignments AssignedOptions { get; set; }
Source
Gets the option properties that were assigned through this builder.
The builder tracks setter calls rather than non-default values so duplicate-registration merging can distinguish "caller left the wrapper value alone" from "caller explicitly reset this option to its default."
Extension methods for registering additional configuration audit keys.
IServiceCollection AddConfigAuditKey<T>(this IServiceCollection services, string key)
Source
Registers an additional configuration key for audit reports.
TThe expected value type.servicesThe service collection.keyThe configuration key.The original services instance.
Use this method for values that should appear in audit reports but are not backed by an IConfig or Config{T} wrapper discovered by assembly scanning. Prefer wrapper discovery when a typed wrapper already exists, because the wrapper can contribute defaults and validation diagnostics. Manual registration creates a ConfigAuditKnownEntry with ConfigAuditKnownEntry.ConfigType set to null and T as the expected value type; for example, AddConfigAuditKey<Uri>("Billing.Endpoint") includes a provider-only key in reports.
IServiceCollection AddConfigAuditKey<T>(this IServiceCollection services, string key, Action<ConfigAuditEntryOptionsBuilder>? configure)
Source
Registers an additional configuration key for audit reports with entry-specific options.
TThe expected value type.servicesThe service collection.keyThe configuration key.configureA callback that customizes the audit options for this key.The original services instance.
Use configure to opt into collection element traversal for this key only or to classify a domain-specific value with ConfigAuditEntryOptionsBuilder.Sensitivity. Options are snapshotted when the registration is created; collection traversal remains disabled by default so existing reports keep their previous shape unless callers explicitly enable it. If this key is also discovered from a config wrapper, the wrapper supplies metadata and validation while explicitly assigned manual options override wrapper audit options per property. Sensitivity merges monotonically, so ConfigAuditSensitivity.NonSensitive never downgrades an effective sensitive entry.
Tracks which audit entry options were intentionally assigned by a wrapper attribute or manual registration.
These flags control duplicate-registration precedence. They are not a serialization format and should not be inferred from option values, because default-valued assignments are meaningful overrides.
Builds safe child audit entries from object and opt-in collection values.
ConfigAuditTraversalResult BuildChildren(ConfigAuditPath path, object? value, IReadOnlyList<ConfigAuditSourceRecord> sources, ConfigAuditFactContext factContext, ConfigAuditEntryOptions options, HashSet<object> visited, ConfigAuditDictionaryLabelSet labels, ConfigAuditDictionaryKeyCorrelationContext correlation)
Source
Builds child audit entries for value.
pathThe root path being traversed.valueThe value to expand into child entries.sourcesCandidate sources used for child provenance and source selection.factContextProof-limited provenance facts used to attach fact-derived child diagnostics. Pass ConfigAuditFactContext.Empty when resolution produced no facts or when child diagnostics must not infer collection element creation from patch evidence. Non-empty contexts can add diagnostics to the returned ConfigAuditTraversalResult without changing labels, correlations, traversal limits, or the child value shape.optionsTraversal limits, collection opt-ins, and redaction options.visitedReference-tracking set used to avoid cycles.labelsDictionary label state carried through traversal.correlationDictionary key correlation context.The traversed child entries and traversal diagnostics.
ConfigAuditTraversalResult BuildChildren(ConfigAuditPath path, object? value, IReadOnlyList<ConfigAuditSourceRecord> sources, ConfigAuditFactContext factContext, ConfigAuditEntryOptions options, HashSet<object> visited, ConfigAuditDictionaryLabelSet labels, ConfigAuditDictionaryKeyCorrelationContext correlation, ref int budget)
Source
Builds child audit entries for value while sharing the caller-owned traversal budget.
pathThe root path being traversed.valueThe value to expand into child entries.sourcesCandidate sources used for child provenance and source selection.factContextProof-limited provenance facts used to attach fact-derived child diagnostics. Pass ConfigAuditFactContext.Empty when there are no facts; non-empty contexts can mark environment-created or unknown-base collection elements in the returned ConfigAuditTraversalResult.optionsTraversal limits, collection opt-ins, and redaction options.visitedReference-tracking set used to avoid cycles.labelsDictionary label state carried through traversal.correlationDictionary key correlation context.budgetRemaining report-node budget shared across recursive traversal.The traversed child entries and traversal diagnostics.
Creates ConfigurationValidationFailure instances from DataAnnotations results while preserving AppSurface's member-path formatting contract.
ConfigurationValidationFailure FromValidationResult(string key, Type configType, Type valueType, string? path, ValidationResult result, string? defaultMemberName = null)
Source
Converts a ValidationResult into a configuration-validation failure payload.
keyThe configuration key being validated.configTypeThe concrete configuration wrapper type.valueTypeThe resolved value type being validated.pathOptional member path prefix. When present, validation-result member names are combined under this path using dot notation, and the path itself is used when the result has no member names.resultThe validation result to convert.defaultMemberNameOptional fallback member name used when result has no member names, such as field-level validation where DataAnnotations did not bind the member name itself.A normalized ConfigurationValidationFailure.
Describes a display-safe configuration provider condition that must stop lower-priority resolution.
Providers use terminal diagnostics when returning null would be ambiguous. For example, a provider can distinguish a true missing key, which may fall through, from an unavailable secret store, which should not allow lower-priority files to mask the failure. Diagnostic text must not contain raw configuration values.
string ToDisplayString()
Source
Formats this diagnostic for display without exposing raw configuration values.
A multiline display-safe diagnostic string.
string Code { get; }
Source
Gets the stable machine-readable diagnostic code.
string Problem { get; }
Source
Gets the operator-facing problem summary.
string Cause { get; }
Source
Gets the display-safe cause summary.
string Fix { get; }
Source
Gets the suggested next action.
string? Docs { get; }
Source
Gets the optional documentation hint or URL.
bool Retryable { get; }
Source
Gets a value indicating whether retrying the same lookup later may resolve the condition.
Runs command-framework-agnostic config audit diff workflows.
The runner belongs to the config package and intentionally has no dependency on CliFx, AppSurface Console, or any command-specific abstractions. Apps can expose a command that either compares two named environments from the already-built host or compares consumer-owned captured JSON snapshots. Non-fatal workflow failures are converted to display-safe ConfigAuditDiffCommandFailure objects with problem, cause, fix, and documentation fields.
ConfigAuditDiffCommandResult Run(string baselineEnvironment, string targetEnvironment, TextWriter output, ConfigAuditDiffOptions? options = null)
Source
Compares two named environments by asking the current host's reporter for both reports.
baselineEnvironmentThe baseline environment name.targetEnvironmentThe target environment name.outputThe writer that receives rendered diff text.optionsDiff options. The default evidence mode warns that this is same-host evidence.A command-runner result describing success or display-safe failure details.
This workflow is convenient for operator triage, but it reuses the already-built host and should not be treated as proof that two deployed hosts have identical provider inputs. Prefer RunCapturedSnapshots for support evidence collected from each environment.
ConfigAuditDiffCommandResult RunCapturedSnapshots(string baselineSnapshotJson, string targetSnapshotJson, TextWriter output, ConfigAuditDiffOptions? options = null, JsonSerializerOptions? jsonOptions = null)
Source
Compares two captured JSON audit report snapshots.
baselineSnapshotJsonThe baseline JSON snapshot.targetSnapshotJsonThe target JSON snapshot.outputThe writer that receives rendered diff text.optionsDiff options. Defaults are used when this value is null.jsonOptionsOptional JSON serializer options for consumers that captured reports with custom settings.A command-runner result describing success or display-safe failure details.
Captured snapshots are a consumer-owned v1 workflow. Capture each sanitized ConfigAuditReport from the host it describes, store it according to your support-bundle policy, and pass the JSON snapshots here when a command wrapper wants stronger evidence than same-host named-environment comparison.
Enables safe collection element traversal for a discovered configuration wrapper in audit reports.
Apply this attribute to a Config{T} or ConfigStruct{T} wrapper when operators need element-level visibility for that key. Attribute presence enables traversal; there is no separate enabled flag. The limit properties mirror ConfigAuditEntryOptions and are validated when reports are built. Invalid limits emit a config-audit-options-invalid diagnostic and fall back to safe bounded defaults. Non-sensitive dictionary keys may be displayed by default, but sensitive-looking keys are always redacted before structured reports or text output are returned. The attribute is inherited by derived wrappers; place a new attribute on the derived wrapper when it needs different traversal limits. Dictionary key correlation stays disabled unless DictionaryKeyCorrelationMode is set and global correlation key material is configured.
ConfigAuditEntryOptions ToOptions()
Source
Converts the attribute values into immutable audit entry options.
The returned options enable collection traversal, copy attribute values as-is, and mark every traversal option plus dictionary key correlation as assigned. The traversal attribute never assigns entry sensitivity; use manual audit-key options when a discovered wrapper should be classified as sensitive.
int MaxCollectionDepth { get; set; }
Source
Gets or sets the maximum nested collection depth traversed for the attributed wrapper.
The default is ConfigAuditEntryOptions.DefaultMaxCollectionDepth. Values must be greater than or equal to 0; invalid values are reported by audit diagnostics and replaced with the safe default for traversal.
int MaxCollectionElements { get; set; }
Source
Gets or sets the maximum number of elements reported from any one traversed collection.
The default is ConfigAuditEntryOptions.DefaultMaxCollectionElements. Values must be greater than or equal to 0; invalid values are reported by audit diagnostics and replaced with the safe default for traversal.
int MaxReportNodes { get; set; }
Source
Gets or sets the maximum number of child nodes created for the attributed entry before traversal stops.
The default is ConfigAuditEntryOptions.DefaultMaxReportNodes. Values must be greater than or equal to 1; invalid values are reported by audit diagnostics and replaced with the safe default for traversal.
bool DisplayDictionaryKeys { get; set; }
Source
Gets or sets a value indicating whether non-sensitive dictionary keys may appear as element labels.
The default is true. Sensitive-looking dictionary keys are redacted even when this property allows key labels to be displayed.
ConfigAuditDictionaryKeyCorrelationMode DictionaryKeyCorrelationMode { get; set; }
Source
Gets or sets the opt-in dictionary key correlation mode for the attributed wrapper.
The default is ConfigAuditDictionaryKeyCorrelationMode.None, which keeps redacted dictionary key labels report-local. ConfigAuditDictionaryKeyCorrelationMode.ScopedHmac adds opaque correlation ids when ConfigAuditDictionaryKeyCorrelationOptions supplies valid key material.
Default implementation of IConfigManager that aggregates configuration from multiple sources.
void LogKeyNotFound(string key, string environment)
Source
Logs that a configuration key was not found.
keyThe configuration key.environmentThe environment name.void LogRetrievedFromEnvironment(string key, string environment, string source)
Source
Logs that a configuration key was retrieved from a specific source.
keyThe configuration key.environmentThe environment name.sourceThe source of the configuration value.Keeps report display paths separate from provider source paths while child entries are built.
Provides shared state predicates for configuration audit entries.
bool IsPartiallyResolved(ConfigAuditEntry entry)
Source
Determines whether an entry or any descendant represents a partial provider patch.
entryThe entry to inspect.true when the entry is explicitly partial, has a patch source, or contains a partial child.
Validates required resolved presence for strongly typed configuration wrappers.
void Validate(string key, Type configType, Type valueType, bool hasValue)
Source
Throws ConfigurationValidationException when a wrapper marked with ConfigKeyRequiredAttribute has no resolved provider or default value.
keyThe configuration key being initialized.configTypeThe concrete configuration wrapper type being initialized.valueTypeThe declared configuration value type.hasValueWhether provider/default resolution produced a value.