Configuration Reference
Introduction
This document provides a complete reference for all configuration settings used by the Ravenxcope backend. Configuration is managed through the standard ASP.NET Core configuration system using appsettings.json files, with environment variable overrides for container deployments.
Configuration Files
| File | Purpose | Gitignored |
|---|---|---|
appsettings.json | Production configuration template | No |
appsettings.Development.json | Development environment overrides | Yes |
Placeholder Pattern
Production appsettings.json uses double-curly-brace placeholders for values that must be provided at runtime:
"Host": "{{PostgresqlSettings__Host}}"
The configuration validation at startup detects these placeholders and treats them as missing values, causing startup failure if they are not overridden by environment variables.
Configuration Sections
PostgresqlSettings
{
"PostgresqlSettings": {
"Host": "{{PostgresqlSettings__Host}}",
"Port": "{{PostgresqlSettings__Port}}",
"Username": "{{PostgresqlSettings__Username}}",
"Password": "{{PostgresqlSettings__Password}}",
"Database": "{{PostgresqlSettings__Database}}",
"MaxPoolSize": "100"
}
}
| Key | Type | Default | Required | Validated |
|---|---|---|---|---|
Host | string | localhost | Yes | Not empty |
Port | string | 5432 | Yes | Positive integer |
Username | string | hduser | Yes | Not empty |
Password | string | — | Yes | Not empty |
Database | string | me | Yes | Not empty |
MaxPoolSize | string | 20 | No | — |
Connection string format:
Host={Host};Port={Port};Username={Username};Password={Password};Database={Database};Maximum Pool Size={MaxPoolSize}
RedisSettings
{
"RedisSettings": {
"Host": "{{RedisSettings__Host}}",
"Port": "{{RedisSettings__Port}}",
"Password": "{{RedisSettings__Password}}",
"DefaultDatabase": "{{RedisSettings__DefaultDatabase}}"
}
}
| Key | Type | Default | Required | Validated |
|---|---|---|---|---|
Host | string | localhost | Yes | Not empty |
Port | string | 6379 | Yes | Positive integer |
Password | string | null | No | — |
DefaultDatabase | string | 0 | No | — |
Connection string format:
- With password:
{Host}:{Port},password={Password},defaultDatabase={DefaultDatabase} - Without password:
{Host}:{Port},defaultDatabase={DefaultDatabase}
JwtSettings
{
"JwtSettings": {
"Secret": "{{JwtSettings__Secret}}",
"Issuer": "{{JwtSettings__Issuer}}",
"Audience": "{{JwtSettings__Audience}}",
"ExpiryMinutes": 1440
}
}
| Key | Type | Default | Required | Notes |
|---|---|---|---|---|
Secret | string | — | Yes | Min 32 chars recommended |
Issuer | string | Ravenxcope.Backend | No | JWT issuer claim |
Audience | string | RavenxcopeUsers | No | JWT audience claim |
ExpiryMinutes | int | 1440 | No | Token lifetime (24h) |
Security Warning: If
Secretis shorter than 32 characters, a startup warning is emitted. The JwtService will throw anInvalidOperationExceptionif the secret is empty or less than 32 characters.
InfluxDb
{
"InfluxDb": {
"Url": "{{InfluxDb__Url}}",
"Token": "{{InfluxDb__Token}}",
"Org": "{{InfluxDb__Org}}",
"Bucket": "{{InfluxDb__Bucket}}",
"Precision": "ms",
"TimeoutSeconds": 30
}
}
| Key | Type | Default | Required |
|---|---|---|---|
Url | string | — | Yes |
Token | string | — | Yes |
Org | string | — | Yes |
Bucket | string | — | Yes |
Precision | string | ms | No |
TimeoutSeconds | int | 30 | No |
OpenSearch
{
"OpenSearch": {
"Url": "{{OpenSearch__Url}}",
"Username": "{{OpenSearch__Username}}",
"Password": "{{OpenSearch__Password}}",
"IndexName": "{{OpenSearch__IndexName}}"
}
}
| Key | Type | Default | Required |
|---|---|---|---|
Url | string | https://localhost:9200 | Yes |
Username | string | admin | Yes |
Password | string | — | Yes |
IndexName | string | mataelang-sensor-events-stream | Yes |
AnalyticsChatEnrichment
{
"AnalyticsChatEnrichment": {
"Enabled": true,
"MispEnabled": "{{AnalyticsChatEnrichment__MispEnabled}}",
"MispBaseUrl": "{{AnalyticsChatEnrichment__MispBaseUrl}}",
"MispApiKey": "{{AnalyticsChatEnrichment__MispApiKey}}",
"MispVerifySsl": "{{AnalyticsChatEnrichment__MispVerifySsl}}",
"HistoricalEnabled": "{{AnalyticsChatEnrichment__HistoricalEnabled}}",
"PlaybooksEnabled": "{{AnalyticsChatEnrichment__PlaybooksEnabled}}",
"MaxIocsPerRequest": "{{AnalyticsChatEnrichment__MaxIocsPerRequest}}",
"MaxMispMatchesPerIoc": "{{AnalyticsChatEnrichment__MaxMispMatchesPerIoc}}",
"HistoricalLookbackDays": "{{AnalyticsChatEnrichment__HistoricalLookbackDays}}",
"ProviderTimeoutSeconds": "{{AnalyticsChatEnrichment__ProviderTimeoutSeconds}}",
"PlaybookPath": "Knowledge/analytics-chat-playbooks.json"
}
}
This section configures the free enrichment v1 layer used by analytics chat. The current implementation uses direct REST calls to a self-hosted MISP instance.
| Key | Type | Default | Required | Notes |
|---|---|---|---|---|
Enabled | bool | true | No | Global switch for all analytics chat enrichment |
MispEnabled | bool | false | No | Enables direct MISP REST lookups when base URL and API key are also set |
MispBaseUrl | string | "" | MISP only | Must be an absolute URL for the provider to become available |
MispApiKey | string | "" | MISP only | Read-only API key recommended |
MispVerifySsl | bool | true | No | Set to false only for trusted environments with self-signed certs |
HistoricalEnabled | bool | true | No | Enables OpenSearch recurrence lookups for IOC and pattern history |
PlaybooksEnabled | bool | true | No | Enables local playbook matching |
MaxIocsPerRequest | int | 5 | No | Caps the number of extracted IOC candidates queried per chat turn |
MaxMispMatchesPerIoc | int | 3 | No | Caps the number of normalized MISP matches kept per IOC |
HistoricalLookbackDays | int | 7 | No | Lookback window used by historical recurrence queries |
ProviderTimeoutSeconds | int | 5 | No | Per-provider timeout for MISP and other enrichment lookups |
PlaybookPath | string | Knowledge/analytics-chat-playbooks.json | No | Relative paths are resolved from AppContext.BaseDirectory |
MISP threat intel is considered available only when:
AnalyticsChatEnrichment:EnabledistrueAnalyticsChatEnrichment:MispEnabledistrueAnalyticsChatEnrichment:MispBaseUrlis a valid absolute URLAnalyticsChatEnrichment:MispApiKeyis non-empty
If these conditions are not met, analytics chat can still run with historical enrichment, playbooks, or analytics-only evidence.
Integration and Runtime Keys
{
"NatsMessaging": {
"Enabled": "{{NatsMessaging__Enabled}}",
"Url": "{{NatsMessaging__Url}}",
"CredsFile": "{{NatsMessaging__CredsFile}}",
"CommandStream": "{{NatsMessaging__CommandStream}}"
},
"SensorApiSettings": { "ApiKey": "{{SensorApiSettings__ApiKey}}" },
"SensorSettings": {
"HeartbeatTimeoutMinutes": "{{SensorSettings__HeartbeatTimeoutMinutes}}",
"ProvisioningSudoPassword": "{{SensorSettings__ProvisioningSudoPassword}}"
},
"OpenSearchAnalytics": {
"DefaultTimeoutSeconds": "{{OpenSearchAnalytics__DefaultTimeoutSeconds}}",
"DashboardTimeoutSeconds": "{{OpenSearchAnalytics__DashboardTimeoutSeconds}}",
"AggregationTimeoutSeconds": "{{OpenSearchAnalytics__AggregationTimeoutSeconds}}",
"ListQueryTimeoutSeconds": "{{OpenSearchAnalytics__ListQueryTimeoutSeconds}}"
},
"AnalyticsCacheWarming": {
"Enabled": "{{AnalyticsCacheWarming__Enabled}}",
"IntervalMinutes": "{{AnalyticsCacheWarming__IntervalMinutes}}",
"InitialDelaySeconds": "{{AnalyticsCacheWarming__InitialDelaySeconds}}"
},
"DockerRegistry": {
"Registry": "{{DockerRegistry__Registry}}",
"Username": "{{DockerRegistry__Username}}",
"Password": "{{DockerRegistry__Password}}"
},
"DataCollector": {
"Endpoint": "{{DataCollector__Endpoint}}",
"Port": "{{DataCollector__Port}}"
},
"BackendUrl": "{{BackendUrl}}"
}
| Key | Type | Default | Required | Validated |
|---|---|---|---|---|
NatsMessaging:Enabled | bool | false | No | — |
NatsMessaging:Url | string | — | When enabled | Not empty |
NatsMessaging:CredsFile | string | — | When enabled | Not empty |
NatsMessaging:CommandStream | string | RXC_CMD | No | — |
SensorApiSettings:ApiKey | string | — | Yes | Not placeholder |
SensorSettings:HeartbeatTimeoutMinutes | int | 1 | No | — |
SensorSettings:ProvisioningSudoPassword | string | — | Yes | Not empty |
OpenSearchAnalytics:DefaultTimeoutSeconds | int | 20 | No | Positive integer (recommended) |
OpenSearchAnalytics:DashboardTimeoutSeconds | int | 30 | No | Positive integer (recommended) |
OpenSearchAnalytics:AggregationTimeoutSeconds | int | 15 | No | Positive integer (recommended) |
OpenSearchAnalytics:ListQueryTimeoutSeconds | int | 25 | No | Positive integer (recommended) |
AnalyticsCacheWarming:Enabled | bool | true | No | — |
AnalyticsCacheWarming:IntervalMinutes | int | 5 | No | Positive integer (recommended) |
AnalyticsCacheWarming:InitialDelaySeconds | int | 20 | No | Non-negative integer (recommended) |
DockerRegistry:Registry | string | — | No | — |
DockerRegistry:Username | string | — | No | — |
DockerRegistry:Password | string | — | No | — |
DataCollector:Endpoint | string | — | Yes | Not empty |
DataCollector:Port | string | — | Yes | Positive integer |
BackendUrl | string | — | Yes | Not empty |
Database Migration Controls
{
"Database": {
"AutoMigrate": true,
"MigrationMaxRetries": 10,
"MigrationRetryDelaySeconds": 5
}
}
| Key | Type | Default | Description |
|---|---|---|---|
AutoMigrate | bool | true | Run EF Core migrations on startup |
MigrationMaxRetries | int | 10 | Max retry attempts for migration |
MigrationRetryDelaySeconds | int | 5 | Delay between retry attempts (seconds) |
Logging (Serilog)
{
"Serilog": {
"Using": ["Serilog.Sinks.Console"],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"Microsoft.AspNetCore": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"Enrich": ["FromLogContext", "WithMachineName"],
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {SourceContext} {Message:lj}{NewLine}{Exception}"
}
}
]
}
}
Environment Variable Mapping
For container deployment, use the ASP.NET Core double-underscore convention to override appsettings values:
| appsettings key | Environment variable |
|---|---|
JwtSettings:Secret | JwtSettings__Secret |
PostgresqlSettings:Host | PostgresqlSettings__Host |
PostgresqlSettings:Port | PostgresqlSettings__Port |
RedisSettings:Host | RedisSettings__Host |
OpenSearch:Url | OpenSearch__Url |
InfluxDb:Url | InfluxDb__Url |
AnalyticsChatEnrichment:Enabled | AnalyticsChatEnrichment__Enabled |
AnalyticsChatEnrichment:MispEnabled | AnalyticsChatEnrichment__MispEnabled |
AnalyticsChatEnrichment:MispBaseUrl | AnalyticsChatEnrichment__MispBaseUrl |
AnalyticsChatEnrichment:MispApiKey | AnalyticsChatEnrichment__MispApiKey |
AnalyticsChatEnrichment:MispVerifySsl | AnalyticsChatEnrichment__MispVerifySsl |
AnalyticsChatEnrichment:HistoricalEnabled | AnalyticsChatEnrichment__HistoricalEnabled |
AnalyticsChatEnrichment:PlaybooksEnabled | AnalyticsChatEnrichment__PlaybooksEnabled |
AnalyticsChatEnrichment:MaxIocsPerRequest | AnalyticsChatEnrichment__MaxIocsPerRequest |
AnalyticsChatEnrichment:MaxMispMatchesPerIoc | AnalyticsChatEnrichment__MaxMispMatchesPerIoc |
AnalyticsChatEnrichment:HistoricalLookbackDays | AnalyticsChatEnrichment__HistoricalLookbackDays |
AnalyticsChatEnrichment:ProviderTimeoutSeconds | AnalyticsChatEnrichment__ProviderTimeoutSeconds |
AnalyticsChatEnrichment:PlaybookPath | AnalyticsChatEnrichment__PlaybookPath |
BackendUrl | BackendUrl |
DataCollector:Endpoint | DataCollector__Endpoint |
Typed Options Class Summary
All options classes are defined in Extensions/BackendConfiguration.cs:
| Class | Config Section | Notes |
|---|---|---|
PostgresqlSettingsOptions | PostgresqlSettings | Includes MaxPoolSize |
RedisSettingsOptions | RedisSettings | Password is nullable |
JwtSettingsOptions | JwtSettings | Includes ExpiryMinutes |
InfluxDbOptions | InfluxDb | All required fields |
OpenSearchOptions | OpenSearch | Has sensible defaults |
AnalyticsChatEnrichmentOptions | AnalyticsChatEnrichment | Controls MISP, history, playbooks, and provider limits |
NatsMessagingOptions | NatsMessaging | Enabled, Url, CredsFile, CommandStream |
NatsProvisionerOptions | NatsProvisioner | Provisioner URL + shared secret |
SensorApiSettingsOptions | SensorApiSettings | ApiKey only |
DataCollectorOptions | DataCollector | Endpoint and Port |
DockerRegistryOptions | DockerRegistry | Registry, Username, Password |
SensorSettingsOptions | SensorSettings | HeartbeatTimeoutMinutes, ProvisioningSudoPassword |
OpenSearchAnalyticsOptions | OpenSearchAnalytics | Query-type timeout controls |
AnalyticsCacheWarmingOptions | AnalyticsCacheWarming | Cache warming schedule controls |
DatabaseOptions | Database | Migration controls |
BackendAppOptions | (composite) | Url from BackendUrl key |
SensorRuntimeOptions | (composite) | Aggregates multiple sections |
Preflight Validation
Use defense_center/scripts/preflight-env.sh to detect missing or weak configuration values before Docker Compose startup:
sh defense_center/scripts/preflight-env.sh defense_center/.env
This script checks for:
- Missing required environment variables
- Placeholder values that weren't replaced
- Weak JWT secrets