Skip to main content
Work through this checklist before any agent running on NSP touches production data or performs irreversible actions. The sections are ordered by priority: security issues in the daemon can expose your applications to unauthorized access, so those come first. Reliability settings determine whether the daemon survives a machine restart or a transient failure. Agent safety settings prevent your code from firing off unrecoverable actions when something goes wrong. Monitoring items ensure you hear about problems before your users do.

Section 1 — Security

Locking down the daemon is the first thing you should do. The default configuration is intentionally permissive to make local development frictionless, but every one of those defaults is a hazard in production.
The daemon emits a loud startup warning whenever require_key = false or cors.allow_all_origins = true is set. These warnings are intentional — do not suppress them; fix the configuration.
  • Enable API key authentication.
    Open C:\ProgramData\Nelieo\axon.toml and confirm the [auth] section requires a key:
    Generate your production key from platform.nelieo.com. Never set require_key = false outside of a fully isolated development machine.
  • Bind only to localhost.
    The host field controls which network interface the daemon listens on. In production it must always be 127.0.0.1. Setting it to 0.0.0.0 exposes the daemon to every network interface on the machine, including any that are publicly reachable.
  • Disable wildcard CORS.
    If you have any dashboard or browser-based tooling that calls the daemon, enumerate those origins explicitly. Never allow all origins.
  • Store API keys in environment variables, not in source code.
    The Python SDK reads NSP_API_KEY automatically:
  • Rotate keys regularly.
    Visit platform.nelieo.com to issue a new key, update your deployment environment, then revoke the old key. The daemon’s in-memory verification cache will invalidate the revoked key within seconds.

Section 2 — Reliability

A daemon that does not survive reboots or crashes is not production-ready. The items in this section make sure NSP keeps running regardless of what the underlying Windows machine does.
  • Install the daemon as a Windows Service with automatic startup.
    Run the following command once from an elevated (Administrator) terminal:
    This registers the NSPDaemon service with start type Automatic, which means it comes back on every reboot without any manual intervention.
  • Configure service recovery actions.
    The installer sets sensible defaults (restart after 30 s, 60 s, then 120 s), but you should verify these are in place or tune them to your requirements:
    The reset= 86400 argument resets the failure counter after 24 hours of clean operation.
  • Set min_confidence to 0.4 or higher.
    This prevents the daemon from wasting resources tracking processes it cannot reliably identify. The default is already 0.4 — confirm it has not been lowered:
  • Tune poll_interval_secs for your latency needs.
    The default of 2 seconds is the right balance for most production workloads. Lowering this value increases CPU load on the host; raising it increases the staleness of cached state. Adjust only if you have a specific latency or resource budget.
  • Poll GET /health from your monitoring system.
    The health endpoint returns a lightweight JSON payload and never requires authentication. Add it to your uptime monitor or Nagios/Datadog check:
    Alert on anything other than "status": "ok".

Section 3 — Agent Safety

These settings guard against your agent taking destructive or irreversible actions when state data is stale, ambiguous, or wrong.
  • Require verify_expression for all irreversible_write actions.
    Any action whose schema has "reversibility": "irreversible_write" — such as send_reply, delete_permanently, or submit_form — must be called with a verify_expression that confirms the action actually took effect. The daemon rejects the call with 400 missing_verify_expression if you omit it, but your code should be explicit regardless:
  • Tune verify_timeout_ms to match your app’s response time.
    The default verification timeout is 5 000 ms. If your target application is slower (for example, a Salesforce form that takes 8 seconds to confirm), raise this value. If it is faster, lower it to fail quickly:
  • Test your agent on a staging environment before production.
    Run your agent against a staging instance of the target app with non-production data. Confirm that every irreversible_write path behaves as expected and that verify_expression values match real post-action state.
  • Handle NSPVerificationFailedError correctly — do not retry blindly.
    When you receive this error it means the action executed but the post-action state did not match your verify_expression. The action may or may not have succeeded in the application. Retrying immediately risks a double-execution. Log the error, inspect the state manually, and alert a human if necessary:
  • Handle NSPRateLimitError with exponential backoff.
    The daemon enforces 10 action executions per second per API key by default. Bursting past that limit returns a 429 which the SDK surfaces as NSPRateLimitError. Back off exponentially and add jitter:

Section 4 — Monitoring

Knowing when something is wrong before your users do is a matter of wiring up the right signals from the start.
  • Poll GET /health from your monitoring system.
    If you have not done this under Reliability above, do it now. This endpoint is unauthenticated by design so your monitoring agent does not need a key.
  • Configure Windows Event Log monitoring.
    The daemon writes all significant events — startup, shutdown, probe errors, auth failures — to the Windows Application event log under the source NSPDaemon. Point your log aggregator (Splunk, Datadog Agent, Elastic Agent, etc.) at this source, or set up a manual alert:
    In Event Viewer: Windows Logs → Application → Filter Current Log → Source: NSPDaemon.
  • Use level = "info" in production — not "debug".
    Debug logging is verbose and will fill your log storage quickly. Set the level to "info" unless you are actively investigating a problem:
  • Use format = "json" for structured log ingestion.
    JSON-formatted logs can be parsed, filtered, and indexed by any modern log aggregator without custom grok patterns. The "text" format is human-readable but unstructured — reserve it for local development:

Production axon.toml Reference

The following snippet shows all security- and reliability-relevant settings together in a single production-ready configuration block:
Use AXON_* environment variables to inject secrets at runtime without putting them in the .toml file. For example, AXON_AUTH__KEYS_FILE overrides auth.keys_file and is never written to disk.