appsettings overview

NodePilot reads configuration from appsettings.json, environment-specific files and environment variables. Later sources override earlier ones. In environment variables, a double underscore __ replaces the colon of a configuration hierarchy.

Example: ConnectionStrings__Postgres corresponds to ConnectionStrings:Postgres.

Providers

SettingValuesDefault
Database:Providerpostgres | sqlserverpostgres
Remote:Providerwinrm | noopwinrm
Secrets:ProviderDpapi | AesGcmDpapi
Logging:Formattext | cmtrace | json | ecs-jsoncmtrace

The noop remote provider has to be acknowledged (Remote:AllowNoop=true or NODEPILOT_ALLOW_NOOP_REMOTE=1), otherwise the boot is aborted.

Provider connections, timeout budgets and the behaviour during database outages are described in Database providers.

Connection strings

ProviderKey
PostgreSQLConnectionStrings:Postgres
SQL ServerConnectionStrings:DefaultConnection

Authentication

KeyDefaultRequirement
Jwt:Key / Jwt:Issuer / Jwt:AudienceAn auto-generated jwt-secret.key if Jwt:Key is absentIdentical on all HA nodes
Authentication:LocalLoginModeBreakGlassOnlyDisabled, BreakGlassOnly or Enabled
Authentication:SessionAbsoluteLifetimeHours81–168; a refresh does not extend the absolute limit
Authentication:MaxAuthorizationStalenessMinutes151–15; stale external snapshots are rejected
Authentication:Ldap:EnabledfalseWith true: an LDAPS endpoint, base DN, UPN suffix, service bind and allow-list are required
Authentication:Ldap:Endpoints[]An ordered DC list, e.g. ldaps://dc01:636; the bind tries them in order, but the lookup afterwards requires consensus across all DCs (no login failover — one DC down ⇒ 503)
Authentication:Ldap:UseSsltrueMandatory when LDAP is enabled; certificate validation stays on
Authentication:Ldap:BindTimeoutSeconds51–5 (boot validation enforces this limit)
Authentication:Ldap:AllowedGroupSids[]At least one AD group SID for LDAP or Windows SSO
Authentication:Ldap:DirectorySyncIntervalMinutes51–5
Authentication:Ldap:DirectorySyncMaxConcurrency161–32 concurrent service-bind lookups per sync pass
Authentication:Windows:EnabledfalseAn HTTP SPN, a browser intranet policy and a complete LDAPS service-bind configuration are required
Authentication:Windows:AllowNtlmFallbackfalseHas to stay false
Authentication:Windows:NtlmDisabledByPolicyfalseHas to be confirmed as true before Windows SSO is enabled
Authentication:Oidc:EnabledfalseAn HTTPS authority, client ID/secret and a group allow-list; release-gated
Authentication:Scim:EnabledfalseA bearer token of 32–4096 characters; release-gated
Authentication:Scim:PreviousBearerTokennullThe old token, only during a controlled rotation overlap; delete it afterwards
DataProtection:KeyRingPathdata-protection-keysWith HA+OIDC, a persistent shared path for all nodes
DataProtection:CertificateThumbprintnullWith HA+OIDC, a shared certificate with its private key in LocalMachine\My
DataProtection:SharedKeyRingfalseHas to be true with HA+OIDC once shared storage is verified
ExternalTrigger:Keys:<id>:KeyHashEmptyThe SHA-256 of the integration key as Base64; the plaintext is not persisted
ExternalTrigger:Keys:<id>:AllowedWorkflowIds[]Immutable workflow GUIDs; empty means deny-all
ExternalTrigger:ApiKeyEmptyThe legacy plaintext key; only effective together with the allow-list below
ExternalTrigger:AllowedWorkflowIds[]The GUID scope of the legacy key; empty means deny-all

ExternalTrigger:Keys is read as a complete map from the highest-priority provider that declares it. A higher-priority Keys: {} therefore reliably revokes all lower-priority keys; individual hashes and scopes are never assembled from different provider snapshots. AllowedWorkflowIds is likewise not merged index by index: [A] replaces a lower-priority list [A,B], and [] is deny-all. A provider override of the Keys map therefore has to contain every integration that should still exist.

The same rule applies to these lists: RestApi:AllowedHosts, WaitForCondition:AllowedHosts, RestApi:Proxy:BypassList, Llm:Proxy:BypassList, Authentication:Ldap:AllowedGroupSids and GlobalRoleMappings, Authentication:Oidc:AllowedGroupIds, GlobalRoleMappings and Scopes, and Agents:ReadOnlyMcpTools. Each list is read whole from the highest-priority provider that declares it, so an override has to repeat every entry that should stay. Declaring the same list as both a scalar value and an array is rejected as ambiguous.

The entire Authentication section is fixed at boot. Saves through the admin settings set the restart marker; they only become active after a service restart. LDAP can be checked against the current draft before saving via POST /api/admin/settings/test/ldap. Secrets belong in environment variables or the secret provider.

In a cluster, authentication is config-as-code: PUT /api/admin/settings/Authentication answers with 409 CLUSTER_CONFIG_AS_CODE_REQUIRED. The configuration and secrets have to be rolled out identically to all nodes, after which a cluster restart is required. The shared data-protection key ring protects OIDC correlation, nonce and server-side tickets across node changes. The certificate can be separate from the Kestrel TLS certificate, but has to be available with its private key on every node.

Restarting from the UI. When a save needs a restart, the banner on the settings page offers Restart service now (POST /api/admin/settings/restart-service, np settings restart-service, MCP restart_service). The process stops its host gracefully and then ends with exit code 75 before the service reports "stopped"; the Service Control Manager treats that as a crash and starts it again through the recovery actions the installers configure (restart/5000/…). No service-control rights are needed. The button only appears when the server runs as a Windows service and every configured recovery action is a restart — otherwise the endpoint answers 409 SERVICE_RESTART_UNAVAILABLE (NOT_A_WINDOWS_SERVICE, SERVICE_NOT_RESOLVED, RECOVERY_NOT_CONFIGURED). Running executions are cancelled; the Windows event log records the restart as an unexpected service termination. Within the 24 h reset window the SCM delays the third restart by 60 s. In a cluster the restart only affects the node you are connected to and triggers a failover.

Details: AD SSO Preview, Authentication.

Cluster / HA

Cluster:Enabled (default false). Details: High availability.

AI

Llm:Enabled (default false) plus at least one profile under Llm:Profiles and an Llm:ActiveProfileId pointing at it. If outbound traffic is only permitted through a proxy, Llm:Proxy:Mode is added (default Off, otherwise System or Custom). Details: AI features.

Observability

OpenTelemetry:Exporters:PrometheusScrapeAllowAnonymous (default false). Details: Observability.

Retention

Opt out via Retention:*:Enabled: false. Idempotency keys (24 h, fixed TTL) run always. Details: Retention services.

Performance

Performance:ManualTuning (default false, requires a restart). With false, NodePilot derives Engine:Runspace:*, Engine:MaxConcurrentSteps, Threading:* and ExecutionDispatch:* from the detected CPU + RAM — the numbers of those sections in the configuration are then an inert preset. What is actually in force: GET /api/admin/settings/effective-sizing or np settings effective-sizing. Details: Performance sizing.

Hardening

Default true (hardened); appsettings.Development.json relaxes them to false. Details: Hardening flags.

Paths (production)

KeyPurposeFallback
Jwt:KeyPathPath for jwt-secret.key{ContentRoot}/jwt-secret.key
Security:AdminSetupTokenPathPath for admin-setup.token{ContentRoot}/admin-setup.token
Logging:File:PathThe Serilog rolling file{ContentRoot}/logs/nodepilot-.log
Kestrel:Https:*Kestrel direct HTTPS from the Windows certificate storeDefault binding

Set Credentials:DpapiScope to LocalMachine in production.

All chapters