appsettings.json and can be overridden via environment variables.
Configuration Sources
Configuration is loaded in this order (later sources override earlier ones):appsettings.json(base settings)appsettings.{Environment}.json(environment-specific)- User secrets (Development only)
- Environment variables
- Command-line arguments
In production, use environment variables or Azure Key Vault for sensitive settings like
JwtOptions__SigningKey and connection strings.Required Configuration (Production)
The API validates these settings on startup whenASPNETCORE_ENVIRONMENT=Production:
src/Playground/Playground.Api/Program.cs
Database Options
Configures Entity Framework Core and database provider.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Provider | string | POSTGRESQL | Database provider: POSTGRESQL or SQLSERVER |
ConnectionString | string | required | Full database connection string |
MigrationsAssembly | string | required | Assembly containing EF Core migrations |
Environment Variable Override
JWT Options
Configures JSON Web Token authentication for API access.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Issuer | string | fsh.local | Token issuer claim (iss) |
Audience | string | fsh.clients | Token audience claim (aud) |
SigningKey | string | required | Symmetric signing key (min 32 characters, 256 bits) |
AccessTokenMinutes | int | 2 | Access token lifetime in minutes |
RefreshTokenDays | int | 7 | Refresh token lifetime in days |
Environment Variable Override
Caching Options
Configures distributed caching with Redis.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Redis | string | "" (empty) | Redis connection string. If empty, uses in-memory cache |
Behavior
- Empty string: Uses
IMemoryCache(in-process caching) - Connection string: Uses
IDistributedCachewith StackExchange.Redis
Environment Variable Override
Distributed caching is required for:
- Multi-instance deployments (horizontal scaling)
- Shared session state
- Rate limiting across instances
OpenTelemetry Options
Configures observability with OpenTelemetry (traces, metrics, logs).appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Enabled | bool | true | Master switch for OpenTelemetry |
Tracing.Enabled | bool | true | Enable distributed tracing |
Metrics.Enabled | bool | true | Enable metrics collection |
Metrics.MeterNames | string[] | [...] | Module-specific meters to collect |
Exporter.Otlp.Enabled | bool | true | Enable OTLP export |
Exporter.Otlp.Endpoint | string | http://localhost:4317 | OTLP gRPC endpoint |
Exporter.Otlp.Protocol | string | grpc | Protocol: grpc or http/protobuf |
Jobs.Enabled | bool | true | Trace Hangfire jobs |
Mediator.Enabled | bool | true | Trace Mediator commands/queries |
Http.Histograms.Enabled | bool | true | Collect request duration histograms |
Data.FilterEfStatements | bool | true | Filter verbose EF Core SQL logs |
Data.FilterRedisCommands | bool | true | Filter verbose Redis command logs |
Supported OTLP Endpoints
CORS Options
Configures Cross-Origin Resource Sharing for API access.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
AllowAll | bool | false | Allow all origins (dangerous, dev only) |
AllowedOrigins | string[] | [...] | Whitelist of allowed origins |
AllowedHeaders | string[] | [...] | Allowed request headers |
AllowedMethods | string[] | [...] | Allowed HTTP methods |
Environment Variable Override
OpenAPI Options
Configures Swagger/OpenAPI documentation.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Enabled | bool | true | Enable OpenAPI generation |
Title | string | FSH PlayGround API | API title in Swagger UI |
Version | string | v1 | API version |
Description | string | ... | API description |
Contact.* | object | {...} | Contact information |
License.* | object | {...} | License information |
https://localhost:5285/scalar
Hangfire Options
Configures the Hangfire dashboard for background jobs.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Username | string | admin | Dashboard login username |
Password | string | Secure1234!Me | Dashboard login password |
Route | string | /jobs | Dashboard URL path |
https://localhost:5285/jobs
Rate Limiting Options
Configures rate limiting for API endpoints.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Enabled | bool | false | Master switch for rate limiting |
Global.PermitLimit | int | 100 | Max requests per window (global) |
Global.WindowSeconds | int | 60 | Time window in seconds |
Global.QueueLimit | int | 0 | Queue size when limit exceeded |
Auth.PermitLimit | int | 10 | Max auth requests per window |
Auth.WindowSeconds | int | 60 | Auth window in seconds |
The
Auth policy applies specifically to authentication endpoints (/api/v1/identity/tokens) to prevent brute force attacks.Mail Options
Configures email sending via SMTP or SendGrid.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
UseSendGrid | bool | false | Use SendGrid instead of SMTP |
From | string | required | Sender email address |
DisplayName | string | required | Sender display name |
SMTP.Host | string | required | SMTP server hostname |
SMTP.Port | int | 587 | SMTP port (typically 587 for TLS) |
SMTP.UserName | string | required | SMTP username |
SMTP.Password | string | required | SMTP password |
SendGrid.ApiKey | string | required | SendGrid API key |
Test Email Setup (Ethereal)
The default configuration uses Ethereal Email for testing:- All emails are captured (not sent to real recipients)
- View emails at https://ethereal.email/messages
Password Policy
Configures password expiration and history tracking.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
PasswordHistoryCount | int | 5 | Prevent reusing last N passwords |
PasswordExpiryDays | int | 90 | Force password change after N days |
PasswordExpiryWarningDays | int | 14 | Warn user N days before expiry |
EnforcePasswordExpiry | bool | true | Enable/disable password expiration |
Multitenancy Options
Configures multi-tenant behavior.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
RunTenantMigrationsOnStartup | bool | true | Auto-apply migrations to all tenant databases on startup |
Storage Options
Configures file storage provider.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Provider | string | local | Storage provider: local, s3, or azure |
Local Storage
Files stored inwwwroot/uploads/ directory.
AWS S3
Azure Blob Storage
Security Headers Options
Configures Content Security Policy (CSP) and security headers.appsettings.json
| Property | Type | Default | Description |
|---|---|---|---|
Enabled | bool | true | Enable security headers |
ExcludedPaths | string[] | ["/scalar", "/openapi"] | Paths exempt from CSP |
AllowInlineStyles | bool | true | Allow inline <style> tags |
ScriptSources | string[] | [] | Additional allowed script sources |
StyleSources | string[] | [] | Additional allowed style sources |
Serilog Configuration
The starter kit uses Serilog for structured logging:appsettings.json
- Written to console with
Informationlevel - Exported to OpenTelemetry endpoint
- Enriched with machine name, thread ID, correlation ID, process ID
Environment-Specific Configuration
Override settings per environment:Configuration Validation
The API validates configuration on startup using Data Annotations:Example: JwtOptions
OptionsValidationException on startup.
Next Steps
Project Structure
Understand the codebase organization
Database
Learn about EF Core setup
Security
Configure JWT authentication
Deployment
Deploy to production
