Skip to content

Configuration Reference - Audit Trail Platform (ATP)

Strongly-typed, validated, environment-aware — ATP's configuration management uses .NET Options pattern, Azure App Configuration for dynamic updates, Azure Key Vault for secrets, and hierarchical configuration sources with validation at startup for fail-fast reliability.


📋 Documentation Generation Plan

This document will be generated in 14 cycles. Current progress:

Cycle Topics Estimated Lines Status
Cycle 1 Configuration Architecture & Philosophy (1-2) ~3,000 ⏳ Not Started
Cycle 2 Options Pattern & Validation (3-4) ~3,500 ⏳ Not Started
Cycle 3 appsettings.json Structure (5-6) ~4,000 ⏳ Not Started
Cycle 4 Environment-Specific Configuration (7-8) ~3,500 ⏳ Not Started
Cycle 5 Azure App Configuration (9-10) ~3,500 ⏳ Not Started
Cycle 6 Azure Key Vault Integration (11-12) ~4,000 ⏳ Not Started
Cycle 7 Feature Flags Management (13-14) ~3,000 ⏳ Not Started
Cycle 8 Connection Strings & Database Config (15-16) ~3,000 ⏳ Not Started
Cycle 9 Messaging & Service Bus Configuration (17-18) ~3,000 ⏳ Not Started
Cycle 10 Observability & Monitoring Config (19-20) ~3,000 ⏳ Not Started
Cycle 11 Security & Compliance Settings (21-22) ~3,000 ⏳ Not Started
Cycle 12 Configuration Providers Hierarchy (23-24) ~2,500 ⏳ Not Started
Cycle 13 Testing Configuration & Overrides (25-26) ~2,500 ⏳ Not Started
Cycle 14 Best Practices & Troubleshooting (27-28) ~3,000 ⏳ Not Started

Total Estimated Lines: ~44,000


Purpose & Scope

This document provides the complete configuration reference for the Audit Trail Platform (ATP), covering all configuration sources, strongly-typed options classes, validation rules, environment-specific overrides, Azure App Configuration integration, Key Vault secrets management, and feature flags.

Key Configuration Principles - Strongly-Typed: Options pattern with C# classes, not magic strings - Validated: Data annotation validation at startup (fail-fast) - Environment-Aware: Hierarchical configuration with environment overrides - Secrets-Safe: No secrets in appsettings.json, all from Key Vault - Dynamic: Azure App Configuration for runtime updates without redeploy - Auditable: Configuration changes tracked in App Configuration history - Testable: Override configuration in tests easily

Configuration Sources (Precedence Order) 1. appsettings.json (base configuration) 2. appsettings.{Environment}.json (environment-specific overrides) 3. Azure App Configuration (dynamic, centralized configuration) 4. Environment Variables (container/Kubernetes overrides) 5. Command-Line Arguments (runtime overrides) 6. Azure Key Vault (secrets referenced from App Configuration or direct)


Detailed Cycle Plan

CYCLE 1: Configuration Architecture & Philosophy (~3,000 lines)

Topic 1: ATP Configuration Architecture

What will be covered: - Configuration Architecture Overview - Hierarchical configuration sources - .NET configuration system fundamentals - IConfiguration abstraction - Configuration providers and precedence

  • ATP Configuration Philosophy
  • Fail-Fast: Validate configuration at startup, not runtime
  • Type-Safe: Use Options pattern (strongly-typed classes)
  • Environment-Specific: Layered overrides per environment
  • Secrets-External: Never store secrets in code or appsettings
  • Dynamic-Ready: Support runtime configuration updates (App Configuration)
  • Auditable: Track all configuration changes with history

  • Configuration Layers

    Priority (Last Wins):
    1. appsettings.json (base, committed to Git)
    2. appsettings.{Environment}.json (dev/staging/prod overrides)
    3. Azure App Configuration (centralized, dynamic)
    4. Environment Variables (container/K8s, CI/CD)
    5. Command-Line Arguments (dotnet run --arg=value)
    6. Key Vault References (secrets from Azure Key Vault)
    

  • ATP Configuration Domains

  • Core: Microservice name, startup settings, localization
  • Persistence: NHibernate/MongoDB connection strings, caching
  • Messaging: Azure Service Bus, MassTransit configuration
  • Observability: Application Insights, OpenTelemetry, logging
  • Security: Authentication, authorization, encryption keys
  • Compliance: PII redaction, data classification, retention policies
  • Performance: Rate limiting, timeouts, batch sizes
  • Feature Flags: Dynamic feature toggles per environment/tenant

Code Examples: - Configuration builder setup (Program.cs) - Configuration hierarchy visualization - appsettings.json base structure

Diagrams: - Configuration architecture layers - Configuration source precedence - ATP configuration domains

Deliverables: - Configuration architecture overview - Configuration philosophy document - Layer precedence guide


Topic 2: Configuration Providers Overview

What will be covered: - .NET Configuration Providers - JsonConfigurationProvider (appsettings.json) - EnvironmentVariablesConfigurationProvider - CommandLineConfigurationProvider - AzureAppConfigurationProvider - KeyVaultConfigurationProvider (via App Configuration)

  • Configuration Builder Pattern

    private static void DefineConfiguration(
        string[] args,
        HostBuilderContext hostBuilderContext,
        IConfigurationBuilder configurationBuilder)
    {
        configurationBuilder.Sources.Clear();
    
        // 1. Base configuration (appsettings.json)
        configurationBuilder
            .SetBasePath(hostBuilderContext.HostingEnvironment.ContentRootPath)
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);
    
        // 2. Environment-specific configuration
        configurationBuilder.AddJsonFile(
            $"appsettings.{hostBuilderContext.HostingEnvironment.EnvironmentName}.json",
            optional: true,
            reloadOnChange: true);
    
        // 3. Azure App Configuration (dynamic, centralized)
        if (UseAzureAppConfiguration)
        {
            configurationBuilder.AddAzureAppConfiguration(options =>
            {
                options.Connect(connectionString)
                    .Select("ConnectSoft.Audit:*", LabelFilter.Null)
                    .ConfigureRefresh(refresh =>
                    {
                        refresh.Register("ConnectSoft.Audit:Settings:Sentinel", refreshAll: true);
                        refresh.SetRefreshInterval(TimeSpan.FromMinutes(30));
                    })
                    .ConfigureKeyVault(kv =>
                    {
                        kv.SetCredential(new DefaultAzureCredential());
                    });
            });
        }
    
        // 4. Environment variables (container/K8s overrides)
        configurationBuilder.AddEnvironmentVariables();
    
        // 5. Command-line arguments (runtime overrides)
        configurationBuilder.AddCommandLine(args);
    }
    

  • Provider Selection Strategy

  • Development: appsettings.json + env vars
  • Docker: appsettings.Docker.json + env vars
  • Kubernetes: App Configuration + Key Vault + env vars
  • CI/CD: Minimal appsettings + pipeline variables

Code Examples: - Complete configuration builder setup - Provider registration order - Environment-aware provider selection

Diagrams: - Configuration providers hierarchy - Provider selection by environment

Deliverables: - Configuration providers guide - Builder setup patterns - Provider selection logic


CYCLE 2: Options Pattern & Validation (~3,500 lines)

Topic 3: Options Pattern Fundamentals

What will be covered: - Why Options Pattern? - Strong typing (compile-time safety) - Validation (fail at startup) - Testability (inject test options) - IntelliSense support - Refactoring-friendly

  • IOptions vs. IOptionsSnapshot vs. IOptionsMonitor

    // IOptions<T> - Singleton, no reload
    public class SingletonService
    {
        public SingletonService(IOptions<MicroserviceOptions> options)
        {
            var value = options.Value; // Read once, never changes
        }
    }
    
    // IOptionsSnapshot<T> - Scoped, reloads per request
    public class ScopedService
    {
        public ScopedService(IOptionsSnapshot<MassTransitOptions> options)
        {
            var value = options.Value; // Reloaded from App Config per request
        }
    }
    
    // IOptionsMonitor<T> - Singleton, reactive to changes
    public class MonitorService
    {
        public MonitorService(IOptionsMonitor<FeatureFlagsOptions> options)
        {
            options.OnChange(newOptions =>
            {
                // React to configuration changes at runtime
                Logger.Log("FeatureFlags updated: {0}", newOptions.FeatureA);
            });
        }
    }
    

  • Options Class Definition

    public sealed class AuditIngestionOptions
    {
        public const string SectionName = "Ingestion";
    
        [Required]
        [Range(1, 10000)]
        public int MaxBatchSize { get; set; } = 1000;
    
        [Required]
        [Range(1, 3600)]
        public int BatchTimeoutSeconds { get; set; } = 30;
    
        [Required]
        public bool EnableClassification { get; set; } = true;
    
        [ValidateObjectMembers]
        public RetryPolicyOptions RetryPolicy { get; set; } = new();
    }
    
    public class RetryPolicyOptions
    {
        [Required]
        [Range(0, 10)]
        public int MaxRetries { get; set; } = 3;
    
        [Required]
        [Range(1, 300)]
        public int RetryDelaySeconds { get; set; } = 5;
    }
    

  • Options Registration

    services.AddOptions<AuditIngestionOptions>()
        .BindConfiguration(AuditIngestionOptions.SectionName)
        .ValidateDataAnnotations()
        .ValidateOnStart();
    
    // With custom validator
    services.AddSingleton<IValidateOptions<AuditIngestionOptions>, 
        AuditIngestionOptionsValidator>();
    

Code Examples: - Options class definitions (all ATP options) - IOptions vs. IOptionsSnapshot vs. IOptionsMonitor usage - Options registration patterns - Custom validator implementation

Diagrams: - Options pattern class diagram - Options lifetime comparison - Registration flow

Deliverables: - Options pattern guide - ATP options classes - Registration templates


Topic 4: Configuration Validation

What will be covered: - Data Annotation Validation - [Required]: Must have value - [Range]: Numeric bounds - [RegularExpression]: Pattern matching - [Url], [EmailAddress]: Format validation - [ValidateObjectMembers]: Validate nested objects

  • Custom Validation

    public class AuditIngestionOptionsValidator : IValidateOptions<AuditIngestionOptions>
    {
        public ValidateOptionsResult Validate(string name, AuditIngestionOptions options)
        {
            var failures = new List<string>();
    
            if (options.MaxBatchSize < 1 || options.MaxBatchSize > 10000)
            {
                failures.Add("MaxBatchSize must be between 1 and 10000");
            }
    
            if (options.BatchTimeoutSeconds < 1)
            {
                failures.Add("BatchTimeoutSeconds must be positive");
            }
    
            if (options.RetryPolicy.MaxRetries < 0)
            {
                failures.Add("RetryPolicy.MaxRetries must be non-negative");
            }
    
            return failures.Count == 0
                ? ValidateOptionsResult.Success
                : ValidateOptionsResult.Fail(failures);
        }
    }
    

  • Validation Timing

  • Eager (ValidateOnStart): Validate at application startup
  • Lazy: Validate on first access (IOptions.Value)
  • ATP uses ValidateOnStart: Fail-fast, no runtime surprises

  • Validation Error Handling

  • OptionsValidationException thrown at startup
  • Clear error messages with property names
  • Application won't start if invalid configuration

Code Examples: - Data annotation validation (all options) - Custom IValidateOptions implementation - Validation failure handling - Error message formatting

Diagrams: - Validation flow (startup) - Validation error handling

Deliverables: - Validation strategy - Custom validators - Error handling guide


CYCLE 3: appsettings.json Structure (~4,000 lines)

Topic 5: Base Configuration Structure

What will be covered: - appsettings.json Organization

{
  "Microservice": {
    "MicroserviceName": "ConnectSoft.Audit.Ingestion",
    "StartupWarmupSeconds": 20
  },

  "Ingestion": {
    "MaxBatchSize": 1000,
    "BatchTimeoutSeconds": 30,
    "EnableClassification": true,
    "RetryPolicy": {
      "MaxRetries": 3,
      "RetryDelaySeconds": 5
    }
  },

  "Validation": {
    "EnableClassLevelFailFast": true,
    "EnableRuleLevelFailFast": true
  },

  "Compliance": {
    "EnableLoggingRedaction": true,
    "StrictInDevelopment": false,
    "Profile": "default"
  },

  "ServiceDiscovery": {
    "Enabled": true,
    "ServiceDiscoveryProvider": "Configuration",
    "RefreshPeriod": "00:01:00"
  },

  "MicroserviceLocalization": {
    "ResourcesPath": "Resources",
    "DefaultRequestCulture": "en-US",
    "SupportedCultures": ["en-US", "en-GB", "de-DE"],
    "SupportedUICultures": ["en-US", "en-GB", "de-DE"]
  },

  "PersistenceModel": {
    "NHibernate": {
      "NHibernateConfigFile": "hibernate.cfg.xml",
      "NHibernateConnectionStringKey": "ConnectSoft.Audit.SqlServer"
    }
  },

  "ConnectionStrings": {
    "ConnectSoft.Audit.SqlServer": "Server=...; (stored in Key Vault in production)",
    "AzureAppConfiguration": "Endpoint=https://...; (Key Vault ref)",
    "AzureServiceBus": "Endpoint=sb://...; (Key Vault ref)"
  },

  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },

  "AllowedHosts": "*"
}

  • Section Organization Principles
  • Group by domain/concern (not alphabetically)
  • Core settings first, specialized settings later
  • Nested objects for hierarchical settings
  • Comments for non-obvious values

  • Naming Conventions

  • Section names: PascalCase (e.g., "Microservice")
  • Property names: PascalCase (e.g., "MicroserviceName")
  • Matches C# property names exactly
  • Connection strings: Fully qualified (e.g., "ConnectSoft.Audit.SqlServer")

Code Examples: - Complete appsettings.json (all ATP services) - Section organization patterns - Nested configuration examples

Diagrams: - appsettings.json structure tree - Section organization by domain

Deliverables: - appsettings.json templates (all ATP services) - Organization guidelines - Naming conventions


Topic 6: ATP Configuration Sections Reference

What will be covered: - Core Configuration Sections

{
  "Microservice": { /* Service identification */ },
  "Validation": { /* FluentValidation behavior */ },
  "Compliance": { /* PII redaction, logging */ },
  "ServiceDiscovery": { /* Service endpoint resolution */ },
  "MicroserviceLocalization": { /* i18n, cultures */ },
  "Logging": { /* Serilog, log levels */ },
  "AllowedHosts": "*"
}

  • Persistence Configuration

    {
      "PersistenceModel": {
        "NHibernate": {
          "NHibernateConfigFile": "hibernate.cfg.xml",
          "NHibernateConnectionStringKey": "ConnectSoft.Audit.SqlServer"
        }
      },
      "ConnectionStrings": {
        "ConnectSoft.Audit.SqlServer": "@Microsoft.KeyVault(SecretUri=https://kv-atp-prod.vault.azure.net/secrets/sql-connection/)"
      }
    }
    

  • Messaging Configuration

    {
      "MassTransit": {
        "HostOptions": {
          "StartTimeout": "00:01:00",
          "StopTimeout": "00:01:00"
        },
        "AzureServiceBusTransport": {
          "AzureServiceBusHost": {
            "FullyQualifiedNamespace": "atp-prod.servicebus.windows.net",
            "UseManagedIdentity": true,
            "OperationTimeoutSeconds": 60
          },
          "AzureServiceBusReceiveEndpoint": {
            "PrefetchCount": 32,
            "ConcurrentMessageLimit": 64
          }
        }
      }
    }
    

  • Observability Configuration

    {
      "ApplicationInsights": {
        "ConnectionString": "@Microsoft.KeyVault(...)",
        "EnableAdaptiveSampling": true,
        "SamplingPercentage": 10.0
      },
      "OpenTelemetry": {
        "ServiceName": "atp-ingestion",
        "ServiceVersion": "1.0.0",
        "ExporterEndpoint": "http://otel-collector:4317"
      }
    }
    

Code Examples: - Complete configuration sections (all ATP domains) - Key Vault reference syntax - Managed Identity configuration

Diagrams: - ATP configuration sections map - Key Vault reference resolution

Deliverables: - Complete configuration reference - All ATP configuration sections - Key Vault reference patterns


CYCLE 4: Environment-Specific Configuration (~3,500 lines)

Topic 7: Environment-Specific Files

What will be covered: - appsettings.{Environment}.json Files - appsettings.Development.json (local dev) - appsettings.Docker.json (Docker containers) - appsettings.Test.json (CI testing) - appsettings.Staging.json (pre-production) - appsettings.Production.json (live environment)

  • appsettings.Development.json Example

    {
      "Microservice": {
        "MicroserviceName": "ConnectSoft.Audit.Ingestion.Dev",
        "StartupWarmupSeconds": 5
      },
    
      "Ingestion": {
        "MaxBatchSize": 100,
        "EnableClassification": false
      },
    
      "ConnectionStrings": {
        "ConnectSoft.Audit.SqlServer": "Server=(localdb)\\MSSQLLocalDB;Database=AuditDev;Integrated Security=True;"
      },
    
      "MassTransit": {
        "AzureServiceBusTransport": {
          "AzureServiceBusHost": {
            "FullyQualifiedNamespace": "atp-dev.servicebus.windows.net",
            "UseManagedIdentity": false,
            "ConnectionString": "Endpoint=sb://atp-dev..."
          }
        }
      },
    
      "Logging": {
        "LogLevel": {
          "Default": "Debug",
          "Microsoft": "Debug"
        }
      },
    
      "ApplicationInsights": {
        "EnableAdaptiveSampling": false
      }
    }
    

  • appsettings.Production.json Example

    {
      "Microservice": {
        "MicroserviceName": "ConnectSoft.Audit.Ingestion",
        "StartupWarmupSeconds": 60
      },
    
      "Ingestion": {
        "MaxBatchSize": 5000,
        "EnableClassification": true
      },
    
      "ConnectionStrings": {
        "ConnectSoft.Audit.SqlServer": "@Microsoft.KeyVault(SecretUri=https://kv-atp-prod.vault.azure.net/secrets/sql-connection/)",
        "AzureServiceBus": "@Microsoft.KeyVault(SecretUri=https://kv-atp-prod.vault.azure.net/secrets/servicebus-connection/)"
      },
    
      "MassTransit": {
        "AzureServiceBusTransport": {
          "AzureServiceBusHost": {
            "FullyQualifiedNamespace": "atp-prod.servicebus.windows.net",
            "UseManagedIdentity": true
          },
          "AzureServiceBusReceiveEndpoint": {
            "PrefetchCount": 256,
            "ConcurrentMessageLimit": 512
          }
        }
      },
    
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning"
        }
      },
    
      "ApplicationInsights": {
        "EnableAdaptiveSampling": true,
        "SamplingPercentage": 10.0
      }
    }
    

  • Environment Selection

  • ASPNETCORE_ENVIRONMENT variable
  • Determines which appsettings.{Environment}.json loads
  • Set in: launchSettings.json, Kubernetes ConfigMap, Docker Compose

Code Examples: - Complete environment-specific files (all environments) - Environment variable configuration - launchSettings.json setup

Diagrams: - Environment file hierarchy - Environment selection flow

Deliverables: - All environment-specific appsettings files - Environment configuration guide - Override patterns


Topic 8: Configuration Overrides & Precedence

What will be covered: - Override Rules - Later sources override earlier sources - Nested sections merged (not replaced entirely) - Array values replaced (not merged) - Null values explicit override

  • Example: Configuration Override

    // appsettings.json (base)
    {
      "Ingestion": {
        "MaxBatchSize": 1000,
        "BatchTimeoutSeconds": 30,
        "EnableClassification": true
      }
    }
    
    // appsettings.Production.json (override)
    {
      "Ingestion": {
        "MaxBatchSize": 5000
        // BatchTimeoutSeconds and EnableClassification inherited from base
      }
    }
    
    // Result in Production:
    {
      "Ingestion": {
        "MaxBatchSize": 5000,           // Overridden
        "BatchTimeoutSeconds": 30,      // Inherited
        "EnableClassification": true    // Inherited
      }
    }
    

  • Environment Variable Overrides

    # Override nested configuration with double underscore
    export Ingestion__MaxBatchSize=2000
    export ConnectionStrings__ConnectSoft__Audit__SqlServer="Server=..."
    
    # Kubernetes ConfigMap
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: atp-ingestion-config
    data:
      Ingestion__MaxBatchSize: "5000"
      Ingestion__EnableClassification: "true"
    

  • Command-Line Overrides

    dotnet run --Ingestion:MaxBatchSize=2000 --Logging:LogLevel:Default=Debug
    

Code Examples: - Override examples (all methods) - Environment variable syntax - Kubernetes ConfigMap configuration - Command-line argument parsing

Diagrams: - Override precedence visualization - Configuration merge strategy

Deliverables: - Override patterns guide - Environment variable syntax - Precedence rules


CYCLE 5: Azure App Configuration (~3,500 lines)

Topic 9: Azure App Configuration Integration

What will be covered: - Why Azure App Configuration? - Centralized configuration management - Dynamic updates without redeployment - Feature flags with targeting - Configuration versioning and history - Key Vault reference support - Label-based environment separation

  • Connection Setup

    configurationBuilder.AddAzureAppConfiguration(options =>
    {
        // Connect via connection string or Managed Identity
        var connectionString = configuration.GetConnectionString("AzureAppConfiguration");
        options.Connect(connectionString);
    
        // Or use Managed Identity (production)
        options.Connect(new Uri("https://appconfig-atp-prod.azconfig.io"))
            .ConfigureKeyVault(kv =>
            {
                kv.SetCredential(new DefaultAzureCredential());
            });
    
        // Select configuration keys (prefix-based)
        options.Select("ConnectSoft.Audit:*", LabelFilter.Null);
    
        // Configure refresh (dynamic updates)
        options.ConfigureRefresh(refresh =>
        {
            // Register sentinel key (change this to refresh all)
            refresh.Register("ConnectSoft.Audit:Settings:Sentinel", refreshAll: true);
            refresh.SetRefreshInterval(TimeSpan.FromMinutes(30));
        });
    
        // Feature flags
        options.UseFeatureFlags(featureFlags =>
        {
            featureFlags.Select("ConnectSoft.Audit:*", LabelFilter.Null);
            featureFlags.SetRefreshInterval(TimeSpan.FromMinutes(5));
        });
    });
    
    // Middleware to enable refresh
    app.UseAzureAppConfiguration();
    

  • Key Organization in App Configuration

    Key Pattern: {AppName}:{Section}:{Subsection}:{Property}
    
    Examples:
    - ConnectSoft.Audit:Ingestion:MaxBatchSize
    - ConnectSoft.Audit:Ingestion:RetryPolicy:MaxRetries
    - ConnectSoft.Audit:ConnectionStrings:SqlServer
    - ConnectSoft.Audit:FeatureFlags:EnableNewExportFormat
    

  • Labels for Environments

  • Label = environment name (dev, test, staging, prod)
  • Same key, different values per label
  • Application selects label based on environment

  • Dynamic Refresh

  • Sentinel key pattern: Change "Sentinel" to trigger full refresh
  • Refresh interval: 30 minutes (configurable)
  • Middleware polls App Configuration periodically
  • IOptionsSnapshot reflects updated values

Code Examples: - App Configuration connection (all methods) - Key selection and filtering - Dynamic refresh configuration - Middleware setup

Diagrams: - App Configuration architecture - Key organization structure - Label-based environment separation - Dynamic refresh flow

Deliverables: - App Configuration setup guide - Key organization standards - Refresh configuration


Topic 10: Configuration Versioning & History

What will be covered: - Snapshot & Restore - Create configuration snapshots - Restore to previous snapshot - Snapshot labeling and tags

  • Change History
  • Track all configuration changes
  • Who changed what and when
  • Audit trail for compliance

  • Import/Export

  • Export configuration to JSON
  • Import from Git repository
  • Automated sync from Git

Code Examples: - Snapshot creation (Azure CLI) - History query (Azure CLI/Portal) - Import/export scripts - Git sync automation

Diagrams: - Versioning workflow - Snapshot restore flow

Deliverables: - Versioning procedures - History audit queries - Import/export scripts


CYCLE 6: Azure Key Vault Integration (~4,000 lines)

Topic 11: Key Vault Secret References

What will be covered: - Key Vault Reference Syntax

{
  "ConnectionStrings": {
    "SqlServer": "@Microsoft.KeyVault(SecretUri=https://kv-atp-prod.vault.azure.net/secrets/sql-connection/)",
    "ServiceBus": "@Microsoft.KeyVault(VaultName=kv-atp-prod;SecretName=servicebus-connection)",
    "BlobStorage": "@Microsoft.KeyVault(SecretUri=https://kv-atp-prod.vault.azure.net/secrets/blob-connection/72f988bf89f74)"
  }
}

  • Key Vault Configuration Provider

    configurationBuilder.AddAzureAppConfiguration(options =>
    {
        options.Connect(endpoint)
            .ConfigureKeyVault(kv =>
            {
                // Use Managed Identity
                kv.SetCredential(new DefaultAzureCredential());
    
                // Or User-Assigned Managed Identity
                kv.SetCredential(new ManagedIdentityCredential(clientId));
    
                // Set secret refresh interval
                kv.SetSecretRefreshInterval(TimeSpan.FromMinutes(60));
            });
    });
    
    // Direct Key Vault provider (without App Configuration)
    configurationBuilder.AddAzureKeyVault(
        new Uri("https://kv-atp-prod.vault.azure.net/"),
        new DefaultAzureCredential());
    

  • Secret Categories in Key Vault

    ATP Key Vault Secrets:
    - sql-connection                (Azure SQL connection string)
    - servicebus-connection         (Azure Service Bus connection string)
    - blob-storage-connection       (Azure Blob Storage connection string)
    - cosmos-connection             (Cosmos DB connection string)
    - redis-connection              (Redis cache connection string)
    - appinsights-key               (Application Insights instrumentation key)
    - signing-key-2025-Q1           (HSM-backed signing key for integrity)
    - encryption-key-kek            (Key Encryption Key)
    - webhook-hmac-secret           (HMAC secret for webhook signatures)
    - external-api-key-*            (Third-party API keys)
    

  • Secret Naming Conventions

  • Lowercase with hyphens: sql-connection
  • Version suffix for rotation: signing-key-2025-Q1
  • Category prefix: external-api-key-stripe

Code Examples: - Key Vault reference syntax (all variations) - Key Vault configuration provider setup - Managed Identity authentication - Secret organization patterns

Diagrams: - Key Vault integration architecture - Secret reference resolution flow - Managed Identity access

Deliverables: - Key Vault integration guide - Secret naming conventions - Reference syntax catalog


Topic 12: Secrets Management & Rotation

What will be covered: - Secret Rotation Strategy - Automated rotation (Key Vault + Azure Automation) - Zero-downtime rotation (dual-secret pattern) - Rotation schedule (90 days for connection strings, 180 days for keys) - Verification after rotation

  • Dual-Secret Pattern

    {
      "ConnectionStrings": {
        "SqlServer": "@Microsoft.KeyVault(SecretUri=https://.../sql-connection-current/)",
        "SqlServerPrevious": "@Microsoft.KeyVault(SecretUri=https://.../sql-connection-previous/)"
      }
    }
    

  • Secret Refresh

  • Automatic refresh interval (hourly)
  • IOptionsSnapshot reflects updated secrets
  • Connection pool draining on secret change

  • Secret Access Control

  • Managed Identity (System-Assigned or User-Assigned)
  • RBAC roles: Key Vault Secrets User (read-only)
  • No Key Vault Administrator role for applications
  • Audit all secret access (diagnostic settings)

Code Examples: - Secret rotation automation (Azure Functions) - Dual-secret configuration - Secret refresh implementation - Access control setup (RBAC)

Diagrams: - Secret rotation workflow - Dual-secret pattern - Access control model

Deliverables: - Secret rotation procedures (see key-rotation.md) - Dual-secret implementation - Access control guide


CYCLE 7: Feature Flags Management (~3,000 lines)

Topic 13: Feature Flags with Microsoft.FeatureManagement

What will be covered: - Feature Flag Basics - Toggle features on/off at runtime - No code deployment required - A/B testing, gradual rollout, kill switches

  • Feature Flag Definition

    {
      "FeatureManagement": {
        "EnableNewExportFormat": true,
        "EnableAdvancedSearch": false,
        "EnableIntegrityVerification": {
          "EnabledFor": [
            {
              "Name": "Percentage",
              "Parameters": {
                "Value": 50
              }
            }
          ]
        },
        "EnableBetaFeatures": {
          "EnabledFor": [
            {
              "Name": "TimeWindow",
              "Parameters": {
                "Start": "2025-11-01T00:00:00Z",
                "End": "2025-12-31T23:59:59Z"
              }
            }
          ]
        }
      }
    }
    

  • Feature Flag Usage in Code

    public class ExportService
    {
        private readonly IFeatureManager _featureManager;
    
        public async Task<ExportPackage> CreateExportAsync(ExportRequest request)
        {
            if (await _featureManager.IsEnabledAsync("EnableNewExportFormat"))
            {
                return await CreateExportV2Async(request);
            }
            else
            {
                return await CreateExportV1Async(request);
            }
        }
    }
    
    // Or use feature gate filter (ASP.NET Core)
    [FeatureGate("EnableAdvancedSearch")]
    [HttpGet("search/advanced")]
    public async Task<IActionResult> AdvancedSearch([FromQuery] SearchQuery query)
    {
        // Only accessible if feature flag enabled
    }
    

  • Feature Filters

  • PercentageFilter: Enable for N% of requests (gradual rollout)
  • TimeWindowFilter: Enable between specific dates
  • TargetingFilter: Enable for specific users/groups/tenants
  • Custom Filters: ATP-specific (e.g., edition-based, tenant-based)

Code Examples: - Feature flag definition (all patterns) - IFeatureManager usage - FeatureGate attribute - Custom feature filter (tenant-based)

Diagrams: - Feature flag architecture - Gradual rollout timeline - Targeting filter logic

Deliverables: - Feature flags guide - All ATP feature flags - Custom filter implementations


Topic 14: Azure App Configuration Feature Flags

What will be covered: - Feature Flags in App Configuration - Centralized feature flag management - UI for non-technical users (PMs, QA) - Label-based environment separation - Targeting rules (users, groups, percentages)

  • Integration with .NET

    configurationBuilder.AddAzureAppConfiguration(options =>
    {
        options.Connect(endpoint)
            .UseFeatureFlags(featureFlags =>
            {
                featureFlags.Select("ConnectSoft.Audit:*", LabelFilter.Null);
                featureFlags.SetRefreshInterval(TimeSpan.FromMinutes(5));
                featureFlags.CacheExpirationInterval = TimeSpan.FromMinutes(5);
            });
    });
    
    // Add feature management services
    services.AddFeatureManagement()
        .AddFeatureFilter<PercentageFilter>()
        .AddFeatureFilter<TimeWindowFilter>()
        .AddFeatureFilter<TargetingFilter>();
    
    // Add middleware to refresh feature flags
    app.UseAzureAppConfiguration();
    

  • Targeting Filters (Advanced)

  • Target specific tenants: { "tenants": ["acme", "contoso"] }
  • Target specific editions: { "editions": ["enterprise"] }
  • Target percentage: { "percentage": 25 }
  • Default behavior: Enable/disable for all

Code Examples: - App Configuration feature flag setup - Targeting filter configuration - Feature flag refresh middleware - Per-tenant feature flag example

Diagrams: - App Configuration feature flags architecture - Targeting filter decision tree

Deliverables: - App Configuration feature flags guide - Targeting configuration - Refresh patterns


CYCLE 8: Connection Strings & Database Config (~3,000 lines)

Topic 15: Connection String Management

What will be covered: - Connection String Patterns

{
  "ConnectionStrings": {
    // Azure SQL
    "ConnectSoft.Audit.SqlServer": "Server=tcp:atp-prod.database.windows.net;Database=AuditDb;Authentication=Active Directory Default;",

    // Cosmos DB
    "ConnectSoft.Audit.CosmosDb": "AccountEndpoint=https://atp-cosmos.documents.azure.com:443/;",

    // Azure Service Bus (Managed Identity)
    "AzureServiceBus": "Endpoint=sb://atp-prod.servicebus.windows.net",

    // Redis Cache
    "Redis": "atp-redis.redis.cache.windows.net:6380,ssl=true,abortConnect=False",

    // Blob Storage (Managed Identity)
    "BlobStorage": "https://atpprod.blob.core.windows.net",

    // Azure App Configuration
    "AzureAppConfiguration": "Endpoint=https://appconfig-atp-prod.azconfig.io"
  }
}

  • Managed Identity for Connections
  • No passwords in connection strings (production)
  • Authentication=Active Directory Default for SQL
  • Endpoint-only for Service Bus, Blob Storage
  • DefaultAzureCredential resolution chain

  • Development vs. Production

  • Development: LocalDB, localhost, connection strings with passwords
  • Production: Azure services, Managed Identity, no passwords

  • Connection String Retrieval

    // From IConfiguration
    var connectionString = configuration.GetConnectionString("ConnectSoft.Audit.SqlServer");
    
    // From Key Vault reference (automatic)
    // appsettings.json:
    // "ConnectSoft.Audit.SqlServer": "@Microsoft.KeyVault(SecretUri=...)"
    // Resolved automatically by configuration system
    

Code Examples: - Connection strings (all ATP data stores) - Managed Identity configuration - Key Vault reference patterns - Connection string builders

Diagrams: - Connection string resolution flow - Managed Identity authentication

Deliverables: - Connection string reference - Managed Identity setup - Key Vault patterns


Topic 16: Database Configuration Options

What will be covered: - NHibernate Configuration - hibernate.cfg.xml file path - Connection string key reference - Dialect selection - Batch size, caching, logging

  • MongoDB Configuration (optional)
  • Connection string
  • Database name
  • Collection naming

  • Connection Pooling

  • Min/max pool size
  • Connection lifetime
  • Pool exhaustion handling

  • Retry Policies

  • Transient fault handling
  • Exponential backoff
  • Max retry attempts

Code Examples: - NHibernate options configuration - MongoDB options configuration - Connection pool settings - Retry policy configuration

Diagrams: - Database configuration hierarchy - Connection pooling architecture

Deliverables: - Database configuration reference - Pool sizing guide - Retry policy patterns


CYCLE 9: Messaging & Service Bus Configuration (~3,000 lines)

Topic 17: MassTransit Configuration

What will be covered: - MassTransit Options Structure

{
  "MassTransit": {
    "HostOptions": {
      "StartTimeout": "00:01:00",
      "StopTimeout": "00:01:00"
    },

    "AzureServiceBusTransport": {
      "AzureServiceBusHost": {
        "FullyQualifiedNamespace": "atp-prod.servicebus.windows.net",
        "UseManagedIdentity": true,
        "ClientId": "",
        "UseWebSockets": false,
        "OperationTimeoutSeconds": 60
      },

      "AzureServiceBusReceiveEndpoint": {
        "PrefetchCount": 256,
        "ConcurrentMessageLimit": 512
      },

      "RetryLimit": 5,
      "RetryMinBackoffSeconds": 1,
      "RetryMaxBackoffSeconds": 30
    }
  }
}

  • Endpoint Configuration
  • Consumer-specific prefetch and concurrency
  • Retry policies per endpoint
  • Circuit breaker configuration
  • Rate limiting

  • Environment-Specific Tuning

    Setting              | Dev  | Test | Staging | Production
    ---------------------|------|------|---------|------------
    PrefetchCount        | 8    | 16   | 64      | 256
    ConcurrentMsgLimit   | 16   | 32   | 128     | 512
    RetryLimit           | 2    | 3    | 5       | 5
    UseManagedIdentity   | No   | No   | Yes     | Yes
    

Code Examples: - Complete MassTransit options - Environment-specific overrides - Endpoint configuration patterns

Diagrams: - MassTransit configuration hierarchy - Environment tuning matrix

Deliverables: - MassTransit configuration reference - Tuning guide per environment - Endpoint configuration patterns


Topic 18: Service Bus Namespace Configuration

What will be covered: - Namespace Selection - Development: Shared namespace (Standard tier) - Production: Dedicated namespace (Premium tier) - Per-environment namespaces

  • Connection Methods
  • Connection string (dev/test)
  • Managed Identity (staging/prod)
  • Private endpoint configuration

  • Queue & Topic Configuration

  • Max message size
  • TTL (time-to-live)
  • Duplicate detection window
  • Partitioning enabled

Code Examples: - Service Bus namespace configuration - Connection methods (all) - Queue/topic settings

Diagrams: - Service Bus topology - Connection method selection

Deliverables: - Service Bus configuration guide - Namespace strategy - Connection patterns


CYCLE 10: Observability & Monitoring Config (~3,000 lines)

Topic 19: Application Insights Configuration

What will be covered: - Application Insights Options

{
  "ApplicationInsights": {
    "ConnectionString": "@Microsoft.KeyVault(SecretUri=https://.../appinsights-connection/)",
    "EnableAdaptiveSampling": true,
    "SamplingPercentage": 10.0,
    "EnableQuickPulseMetricStream": true,
    "EnableDependencyTracking": true,
    "EnablePerformanceCounterCollection": true,
    "EnableEventCounterCollection": true,
    "EnableHeartbeat": true
  }
}

  • Sampling Configuration
  • Development: 100% (no sampling)
  • Staging: 50% sampling
  • Production: 10% sampling (cost optimization)
  • Adaptive sampling (automatic adjustment)

  • Telemetry Filtering

  • Filter out health check requests
  • Filter out internal calls
  • Redact PII from telemetry

  • Custom Telemetry Initializers

  • Add tenantId to all telemetry
  • Add edition context
  • Add correlation IDs

Code Examples: - Application Insights configuration (complete) - Sampling configuration - Telemetry filtering - Custom initializers

Diagrams: - Application Insights architecture - Sampling strategy per environment

Deliverables: - App Insights configuration guide - Sampling recommendations - Telemetry filtering patterns


Topic 20: OpenTelemetry Configuration

What will be covered: - OpenTelemetry Options

{
  "OpenTelemetry": {
    "ServiceName": "atp-ingestion",
    "ServiceVersion": "1.0.0",
    "ServiceNamespace": "ConnectSoft.Audit",
    "ServiceInstanceId": "${HOSTNAME}",

    "ExporterType": "OTLP",
    "OtlpExporterEndpoint": "http://otel-collector:4317",
    "OtlpExporterProtocol": "Grpc",

    "EnableTracing": true,
    "EnableMetrics": true,
    "EnableLogging": true,

    "TraceSampler": "ParentBased",
    "TraceSamplingRatio": 0.1,

    "MetricExportIntervalMs": 60000,
    "MetricExportTimeoutMs": 30000
  }
}

  • Resource Attributes
  • service.name, service.version
  • deployment.environment (dev/staging/prod)
  • cloud.provider (azure), cloud.region
  • k8s.pod.name, k8s.namespace

  • Instrumentation Configuration

  • ASP.NET Core instrumentation
  • HttpClient instrumentation
  • SQL Client instrumentation
  • Azure SDK instrumentation

Code Examples: - OpenTelemetry configuration (complete) - Resource attributes setup - Instrumentation registration - Exporter configuration

Diagrams: - OpenTelemetry architecture - Trace/metric/log export flow

Deliverables: - OTel configuration reference - Instrumentation guide - Exporter setup


CYCLE 11: Security & Compliance Settings (~3,000 lines)

Topic 21: Authentication & Authorization Configuration

What will be covered: - JWT Authentication Configuration

{
  "Authentication": {
    "JwtBearer": {
      "Authority": "https://login.microsoftonline.com/{tenantId}/v2.0",
      "Audience": "api://atp-ingestion",
      "ValidateIssuer": true,
      "ValidateAudience": true,
      "ValidateLifetime": true,
      "ValidateIssuerSigningKey": true,
      "ClockSkew": "00:05:00",
      "RequireHttpsMetadata": true
    }
  },

  "Authorization": {
    "DefaultPolicy": "RequireAuthenticatedUser",
    "TenantClaimType": "http://schemas.microsoft.com/identity/claims/tenantid",
    "RoleClaimType": "http://schemas.microsoft.com/ws/2008/06/identity/claims/role"
  }
}

  • API Key Configuration (for service-to-service)

    {
      "ApiKeys": {
        "HeaderName": "X-API-Key",
        "ValidApiKeys": [
          "@Microsoft.KeyVault(SecretUri=https://.../api-key-ingestion/)",
          "@Microsoft.KeyVault(SecretUri=https://.../api-key-integrity/)"
        ]
      }
    }
    

  • CORS Configuration

    {
      "Cors": {
        "PolicyName": "DefaultCorsPolicy",
        "AllowedOrigins": [
          "https://admin.audit.connectsoft.io",
          "https://app.audit.connectsoft.io"
        ],
        "AllowedMethods": ["GET", "POST", "PUT", "DELETE"],
        "AllowedHeaders": ["*"],
        "AllowCredentials": true,
        "MaxAge": 600
      }
    }
    

Code Examples: - Authentication configuration (complete) - Authorization policy configuration - CORS configuration - API key validation setup

Diagrams: - Authentication flow with configuration - Authorization policy architecture

Deliverables: - Auth configuration reference - Policy configuration guide - CORS setup patterns


Topic 22: Compliance & Data Protection Config

What will be covered: - PII Redaction Configuration

{
  "Compliance": {
    "EnableLoggingRedaction": true,
    "StrictInDevelopment": false,
    "Profile": "default",

    "Redaction": {
      "RedactionFormat": "******",
      "RedactionLength": 6,
      "RedactEmailDomain": false,
      "RedactPhoneNumber": true
    },

    "DataClassification": {
      "DefaultClassification": "SENSITIVE",
      "AutoClassifyPII": true,
      "PiiPatterns": {
        "Email": "^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$",
        "SSN": "^\\d{3}-\\d{2}-\\d{4}$",
        "CreditCard": "^\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}[\\s-]?\\d{4}$"
      }
    }
  }
}

  • Retention Policy Configuration
  • Default retention periods
  • Classification-based retention
  • Legal hold configuration

  • Encryption Configuration

  • Encryption key references (Key Vault)
  • Algorithm selection (AES-256-GCM)
  • Key rotation schedule

Code Examples: - Compliance options (complete) - PII detection configuration - Retention policy options - Encryption key configuration

Diagrams: - Compliance configuration architecture - PII redaction flow

Deliverables: - Compliance configuration reference - PII patterns catalog - Encryption setup guide


CYCLE 12: Configuration Providers Hierarchy (~2,500 lines)

Topic 23: Configuration Provider Precedence

What will be covered: - Provider Chain

1. appsettings.json           (Base: MaxBatchSize=1000)
2. appsettings.Production.json (Override: MaxBatchSize=5000)
3. Azure App Configuration    (Override: MaxBatchSize=7000)
4. Environment Variable       (Override: Ingestion__MaxBatchSize=8000)
5. Command-Line Argument      (Override: --Ingestion:MaxBatchSize=9000)

Final Value: 9000 (command-line wins)

  • Debugging Configuration

    // Log all configuration sources and values
    public void LogConfiguration(IConfiguration configuration)
    {
        var configRoot = (IConfigurationRoot)configuration;
    
        foreach (var provider in configRoot.Providers)
        {
            _logger.LogInformation("Provider: {ProviderType}", provider.GetType().Name);
        }
    
        // Log specific configuration value sources
        var section = configuration.GetSection("Ingestion:MaxBatchSize");
        _logger.LogInformation("MaxBatchSize = {Value}, Source = {Source}",
            section.Value,
            GetConfigurationSource(section));
    }
    

  • Configuration Snapshot

  • Capture effective configuration at startup
  • Log to Application Insights
  • Store in audit trail
  • Use for troubleshooting

Code Examples: - Provider precedence examples - Configuration debugging utility - Snapshot generation - Source tracking

Diagrams: - Provider precedence visualization - Configuration merge flow

Deliverables: - Precedence guide - Debugging utilities - Snapshot procedures


Topic 24: Configuration Reloading & Change Detection

What will be covered: - File Watch Reloading - appsettings.json: reloadOnChange: true - Automatic reload on file save - IOptionsSnapshot reflects changes

  • App Configuration Refresh
  • Sentinel key pattern
  • Polling interval (30 minutes)
  • Push notification via Event Grid (optional)
  • Middleware refresh on each request

  • Change Handlers

    services.Configure<IngestionOptions>(options =>
    {
        // Initial setup
    });
    
    // React to changes
    services.AddSingleton<IOptionsChangeTokenSource<IngestionOptions>>(provider =>
    {
        var monitor = provider.GetRequiredService<IOptionsMonitor<IngestionOptions>>();
        monitor.OnChange(newOptions =>
        {
            _logger.LogInformation("Ingestion configuration changed: MaxBatchSize = {MaxBatchSize}",
                newOptions.MaxBatchSize);
    
            // React to change (e.g., update internal caches)
        });
        return new ConfigurationChangeTokenSource<IngestionOptions>(
            optionsName: Options.DefaultName,
            config: configuration.GetSection(IngestionOptions.SectionName));
    });
    

  • Safe Reloading

  • Validate new configuration before applying
  • Graceful degradation if invalid
  • Rollback to previous values on error

Code Examples: - Reload configuration - Change detection handlers - Validation before apply - Safe reloading patterns

Diagrams: - Configuration reload flow - Change notification architecture

Deliverables: - Reload configuration guide - Change handler patterns - Safe reload procedures


CYCLE 13: Testing Configuration & Overrides (~2,500 lines)

Topic 25: Test Configuration Strategies

What will be covered: - Test-Specific Configuration Files - appsettings.UnitTests.json - appsettings.IntegrationTests.json - appsettings.AcceptanceTests.json

  • In-Memory Configuration

    [TestClass]
    public class IngestionServiceTests
    {
        private IConfiguration CreateTestConfiguration()
        {
            var configData = new Dictionary<string, string>
            {
                ["Ingestion:MaxBatchSize"] = "100",
                ["Ingestion:EnableClassification"] = "false",
                ["ConnectionStrings:SqlServer"] = "Server=(localdb)\\test;Database=AuditTest;"
            };
    
            return new ConfigurationBuilder()
                .AddInMemoryCollection(configData)
                .Build();
        }
    
        [TestMethod]
        public void Service_Should_UseBatchSize_From_Configuration()
        {
            // Arrange
            var config = CreateTestConfiguration();
            var options = config.GetSection("Ingestion").Get<IngestionOptions>();
            var service = new IngestionService(Options.Create(options));
    
            // Act & Assert
            Assert.AreEqual(100, service.MaxBatchSize);
        }
    }
    

  • Configuration Mocking

  • Mock IConfiguration
  • Mock IOptions
  • Override specific values for test scenarios

  • Test Environment Variables

    [TestInitialize]
    public void Setup()
    {
        Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Test");
        Environment.SetEnvironmentVariable("Ingestion__MaxBatchSize", "50");
    }
    
    [TestCleanup]
    public void Cleanup()
    {
        Environment.SetEnvironmentVariable("Ingestion__MaxBatchSize", null);
    }
    

Code Examples: - Test configuration files - In-memory configuration builder - Configuration mocking patterns - Environment variable overrides in tests

Diagrams: - Test configuration hierarchy - Mock configuration flow

Deliverables: - Test configuration guide - Mock patterns - Override strategies


Topic 26: CI/CD Configuration Injection

What will be covered: - Azure Pipeline Variable Groups

variables:
- group: atp-dev-config
- group: atp-shared-secrets  # From Key Vault

- name: Ingestion__MaxBatchSize
  value: $(IngestionMaxBatchSize)  # From variable group

steps:
- task: DotNetCoreCLI@2
  inputs:
    command: run
  env:
    Ingestion__MaxBatchSize: $(Ingestion__MaxBatchSize)
    ConnectionStrings__SqlServer: $(SqlConnectionString)  # From Key Vault variable group

  • Kubernetes ConfigMaps

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: atp-ingestion-config
    data:
      appsettings.Production.json: |
        {
          "Ingestion": {
            "MaxBatchSize": 5000
          }
        }
    
    # Mount as file
    volumeMounts:
    - name: config
      mountPath: /app/config
      readOnly: true
    
    volumes:
    - name: config
      configMap:
        name: atp-ingestion-config
    

  • Secrets in Kubernetes

  • Azure Key Vault CSI Driver
  • External Secrets Operator
  • Native Kubernetes Secrets (encrypted at rest)

Code Examples: - Pipeline variable group configuration - Kubernetes ConfigMap manifests - Secret injection patterns (CSI driver) - Environment variable injection

Diagrams: - CI/CD configuration injection flow - Kubernetes configuration architecture

Deliverables: - CI/CD configuration guide - Kubernetes configuration patterns - Secret injection setup


CYCLE 14: Best Practices & Troubleshooting (~3,000 lines)

Topic 27: Configuration Best Practices

What will be covered: - Configuration Best Practices - ✅ Use Options pattern (not IConfiguration directly) - ✅ Validate at startup (ValidateOnStart) - ✅ Never store secrets in appsettings (use Key Vault) - ✅ Use Managed Identity (no connection string passwords in production) - ✅ Environment-specific files (appsettings.{Environment}.json) - ✅ Hierarchical sections (group related settings) - ✅ Comments in appsettings.json (explain non-obvious values) - ✅ Type-safe options classes (strongly typed, not magic strings) - ✅ Required fields marked ([Required] attribute) - ✅ Ranges validated ([Range] attribute) - ✅ Defaults in code (not just appsettings.json) - ✅ Fail-fast (application won't start if config invalid)

  • Anti-Patterns to Avoid
  • Magic strings (configuration["Ingestion:MaxBatchSize"])
  • Secrets in appsettings.json (commit to Git)
  • No validation (runtime errors instead of startup failures)
  • Global state (static configuration singletons)
  • Runtime configuration mutation (configuration should be immutable)
  • Missing environment files (no dev/prod separation)
  • Hardcoded values (bypass configuration system)
  • IConfiguration everywhere (use Options pattern)

  • Code Review Checklist

  • New settings added to options class (not accessed via IConfiguration)
  • Options class has validation attributes ([Required], [Range], etc.)
  • Options registered with ValidateOnStart
  • No secrets in appsettings.json (Key Vault references used)
  • Environment-specific overrides in appsettings.{Env}.json
  • Default values documented in code comments
  • Configuration changes documented in changelog

Code Examples: - Good configuration examples (Options pattern) - Bad configuration examples (magic strings, hardcoded) - Code review checklist automation

Diagrams: - Best practices vs. anti-patterns comparison - Configuration architecture (ideal)

Deliverables: - Best practices handbook - Anti-pattern catalog - Code review checklist


Topic 28: Troubleshooting Configuration Issues

What will be covered: - Common Configuration Problems - Problem: OptionsValidationException at startup - Cause: Required field missing or invalid value - Solution: Check appsettings.json, verify all required fields - Debug: Enable verbose logging, check exact error message

  • Problem: Configuration value not updating

    • Cause: Using IOptions instead of IOptionsSnapshot
    • Solution: Use IOptionsSnapshot for reload support
    • Debug: Check refresh interval, verify sentinel key changed
  • Problem: Key Vault secret not resolved

    • Cause: Managed Identity doesn't have access to Key Vault
    • Solution: Grant "Key Vault Secrets User" role to Managed Identity
    • Debug: Check Azure RBAC assignments, verify Key Vault diagnostic logs
  • Problem: Environment-specific file not loaded

    • Cause: ASPNETCORE_ENVIRONMENT not set correctly
    • Solution: Set environment variable before application start
    • Debug: Log environment name at startup
  • Configuration Debugging

    public void LogConfigurationSources(IConfiguration configuration)
    {
        if (configuration is IConfigurationRoot root)
        {
            _logger.LogInformation("Configuration Providers:");
            foreach (var provider in root.Providers)
            {
                _logger.LogInformation("  - {ProviderType}", provider.GetType().Name);
            }
        }
    
        // Log effective values
        var ingestionConfig = configuration.GetSection("Ingestion");
        _logger.LogInformation("Ingestion Configuration:");
        foreach (var kvp in ingestionConfig.AsEnumerable())
        {
            _logger.LogInformation("  {Key} = {Value}", kvp.Key, kvp.Value);
        }
    }
    

  • Validation Troubleshooting

  • Read OptionsValidationException message
  • Check which property failed validation
  • Verify appsettings.json syntax (JSON valid?)
  • Verify data types match (string vs. int)

  • Connection String Troubleshooting

  • Test connection string manually (SQL Server Management Studio)
  • Verify Managed Identity has access
  • Check network connectivity (private endpoints, firewall rules)
  • Review diagnostic logs (Azure SQL, Service Bus)

Code Examples: - Configuration debugging utility (complete) - Validation error parsing - Connection string testing - Troubleshooting scripts

Diagrams: - Troubleshooting decision tree - Configuration debugging flow

Deliverables: - Troubleshooting guide - Common problems catalog - Debugging utilities


Summary of Deliverables

Across all 14 cycles, this documentation will provide:

  1. Architecture & Philosophy
  2. Configuration architecture overview
  3. Options pattern fundamentals
  4. Configuration providers and precedence

  5. Options Pattern

  6. IOptions, IOptionsSnapshot, IOptionsMonitor comparison
  7. Options class definitions (all ATP options)
  8. Validation with data annotations and custom validators
  9. Registration patterns and DI integration

  10. appsettings.json

  11. Base configuration structure
  12. All ATP configuration sections reference
  13. Section organization and naming conventions
  14. Comments and documentation

  15. Environment-Specific Configuration

  16. appsettings.{Environment}.json files (all environments)
  17. Override patterns and precedence rules
  18. Environment variable syntax
  19. Command-line argument overrides

  20. Azure App Configuration

  21. Integration setup and connection methods
  22. Key organization standards
  23. Labels for environment separation
  24. Dynamic refresh configuration
  25. Versioning and history management

  26. Azure Key Vault

  27. Secret reference syntax (@Microsoft.KeyVault)
  28. Secret organization and naming
  29. Managed Identity authentication
  30. Secret rotation and dual-secret pattern
  31. Access control (RBAC)

  32. Feature Flags

  33. Feature flag definition and usage
  34. Microsoft.FeatureManagement integration
  35. Feature filters (percentage, time window, targeting)
  36. Azure App Configuration feature flags
  37. Per-tenant/edition targeting

  38. Infrastructure Configuration

  39. Connection strings (all data stores)
  40. Database configuration (NHibernate, MongoDB)
  41. Messaging configuration (MassTransit, Service Bus)
  42. Observability (Application Insights, OpenTelemetry)

  43. Security & Compliance

  44. Authentication and authorization configuration
  45. CORS policies
  46. PII redaction and data classification
  47. Retention policies and encryption settings

  48. Configuration Providers

    • Provider hierarchy and precedence
    • Configuration debugging and logging
    • Configuration snapshot generation
    • Dynamic reloading and change detection
  49. Testing Configuration

    • Test-specific configuration files
    • In-memory configuration for unit tests
    • Configuration mocking patterns
    • CI/CD configuration injection (pipelines, Kubernetes)
  50. Best Practices & Troubleshooting

    • Configuration best practices checklist
    • Anti-patterns to avoid
    • Common problems and solutions
    • Debugging utilities and procedures

Next Steps

  1. Review & Approval: Validate cycle plan with platform and development teams
  2. Cycle 1 Generation: Begin content generation for configuration architecture
  3. Options Classes: Define all ATP options classes with validation
  4. appsettings Templates: Create appsettings.json templates for all services
  5. Key Vault Setup: Organize secrets in Key Vault with naming conventions
  6. App Configuration: Setup Azure App Configuration with key organization


This documentation plan covers the complete configuration management for ATP, from Options pattern and appsettings.json to Azure App Configuration, Key Vault integration, feature flags, and environment-specific overrides, ensuring strongly-typed, validated, secure, and dynamic configuration across all environments.