Configuration Reference

Complete reference for appsettings.json settings in the Riptide Application Manager. Environment variables can override any setting — see Deployment Guide for environment-specific configuration.

Distinct from the API Reference, which documents the REST surface AM exposes to client applications. This document covers the configuration surface AM consumes at startup.

Which file, and in which process

Application Manager runs as two processes, and each reads its own configuration the standard .NET way — appsettings.json and appsettings.{Environment}.json from its own project, then environment variables:

Process Settings file
API Riptide.ApplicationManager.Api/appsettings.json
Web UI Riptide.ApplicationManager.Web/appsettings.json

There is no single unified settings file. An earlier arrangement kept one at the repository root and loaded it with custom code in both Program.cs files; that is being withdrawn. It loaded from the binary directory rather than the content root, which put it above appsettings.{Environment}.json and silently disabled the environment overlay — a Development run produced no debug logging at all, because the base file's Logging:LogLevel:Default won.

Settings each process must agree on — the platform key, the database stores — are therefore written in both files, deliberately and identically. Anything genuinely per-deployment comes from environment variables, which outrank every settings file.

Ports and Hosting

Ports come from the standard top-level Kestrel section, in each project's own file. There is no Api:Kestrel or Web:Kestrel: Kestrel binds Kestrel:* and nothing else, so a prefixed variant is well-formed, plausible, and read by nobody. Earlier revisions of this document described exactly that, which is why the keys existed.

In the container neither file supplies the port — docker-entrypoint.sh sets ASPNETCORE_URLS per process from API_PORT and WEB_PORT.

Web UI

{
  "Kestrel": {
    "Endpoints": {
      "Http": { "Url": "http://*:11401" }
    }
  },
  "Web": {
    "ApiBaseUrl": "http://localhost:11402",
    "BaseUrl": "http://localhost:11401",
    "Timeout": 30
  }
}
Setting Default Description
Kestrel:Endpoints:Http:Url http://*:11401 Web UI listen address (Web project's file)
Web:ApiBaseUrl http://localhost:11402 Internal URL the Web UI uses to call the API. Required — ApiClient throws if absent rather than defaulting
Web:BaseUrl http://localhost:11401 Browser-facing address the Web UI advertises
Web:Timeout 30 HTTP client timeout in seconds

Authentication of Web UI → API calls uses Riptide:PlatformKey, one value shared by both processes. Web:ApiKey and Api:ApiKey were the previous spellings and are read by nothing.

REST API

{
  "Kestrel": {
    "Endpoints": {
      "Http": { "Url": "http://*:11402" }
    }
  },
  "Riptide": {
    "PlatformKey": ""
  },
  "Api": {
    "Cors": {
      "AllowedOrigins": ["http://localhost:11401"]
    },
    "MaxRequestBodySize": 10485760,
    "RequestTimeout": 30
  }
}
Setting Default Description
Kestrel:Endpoints:Http:Url http://*:11402 API listen address (API project's file)
Api:Cors:AllowedOrigins ["http://localhost:11401"] Allowed CORS origins
Riptide:PlatformKey (none) The platform key this API validates. Callers present it as X-Riptide-Key; the Web tier presents the same value. Replaces Api:ApiKey, which is read by nothing
Api:MaxRequestBodySize 10485760 (10 MB) Maximum request body size
Api:RequestTimeout 30 Request timeout in seconds

Databases

{
  "Database": {
    "Identity": {
      "Provider": "Sqlite",
      "ConnectionString": "Data Source=data/identity/identity.db",
      "MigrationsAssembly": "Riptide.ApplicationManager.Infrastructure"
    },
    "Configuration": {
      "Provider": "Sqlite",
      "ConnectionString": "Data Source=data/configuration/configuration.db",
      "MigrationsAssembly": "Riptide.ApplicationManager.Infrastructure"
    }
  }
}

Application Manager uses two separate databases:

Database Purpose
Identity Trial users, sessions, roles, capabilities, identity providers
Configuration Admin users, managed applications, file tree, versions, audit logs

The Provider field selects the relational engine per database and accepts Sqlite (default), Postgres / PostgreSql, or SqlServer (aliases such as npgsql, mssql are also accepted). An unrecognized value fails fast at startup. SQLite stores single-file databases under data/; for PostgreSQL or SQL Server, set ConnectionString to the appropriate engine connection string. Migrations for the non-SQLite providers are handled separately — see persistence-provider-switching-plan.md.

{
  "Database": {
    "Identity": {
      "Provider": "Postgres",
      "ConnectionString": "Host=db;Database=identity;Username=am;Password=..."
    }
  }
}

Secrets via Azure Key Vault

Application Manager can source secrets from Azure Key Vault, layered on top of appsettings.json and environment variables (the vault wins for keys it provides). This is opt-in:

{
  "Azure": {
    "KeyVault": {
      "Enabled": true,
      "VaultUri": "https://my-vault.vault.azure.net/"
    }
  }
}
Key Description
Azure:KeyVault:Enabled true to enable Key Vault secret sourcing (default false).
Azure:KeyVault:VaultUri The vault URI. Required when enabled; a missing/invalid URI is surfaced as a startup skip reason.

Authentication uses DefaultAzureCredential: a managed identity when AM runs on Azure, or a service principal via AZURE_TENANT_ID / AZURE_CLIENT_ID / AZURE_CLIENT_SECRET on a self-hosted host. The principal needs the Key Vault Secrets User role (or a get/list secrets access policy). See azure-key-vault-secrets.md.

Web UI Settings

{
  "Web": {
    "Ui": {
      "ApplicationName": "Riptide Application Manager",
      "PageSize": 20,
      "Theme": "light",
      "EnableDebugInfo": false
    },
    "Session": {
      "TimeoutMinutes": 60,
      "SlidingExpiration": true
    },
    "Features": {
      "EnableTrialManagement": true,
      "EnableConfigurationManagement": true,
      "EnableFileVersioning": true,
      "EnableAuditLog": true
    }
  }
}
Setting Default Description
Web:Ui:ApplicationName Riptide Application Manager Display name in the UI header
Web:Ui:PageSize 20 Default page size for list views
Web:Ui:Theme light UI theme
Web:Ui:EnableDebugInfo false Show debug information in the UI
Web:Session:TimeoutMinutes 60 Session inactivity timeout
Web:Session:SlidingExpiration true Reset timeout on activity
Web:Features:Enable* true Feature flags to enable/disable major sections

Trial Settings

{
  "Trial": {
    "DefaultDurationDays": 7,
    "GracePeriodDays": 30,
    "MaxTeamMembers": 5,
    "AutoActivate": true
  }
}
Setting Default Description
Trial:DefaultDurationDays 7 Default trial period length
Trial:GracePeriodDays 30 Grace period after trial expiration
Trial:MaxTeamMembers 5 Maximum team members per trial
Trial:AutoActivate true Automatically activate trials after email verification

Email

{
  "EmailProvider": "AwsSes",
  "Email": {
    "Enabled": true,
    "FromAddress": "noreply@riptide.solutions",
    "FromName": "Riptide Application Manager"
  }
}

Set EmailProvider to either Smtp or AwsSes.

SMTP

{
  "Smtp": {
    "Host": "smtp.example.com",
    "Port": 587,
    "Username": "",
    "Password": "",
    "EnableSsl": true
  }
}

AWS SES

{
  "AwsSes": {
    "Region": "us-east-1",
    "AccessKey": "",
    "SecretKey": "",
    "ConfigurationSetName": ""
  }
}

See the Deployment Guide for detailed AWS SES setup including IAM policies.

Security

{
  "Security": {
    "SessionTimeoutMinutes": 60,
    "PasswordResetTokenExpirationMinutes": 60,
    "MaxLoginAttempts": 5,
    "LockoutDurationMinutes": 15
  }
}
Setting Default Description
Security:SessionTimeoutMinutes 60 Session timeout
Security:PasswordResetTokenExpirationMinutes 60 Password reset token lifetime
Security:MaxLoginAttempts 5 Failed attempts before lockout
Security:LockoutDurationMinutes 15 Lockout duration after max attempts

SDK Security Middleware

{
  "Riptide": {
    "Security": {
      "Headers": {
        "EnableHsts": false,
        "RemoveServerHeader": true,
        "EnableXContentTypeOptions": true,
        "EnableXFrameOptions": true,
        "ContentSecurityPolicy": "default-src 'self'; ...",
        "ReferrerPolicy": "strict-origin-when-cross-origin"
      },
      "Audit": {
        "Enabled": true,
        "StorageProvider": "Database",
        "RetentionDays": 2555,
        "IncludeRequestBody": false,
        "IncludeResponseBody": false,
        "ExcludePaths": ["/health", "/ready", "/hangfire"],
        "AlertOnPolicyViolations": false
      },
      "Compliance": {
        "Enabled": true,
        "EnabledTemplates": ["SOC2", "HIPAA", "FedRAMP"]
      }
    }
  }
}
Setting Default Description
Headers:EnableHsts false Enable HTTP Strict Transport Security (enable in production behind TLS)
Headers:RemoveServerHeader true Remove the Server response header
Audit:RetentionDays 2555 Audit log retention (~7 years)
Audit:ExcludePaths ["/health", "/ready", "/hangfire"] Paths excluded from audit logging
Compliance:EnabledTemplates ["SOC2", "HIPAA", "FedRAMP"] Active compliance frameworks

Scheduled Audits

{
  "SecurityAudit": {
    "ScheduledAudit": {
      "Enabled": false,
      "IntervalHours": 24,
      "Frameworks": ["SOC2", "HIPAA", "FedRAMP", "StateRAMP"]
    }
  }
}
Setting Default Description
ScheduledAudit:Enabled false Enable automatic compliance audits
ScheduledAudit:IntervalHours 24 Hours between audit runs
ScheduledAudit:Frameworks All four Frameworks to audit

Riptide SDK

{
  "Riptide": {
    "Logging": {
      "ApplicationName": "RiptideApplicationManager",
      "MinimumLevel": "Information",
      "EnableCorrelationId": true,
      "EnablePiiSanitization": true,
      "Console": {
        "Enabled": true,
        "MinimumLevel": "Debug"
      },
      "File": {
        "Enabled": true,
        "LogDirectory": "logs",
        "MaxFileSizeInMB": 10,
        "RetainedFileCountLimit": 31
      },
      "External": {
        "Enabled": false,
        "Provider": "DataDog",
        "ApiKey": ""
      }
    },
    "Monitoring": {
      "ApplicationName": "RiptideApplicationManager",
      "EnableMetrics": true,
      "EnableTracing": true,
      "Provider": "Console",
      "SamplingRate": 1.0
    },
    "Configuration": {
      "Provider": "LocalDevelopment",
      "EnableValidation": true,
      "EnableCaching": true,
      "CacheExpirationMinutes": 60
    }
  }
}
Setting Default Description
Logging:EnableCorrelationId true Add correlation IDs to all log entries
Logging:EnablePiiSanitization true Sanitize personally identifiable information in logs
Logging:File:RetainedFileCountLimit 31 Number of log files to retain
Monitoring:EnableMetrics true Enable performance metrics collection
Monitoring:EnableTracing true Enable distributed tracing
Monitoring:SamplingRate 1.0 Trace sampling rate (1.0 = sample everything)

Rate Limiting

{
  "RateLimiting": {
    "GlobalPermitLimit": 100,
    "EmailResendLimitPerHour": 3,
    "BulkOperationConcurrency": 3,
    "ApiRequestsPerMinute": 60
  }
}

File Management

{
  "FileManagement": {
    "MaxFileSizeBytes": 5242880,
    "MaxVersions": 10,
    "AllowedFileExtensions": [".json", ".yaml", ".yml", ".txt", ".xml", ".conf", ".config", ".env"]
  }
}
Setting Default Description
MaxFileSizeBytes 5242880 (5 MB) Maximum configuration file size
MaxVersions 10 Maximum versions retained per file
AllowedFileExtensions See above Permitted file types

Background Jobs (Hangfire)

{
  "Hangfire": {
    "DashboardPath": "/hangfire",
    "ServerName": "ApplicationManager",
    "WorkerCount": 5,
    "EnableDashboard": true
  }
}

SignalR

{
  "SignalR": {
    "EnableDetailedErrors": true,
    "MaximumReceiveMessageSize": 102400
  }
}

The SignalR hub at /hubs/progress provides real-time progress updates for long-running operations like compliance assessments and bulk operations.

LLM Gateway

Configuration for the 2.0 AI/LLM gateway. The gateway routes agent and application LLM traffic to managed providers and meters it against budgets.

Gateway authentication

{
  "Llm": {
    "Gateway": {
      "Auth": {
        "AllowApiKey": true,
        "AllowAgentBearer": true
      }
    }
  }
}
Key Default Description
Llm:Gateway:Auth:AllowApiKey true Accept service-account API keys (X-Api-Key) on the gateway endpoints.
Llm:Gateway:Auth:AllowAgentBearer true Accept agent bearer tokens (Authorization: Bearer) on the gateway endpoints.

At least one of the two must be enabled or the API fails fast at startup.

Provider endpoint allowlist (SSRF guard)

Outbound provider calls are restricted to an allowlist of hosts. Configure the permitted provider hosts so the gateway cannot be coerced into calling arbitrary URLs:

{
  "Llm": {
    "ProviderEndpoints": {
      "AllowedHosts": [
        "api.openai.com",
        "api.anthropic.com",
        "*.openai.azure.com"
      ]
    }
  }
}

Provider accounts and API-key storage

Each provider account chooses where its API key lives (KeySource), set per account in the Web UI under Provider Accounts:

KeySource Where the key is read from
EnvironmentVariable (default) An environment variable named by the account's ApiKeySecretName (with a configuration fallback).
Database Stored in the database, encrypted at rest via Data Protection; plaintext is never persisted or returned.
Vault A named secret in the configured Azure Key Vault, resolved by ApiKeySecretName.

Per-model limits (including an optional MaxOutputTokens cap) are configured on each model-catalog entry through the Models screen, not in appsettings.json.

Environment Variable Overrides

Any setting can be overridden via environment variables using the standard ASP.NET Core convention (double underscores for section separators):

# Override the API key
Api__ApiKey=rtk_your-api-key-here

# Point the Identity store somewhere else. Provider and connection string belong to the
# same section — change one and change the other.
Riptide__Database__Identity__Provider=SQLite
Riptide__Database__Identity__ConnectionString="Data Source=/custom/path/identity.db"

# Enable scheduled audits
SecurityAudit__ScheduledAudit__Enabled=true

In Docker deployments, set these in the .env file or pass them directly to docker compose.