Skip to main content

appsettings.json Reference Guide

Complete reference for configuring Muonroi applications. Each configuration section maps to a .NET IOptions<T> pattern and supports environment variable overrides.

Quick Start

Copy the Complete Example below and customize for your environment.


LicenseConfigs

License activation and verification settings for offline and online modes. Bound from the LicenseConfigs section to Muonroi.Governance.Abstractions.License.LicenseConfigs.

Core / activation

KeyTypeDefaultRequiredDescription
ModeenumOfflineNoOffline (verify a license file locally) or Online (phone-home to the license server). Default is Offline. An invalid string (e.g. "office") fails enum binding at startup.
LicenseFilePathstringNoRelative (to content root) or absolute path to the license file. Offline: must be a signed payload JSON ({ "LicenseId": ..., "Signature": ... }); a raw-key file { "LicenseKey": "MRR-..." } is ignored by LicenseStore.Load(). Online: the raw-key file is used to activate against the server.
PublicKeyPathstringNoPath to the license server's RSA public key (PEM). Required for non-free licenses — signature verification is mandatory and cannot be bypassed via config. Get it from GET {Endpoint}/api/v1/signing-key/public.
ActivationProofPathstringlicenses/activation_proof.jsonNoPath to the signed activation proof. Created on first online activation; lets production verify offline without internet.
ActivationJwtPathstringlicenses/activation_jwt.txtNoPath to the activation JWT for frontend verification (MLicenseVerifier). Created during online activation when the server returns a JWT.
FallbackToOnlineActivationbooltrueNoIn Offline mode, if the proof is missing/expired, attempt online activation. Requires connectivity. Set false in production to require pre-activation.
ProjectSeedstringNoPer-project seed for the runtime fingerprint (stored obfuscated in memory). Used only when fingerprint/hardware binding applies; a license with Fingerprint/HardwareId = null is not bound, so changing this does not invalidate it.
FingerprintSaltstringNoSalt mixed into the runtime fingerprint. Same binding caveat as ProjectSeed.
FingerprintScopeenumMachineAndProjectNoControls fingerprint factors. MachineAndProject (default) binds to hardware + OS + project seed; ProjectOnly omits hardware/OS so the same license validates on any machine (dev / UAT / prod).

One license, multiple projects? Yes — verification does not compare the payload ProjectId/TenantId against the consuming app; those fields are only part of the signed canonical data (LicenseVerifier.VerifySignature). A license file with null Fingerprint/HardwareId validates in any project on any machine. ProjectId is metadata/audit only. Prefer a dedicated key per project so revocation, expiry, and MaxActivations are tracked independently.

Enforcement / failure handling

KeyTypeDefaultRequiredDescription
FailModeenumSoftNoSoft = log and degrade (no throw); Hard = throw MInternalException ([SEC_ERR_01]) on validation/chain failure. Use Hard in production with a valid license.
EnforceOnDatabaseboolfalseNoEnforce license checks on database operations.
EnforceOnMiddlewareboolfalseNoEnforce license checks on the HTTP middleware pipeline.
EnforcementModeenum?nullNoForce Free/Development/Production enforcement. If null, derived from tier + ASPNETCORE_ENVIRONMENT.
SkipSignatureVerificationboolfalseNoDev/test only. Ignored for non-free licenses (signature is always mandatory). Never set in production.
SkipAssemblyWhitelistboolfalseNoDev/test only. Skip assembly whitelist verification during activation.
RequireSignedPolicyboolfalseNoRequire a valid signed policy file (PolicyFilePath) for the app to run. Recommended for enterprise.
PolicyFilePathstringNoPath to the signed policy file (e.g. licenses/policy.json).
TrustedPublicKeyTokensstring[]NoHex-encoded public key tokens of assemblies trusted to call sensitive operations.

Anti-tampering (Licensed/Enterprise, production)

KeyTypeDefaultRequiredDescription
EnableAntiTamperingboolfalseNoEnable runtime anti-tampering protection.
AntiTamperingCheckIntervalSecondsint30NoMin seconds between anti-tampering checks per tenant partition. 0 = check every guarded call.
EnableHardwareBreakpointDetectionboolfalseNoDetect hardware breakpoints on compatible runtimes.
EnableTpmAnchoringboolfalseNoAnchor the license to the machine via Windows DPAPI/TPM, making the file non-transferable.

Action chain / audit trail

KeyTypeDefaultRequiredDescription
EnableChainboolfalseNoEnable action-chain tracking (audit trail). Enable only for Licensed/Enterprise.
ChainStorageenumNoneNoNone / File (other backends per LicenseChainStorage).
ChainFilePathstringNoPath to the chain log file when ChainStorage = File (e.g. logs/license-chain.log).
EnableServerValidationboolfalseNoSubmit action chains to the license server for remote audit.
ChainSubmissionIntervalMinutesint60NoHow often to submit chains to the server.
ChainSubmissionBatchSizeint100NoMax chain entries per submission batch.

Online (used only when Mode = "Online")

KeyTypeDefaultRequiredDescription
Online:EndpointstringYes (if Mode=Online)License server base URL (e.g. https://license.muonroi.com). No trailing slash. Host must be in Enterprise.TrustedLicenseServerHosts for Enterprise+Production.
Online:ChainSubmissionEndpointstring/api/v1/chain/submitNoRelative path for submitting action chains.
Online:TimeoutSecondsint10NoHTTP timeout for activation/heartbeat/refresh.
Online:RefreshMinutesint1440NoInterval for the background refresh hosted service (disabled entirely in Offline mode).
Online:EnableHeartbeatboolfalseNoEnable periodic heartbeat verification (nonce rotation).
Online:HeartbeatIntervalMinutesint240NoMinutes between heartbeat checks.
Online:RevocationGraceHoursint24NoGrace period after heartbeat failure before degrading to Free. Handles outages.
Online:EnableCertificatePinningbooltrueNoPin the server certificate to block MITM/fake servers.
Online:ExpectedCertificateThumbprintstringYes (if pinning)SHA-256 thumbprint of the expected server certificate.
Online:TrustedCertificateThumbprintsstring[]NoAdditional trusted thumbprints for certificate rotation.

Enterprise security profile (LicenseConfigs:Enterprise)

Secure-by-default for Enterprise + Production. Key knobs: EnableSecureDefaults (true), AllowPolicyBypassInProduction (false), AllowEndpointTrustBypassInProduction (false), RequireCertificatePinningInProduction (true), RequireTrustedEndpointInProduction (true), RequireServerResponseSignatureInProduction (true), and TrustedLicenseServerHosts (default: license.muonroi.com, license-backup.muonroi.com, license.muonroi.net, license-api.muonroi.com).

Because RequireTrustedEndpointInProduction defaults to true, an Online:Endpoint whose host is not in TrustedLicenseServerHosts is rejected in Enterprise+Production. Use license.muonroi.com (already trusted) or add your host to the list.

Compliance (LicenseConfigs:Compliance) controls evidence-pack export — Enabled (false), ExportRootPath, ExportIntervalMinutes (15), EnableBackgroundExport (false), EvidencePackRetentionDays (365), etc.

Example — Offline (Enterprise, full feature):

"LicenseConfigs": {
"Mode": "Offline",
"ProjectSeed": "your-project-seed-min-16-chars",
"LicenseFilePath": "licenses/license.json",
"PublicKeyPath": "licenses/public.pem",
"FingerprintSalt": "your-project-salt",
"FingerprintScope": "MachineAndProject",
"EnableChain": true,
"ChainStorage": "File",
"ChainFilePath": "logs/license-chain.log",
"FailMode": "Soft",
"EnforceOnDatabase": false,
"EnforceOnMiddleware": false,
"Online": {
"Endpoint": "https://license.muonroi.com",
"ChainSubmissionEndpoint": "/api/v1/chain/submit",
"TimeoutSeconds": 10,
"RefreshMinutes": 60
}
}

Example — Online (with heartbeat + pinning):

"LicenseConfigs": {
"Mode": "Online",
"LicenseFilePath": "licenses/license.key",
"PublicKeyPath": "licenses/public.pem",
"FailMode": "Hard",
"Online": {
"Endpoint": "https://license.muonroi.com",
"EnableHeartbeat": true,
"HeartbeatIntervalMinutes": 240,
"RevocationGraceHours": 24,
"TimeoutSeconds": 10,
"EnableCertificatePinning": true,
"ExpectedCertificateThumbprint": "A1:B2:C3:..."
}
}

See also: License Activation Guide


ControlPlaneAuth

JWT and authorization settings for Control Plane API.

KeyTypeDefaultRequiredDescription
DisableAuthorizationbooltrueNoDevelopment only. Disables auth checks for easier testing. Must be false in production.
SigningKeystring"dev-control-plane-signing-key-change-this"YesHMAC signing key for JWT tokens. Change in production. Min 32 chars.
Issuerstring"muonroi-control-plane"NoJWT issuer claim. Used for token validation.
Audiencestring"muonroi-control-plane-clients"NoJWT audience claim. Identifies intended API clients.

Example:

"ControlPlaneAuth": {
"DisableAuthorization": false,
"SigningKey": "your-super-secret-key-min-32-chars-here!",
"Issuer": "muonroi-control-plane",
"Audience": "muonroi-control-plane-clients"
}
Production Security

Never commit actual signing keys to version control. Use environment variables (ControlPlaneAuth__SigningKey) or Azure Key Vault / AWS Secrets Manager.


RuleControlPlane

Rule management workflow settings (approval, canary, audit).

KeyTypeDefaultRequiredDescription
RequireApprovalbooltrueNoRequire manual approval before activating new rule versions. Prevents accidental deployments.
NotifyOnStateChangebooltrueNoSend notifications (email/Slack) when rules are created, submitted, approved, or activated. Requires external notifier integration.
EnableCanarybooltrueNoEnable canary deployments (gradual rollout to percentage of tenants).
AuditSignerKeyIdstring"ruleset-control-plane"NoKey ID for audit trail signing. Used to link audit records to signing keys.
AuditPrivateKeyPemPathstring""NoPath to RSA private key (PEM) for signing audit trail entries. Empty = disable audit signing.

Example:

"RuleControlPlane": {
"RequireApproval": true,
"NotifyOnStateChange": true,
"EnableCanary": true,
"AuditSignerKeyId": "ruleset-control-plane",
"AuditPrivateKeyPemPath": "config/audit-signer.pem"
}

See also: Rule Workflow Guide


DecisionTableEngineOptions

Decision table execution engine configuration.

KeyTypeDefaultRequiredDescription
PostgresConnectionStringstringConditionalPostgreSQL connection string. Use if backing decision tables with PostgreSQL.
SqlServerConnectionStringstringConditionalSQL Server connection string. Use if backing decision tables with SQL Server.
Schemastring"public"NoDatabase schema for decision table storage (PostgreSQL) or prefix (SQL Server).
AutoMigrateDatabasebooltrueNoAutomatically run pending migrations on startup. Disable in production if you manage migrations separately.
DefaultHitPolicystring"FIRST"NoDefault hit policy for new decision tables: FIRST, UNIQUE, COLLECT, PRIORITY, RULE_ORDER.
MaxTableSizeint10000NoMaximum rows per decision table. Enforced at evaluation time.

Example:

"DecisionTableEngineOptions": {
"PostgresConnectionString": "Server=db.example.com;Database=muonroi_rules;User=muonroi;Password=***",
"Schema": "public",
"AutoMigrateDatabase": true,
"DefaultHitPolicy": "FIRST",
"MaxTableSize": 10000
}

See also: Decision Table Guide


TokenConfigs

JWT and token lifetime settings (Access Token / Refresh Token).

KeyTypeDefaultRequiredDescription
IssuerstringYesToken issuer. Must match ControlPlaneAuth:Issuer or client validation fails.
AudiencestringYesToken audience. Clients validate this claim.
AccessTokenExpireMinutesint60NoAccess token lifetime (minutes). Short-lived. Typical: 15–60 min.
RefreshTokenExpireDaysint7NoRefresh token lifetime (days). Long-lived. Used to obtain new access tokens.
SecretKeystringYesHMAC secret for token signing (same as ControlPlaneAuth:SigningKey).

Example:

"TokenConfigs": {
"Issuer": "muonroi-control-plane",
"Audience": "muonroi-control-plane-clients",
"AccessTokenExpireMinutes": 60,
"RefreshTokenExpireDays": 7,
"SecretKey": "your-super-secret-key-min-32-chars-here!"
}

See also: Authentication Guide


TenancyConfigs

Multi-tenancy and data isolation configuration.

KeyTypeDefaultRequiredDescription
IsolationModestring"SharedSchema"NoData isolation strategy: SharedSchema (EF query filters), SeparateSchema (PostgreSQL SearchPath), SeparateDatabase (DB per tenant).
DefaultTenantIdstringNoSystem tenant ID for background jobs and system operations. If omitted, job execution requires explicit tenant context.
EnableQuotaEnforcementbooltrueNoEnforce per-tenant quotas (max workflows, concurrent rules, requests/day).
QuotaCacheExpiryMinutesint5NoCache quota checks for N minutes. Lower = more accurate but higher DB load.

Example:

"TenancyConfigs": {
"IsolationMode": "SharedSchema",
"DefaultTenantId": "system",
"EnableQuotaEnforcement": true,
"QuotaCacheExpiryMinutes": 5
}

See also: Multi-Tenancy Architecture


CacheConfigs

In-memory and distributed cache configuration.

KeyTypeDefaultRequiredDescription
Providerstring"InMemory"NoCache provider: InMemory (single-server), Redis (distributed).
DefaultTTLSecondsint300NoDefault cache TTL (seconds) if not explicitly set per entry. Typical: 300–3600.
Redis:ConnectionStringstringConditionalRedis connection string (e.g., localhost:6379). Required if Provider=Redis.
Redis:InstanceNamestring"muonroi:"NoKey prefix for all Redis entries. Allows multiple apps to share Redis instance.
MaxMemoryMBint256NoInMemory only. Maximum memory before eviction. -1 = unlimited.

Example:

"CacheConfigs": {
"Provider": "Redis",
"DefaultTTLSeconds": 300,
"Redis": {
"ConnectionString": "localhost:6379,ssl=false",
"InstanceName": "muonroi:"
}
}

See also: Caching Guide


MessagingConfigs

Message bus and event publishing configuration.

KeyTypeDefaultRequiredDescription
Providerstring"InMemory"NoMessage bus provider: InMemory, RabbitMQ, AzureServiceBus, EventBridge.
ConnectionStringstringConditionalConnection string for external bus. Required if Provider is not InMemory.
Topics:RuleSetChangedstring"ruleset-changes"NoTopic/queue name for rule set change events.
Topics:AuditLogstring"audit-logs"NoTopic/queue name for audit trail events.
PublisherBatchSizeint100NoBatch events before publishing. Higher = better throughput, higher latency.

Example:

"MessagingConfigs": {
"Provider": "RabbitMQ",
"ConnectionString": "amqp://guest:guest@localhost:5672/",
"Topics": {
"RuleSetChanged": "ruleset-changes",
"AuditLog": "audit-logs"
},
"PublisherBatchSize": 100
}

See also: Event Messaging Guide


ObservabilityConfigs

OpenTelemetry tracing and Prometheus metrics configuration.

KeyTypeDefaultRequiredDescription
EnableTracingbooltrueNoEnable distributed tracing via OpenTelemetry.
EnableMetricsbooltrueNoEnable Prometheus metrics export.
OtlpEndpointstringConditionalOTLP exporter endpoint (e.g., http://localhost:4317). Required if EnableTracing=true and using external collector.
LogLevelstring"Information"NoMinimum log level: Trace, Debug, Information, Warning, Error, Critical.
SamplingFractiondouble1.0NoTrace sampling ratio (0.0–1.0). 0.1 = 10% of traces. Use in high-volume scenarios.

Example:

"ObservabilityConfigs": {
"EnableTracing": true,
"EnableMetrics": true,
"OtlpEndpoint": "http://localhost:4317",
"LogLevel": "Information",
"SamplingFraction": 1.0
}

See also: Observability Guide


Connection Strings

Standard database and external service connections.

KeyDescription
RuleControlPlaneDbPrimary PostgreSQL or SQL Server connection for rule definitions, versions, approvals, and metadata.
RedisRedis connection for caching and session state. Format: host:port[,ssl=true/false].
AuditDb(Optional) Separate database for immutable audit trail storage. If omitted, uses RuleControlPlaneDb.

Example:

"ConnectionStrings": {
"RuleControlPlaneDb": "Server=localhost;Database=muonroi_rules;User=muonroi;Password=***",
"Redis": "localhost:6379,ssl=false",
"AuditDb": "Server=localhost;Database=muonroi_audit;User=muonroi;Password=***"
}

Environment Variable Overrides

All configuration keys can be overridden via environment variables using double-underscore (__) notation:

appsettings KeyEnvironment Variable
LicenseConfigs:ModeLicenseConfigs__Mode
LicenseConfigs:Online:EndpointLicenseConfigs__Online__Endpoint
ControlPlaneAuth:SigningKeyControlPlaneAuth__SigningKey
CacheConfigs:Redis:ConnectionStringCacheConfigs__Redis__ConnectionString
ConnectionStrings:RuleControlPlaneDbConnectionStrings__RuleControlPlaneDb

Example (Docker):

docker run \
-e "LicenseConfigs__Mode=Online" \
-e "LicenseConfigs__Online__Endpoint=https://license.truyentm.xyz" \
-e "ControlPlaneAuth__SigningKey=your-production-key" \
-e "CacheConfigs__Redis__ConnectionString=redis:6379" \
muonroi-app:latest

Example (Linux Bash):

export LicenseConfigs__Mode="Online"
export LicenseConfigs__Online__Endpoint="https://license.truyentm.xyz"
export ControlPlaneAuth__SigningKey="your-production-key"
dotnet MyApp.dll

Complete Example

Minimal production-ready appsettings.json with all major sections:

{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Muonroi": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"RuleControlPlaneDb": "Server=db.example.com;Database=muonroi_rules;User=muonroi;Password=***;SSL Mode=Require",
"Redis": "cache.example.com:6379,ssl=true",
"AuditDb": "Server=db.example.com;Database=muonroi_audit;User=muonroi;Password=***;SSL Mode=Require"
},
"LicenseConfigs": {
"Mode": "Online",
"LicenseFilePath": "licenses/license.key",
"ActivationProofPath": "licenses/activation_proof.json",
"FallbackToOnlineActivation": true,
"Online": {
"Endpoint": "https://license.truyentm.xyz",
"EnableHeartbeat": true,
"HeartbeatIntervalMinutes": 240,
"RevocationGraceHours": 24,
"TimeoutSeconds": 10
}
},
"ControlPlaneAuth": {
"DisableAuthorization": false,
"SigningKey": "your-super-secret-key-min-32-chars-here!",
"Issuer": "muonroi-control-plane",
"Audience": "muonroi-control-plane-clients"
},
"TokenConfigs": {
"Issuer": "muonroi-control-plane",
"Audience": "muonroi-control-plane-clients",
"AccessTokenExpireMinutes": 60,
"RefreshTokenExpireDays": 7,
"SecretKey": "your-super-secret-key-min-32-chars-here!"
},
"RuleControlPlane": {
"RequireApproval": true,
"NotifyOnStateChange": true,
"EnableCanary": true,
"AuditSignerKeyId": "ruleset-control-plane",
"AuditPrivateKeyPemPath": "config/audit-signer.pem"
},
"DecisionTableEngineOptions": {
"PostgresConnectionString": "Server=db.example.com;Database=muonroi_rules;User=muonroi;Password=***;SSL Mode=Require",
"Schema": "public",
"AutoMigrateDatabase": true,
"DefaultHitPolicy": "FIRST",
"MaxTableSize": 10000
},
"TenancyConfigs": {
"IsolationMode": "SharedSchema",
"DefaultTenantId": "system",
"EnableQuotaEnforcement": true,
"QuotaCacheExpiryMinutes": 5
},
"CacheConfigs": {
"Provider": "Redis",
"DefaultTTLSeconds": 300,
"Redis": {
"ConnectionString": "cache.example.com:6379,ssl=true",
"InstanceName": "muonroi:"
}
},
"MessagingConfigs": {
"Provider": "RabbitMQ",
"ConnectionString": "amqp://guest:[email protected]:5672/",
"Topics": {
"RuleSetChanged": "ruleset-changes",
"AuditLog": "audit-logs"
},
"PublisherBatchSize": 100
},
"ObservabilityConfigs": {
"EnableTracing": true,
"EnableMetrics": true,
"OtlpEndpoint": "http://otel-collector.example.com:4317",
"LogLevel": "Information",
"SamplingFraction": 1.0
}
}

Development vs. Production Checklist

SettingDevelopmentProduction
LicenseConfigs:ModeOffline (local testing)Online (with heartbeat)
ControlPlaneAuth:DisableAuthorizationtrue (optional)false (required)
ControlPlaneAuth:SigningKeyTest valueUnique 32+ char secret from Key Vault
RuleControlPlane:RequireApprovalfalse (optional)true (required)
CacheConfigs:ProviderInMemoryRedis
ObservabilityConfigs:SamplingFraction1.0 (all traces)0.1–0.5 (reduce noise)
Security Checklist
  • Never commit production secrets to Git. Use environment variables or managed secrets.
  • Rotate signing keys every 90 days.
  • Use HTTPS for all external endpoints (license server, OTLP, Redis, RabbitMQ).
  • Enable RequireApproval for all non-development environments.
  • Review audit logs monthly.

See Also