Server settings¶
Admins change how the server runs on the Settings page: the public address,
the web address and certificate, the OpenSearch connection, search limits, syslog,
the detection scheduler, the AI assistant and more, without editing
signalith.yaml on the server. Each setting says where its value comes from, and
whether it applies at once or after a restart, which the page does for you.
Users, directory sign-in, agent tokens, threat intel feeds and data retention keep their own pages; the Settings page links to them.
Only admins see the page (under Configure, or type "settings" in the
Jump to box with Ctrl+K). Viewers and analysts do not see it, and its API
answers them 403.
Using the page¶
The page has one card per section (General, Web server, HTTPS, OpenSearch, Search, Syslog, Detections, AI assistant, Threat intel) and About this server. On a wide screen a list of the sections stays on the left; on a phone the sections are a row of buttons under the top bar that scrolls sideways.
Each setting has its name and what it does. A setting with no note comes from
signalith.yaml or the built-in default (an empty box shows what empty means,
such as "When empty: 12h"); the page says so once, at the top. A note shows only
when it tells you something:
- Changed here by ann, 2h ago, with Reset to take it off the page.
- A lock and Set by SIGNALITH_… when an environment variable sets it. The box cannot be changed; change the variable where Signalith's environment is set.
- Set aside, when a restart could not use a change (see below), with why, Try it again and Remove.
Changes wait until you save them. A bar at the bottom says how many are not saved yet, with Discard and Save changes; leaving the page or closing the tab with unsaved changes asks first. When something cannot be saved, nothing is saved: each setting with a problem says what is wrong, and the cursor moves to the first one.
Changes that are hard to undo ask before they are saved, and say what will happen:
a new listen address, OpenSearch address or index prefix, turning HTTPS on or off,
skipping OpenSearch's certificate check, turning the detection scheduler off, and
allowing threat intel feeds from this computer. The server checks the changes
first, so you are only asked about changes that can be saved. When the listen
port or HTTPS changes and the public address still names the old one, the same
question offers to change the public address too, since agents send there. A
listen address on 127.0.0.1 chosen from another computer says plainly that you
could not open the page again from there.
The public address may be left empty: it is then worked out from the listen
address, and the page shows what it works out to. When it is set and does not
match how Signalith answers (http:// while it serves HTTPS, or another port),
the page warns and offers the matching address with one click. That is right
only behind a proxy or a port forward.
Proxies and gateways, in the Web server card, lists addresses that stand for
many people, such as a NAT gateway or Docker Desktop's port forwarding. Such an
address is not held to one computer's share of connections, and wrong passwords
from it count against each account instead of pausing sign-ins from the whole
address. For a reverse proxy that sets X-Forwarded-For itself, list it under
Trusted reverse proxies in the HTTPS card instead and choose Client address
header, so each person is counted by their own address. See
failed sign-in limits. Applies after a restart.
Turning syslog on is two settings in the Syslog card (UDP and TCP address,
such as 0.0.0.0:514), then a restart. The Add data page's syslog steps send
you there.
HTTPS¶
The HTTPS card has how Signalith keeps the web page, the API, agents and syslog over TLS private (see HTTPS):
- HTTPS: Automatic (Signalith's own certificate, the default), your own certificate files, or Off, only behind a reverse proxy that serves HTTPS.
- Extra certificate names: other names or addresses people and agents use, for the automatic certificate.
- Certificate authority reaches: standard (this server and private network names, the default) or strict (only this server's own names and addresses), for a certificate authority Signalith makes. Saving it changes nothing for browsers or agents. It is used when you make a new certificate authority on the Security page, which then helps you switch to it (see How far the certificate authority reaches).
- Certificate file and Key file: used only with your own certificate files. The page checks that they load before saving.
- Agents on plain HTTP: whether agents set up for
http://may still send while you update them from Add data. Applies at once. On a Docker quick start upgraded from an older version, choosing Refuse them also ends the old example tokenchange-this-ingest-tokenfor good. - Trusted reverse proxies: the proxies whose
X-Forwarded-Protoheader is believed. Applies at once. With this empty, asignalith.yamlfrom before HTTPS was the default believes a proxy on this computer or a private network, and the field says so; listing one ends that. A list that leaves out the proxy you opened the page through is refused, since with HTTPS on that proxy would stop working at once: add it, or make the change from a browser that reaches Signalith without the proxy. - Client address header: the header the trusted proxies set to each person's
address,
X-Forwarded-FororForwarded. The sign-in limits and the log then use that address instead of the proxy's (see failed sign-in limits). Choose one only if the proxy sets the header itself; for nginx that takesproxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;(see Behind a reverse proxy). With None, everyone reaching Signalith through a trusted proxy counts as one shared address. Applies at once.
The rules are those of signalith.yaml: your own files need both files, and the files
are refused with the other modes; an http:// public address is read as https://
while HTTPS is on, and the page offers the https:// one. Certificate files saved on
the page by a version without the HTTPS setting, which was then how HTTPS was turned
on, mean your own certificate files, as they do in a signalith.yaml without
server.tls.mode. A restart keeps the same
certificate authority, so browsers and agents that trust it go on doing so; a public
address saved on the page joins the certificate at once. In use now, under the
settings, shows the mode in use, the names the certificate covers and the CA's
fingerprint, with a link to download the CA.
Where changes are kept¶
Changes made on the page are written to settings.yaml in the lookups folder
(/var/lib/signalith/lookups/settings.yaml on Linux,
C:\ProgramData\Signalith\lookups\settings.yaml on Windows, the lookups volume in
Docker), never to signalith.yaml, which is often read-only. Set
SIGNALITH_SETTINGS_FILE to keep it somewhere else.
The file holds only the settings changed on the page, each with who changed it and
when, when a restart last checked it (checked_at), and for a change a restart set
aside, why (refused). Signalith rewrites it whole on every save, through a
temporary file and a rename, readable only by its own account: mode 0600, even
when the file it replaces allowed more (on Windows, only SYSTEM, Administrators,
the service account and the account that saved it). A link put in its place is
replaced by the new file, and the file it pointed to is left as it was, with
whatever it held; signalith secrets and the server's log say so. The
OpenSearch password and the AI model's API key saved on the page are kept in it
encrypted with Signalith's master key (enc:v1:..., see
encryption.md); one kept as plain text, as earlier versions did,
still works and is encrypted when the server next starts. When signalith settings
reset runs as root, the new file keeps the owner the old one had (or takes its
folder's), so the service can still read it.
settings:
opensearch.index_prefix:
value: siem2
changed_by: ann
changed_at: 2026-10-12T18:52:32Z
checked_at: 2026-10-12T18:53:02Z
server.listen:
value: 0.0.0.0:443
changed_by: ann
changed_at: 2026-10-12T18:55:10Z
refused: "Signalith cannot listen on 0.0.0.0:443 (bind: permission denied). Signalith kept running with the previous settings. Choose another address or port."
refused_at: 2026-10-12T18:55:12Z
opensearch.password:
secret: enc:v1:9096cd23:zNhdzHvpeSnrdiqQHGOGMRlih2VUzUrwcOjWVF3w4lW1dAVcs-fPcn_nBiPB6wM
sent_to: https://opensearch.corp.example:9200
changed_by: ann
changed_at: 2026-10-12T18:52:32Z
Which value wins¶
- An environment variable, such as
SIGNALITH_LISTENorSIGNALITH_OPENSEARCH_PASSWORD. The page shows these settings locked, with the variable's name: change them where Signalith's environment is set (for exampledocker-compose.ymlor the service's settings), then restart it. - The Settings page.
signalith.yaml.- The built-in default.
Every setting on the page shows which of these its value comes from, and
Reset takes it off the page, so signalith.yaml or the default applies again.
Applying changes¶
Settings marked applies at once take effect when you save: the public address, the sign-out time, the default time range and events per search, the quiet data source time, the most findings per run, and the AI assistant. A new public address waits for the restart when the listen address or the certificate also changes, so agents set up meanwhile are not sent to an address nothing answers yet.
The others are saved and wait for a restart. A banner at the top of the page
names what is waiting (What changes lists the value in use and the saved
one) and has a Restart now button. While Signalith restarts, the banner
shows its progress; the page reloads when Signalith is back, or moves to the new
address when the web address or HTTPS changed, and you stay signed in (unless
HTTPS was turned on or off: browsers keep sign-ins over http:// and https://
apart, so you sign in again there). If the new settings cannot work, the banner
says why, with a link to the setting to change, and Try again is no longer
the main button until something changes. Signalith restarts
itself inside the same process: it stops its components (web handlers, OpenSearch
client, syslog receiver, detection scheduler, feed downloader and the rest) and
builds them again from the saved settings. This works the same under Docker,
systemd, a Windows service or a terminal. People stay signed in, and requests that
arrive during the few milliseconds of the switch wait for it. The server keeps its
identity, and, when it runs the background jobs, keeps running them: they finish
their current step and start again with the new settings. If the restart turns
Run detections on schedule off, or moves to another OpenSearch, it hands them to
another server that shares the OpenSearch, if there is one.
Protection against locking yourself out¶
The page makes it hard to lock yourself out, though not impossible: a firewall or a proxy between you and Signalith can still make a working address unreachable. Keep shell access to the server for the steps below.
Before anything stops, a restart checks that the new settings can work:
- data retention is not deleting, archiving or restoring days right now;
- the files and folders Signalith reads can be read (users, directory sign-in, detections, dashboards);
- the certificate and key files load;
- OpenSearch answers with the new connection settings (within 10 seconds);
- the new web address and syslog addresses can be listened on.
If one of these fails, nothing changes: Signalith keeps running with the settings in use, and the page says what failed. A change that caused it is set aside: it stays in the settings file, marked with why, but is not used, not even when Signalith next starts, until you Try it again, change it or Remove it. Changes that cannot be used without it are set aside with it, such as the certificate files saved with HTTPS set to your own files, so the rest still work at the next start. The other changes can then be applied with Restart now. If the new components then fail to start anyway, Signalith goes back to the previous settings, sets the changes aside, and says so. If even the previous settings cannot start, the web page stays up to say so, and Signalith tries again every 30 seconds.
When the web address or HTTPS changes, the page moves to the new address, and
Signalith waits up to 2 minutes for an admin to open a page there. Behind a
trusted reverse proxy, turning HTTPS on or off leaves the proxy's address as it
is, so the page stays there, and its next request confirms the change. If nobody
does (the new address cannot be reached from your computer, or a firewall blocks
it), Signalith goes back to the previous address by itself and sets the change
aside. For a move to another port, the old address keeps answering until then.
A listen address on 127.0.0.1 saved from another computer asks once more
before the restart, and is then kept, since only the server can reach it.
Settings saved on the page never keep Signalith from starting. If the settings
file cannot be read, or Signalith cannot start with the settings in it (for
example, the saved web address is taken) but can with signalith.yaml alone, it
starts with signalith.yaml alone, logs why, and shows it at the top of the
Settings page, on the setting to blame, and in signalith validate. An
OpenSearch connection saved on the page but not checked by a restart yet is
checked when Signalith starts: if OpenSearch answers with the settings in
signalith.yaml but not with the page's, those are set aside.
If you are locked out anyway¶
On the server, with the file the service uses. On Linux, the service's unit
points the lookups folder at /var/lib/signalith. signalith settings and
signalith validate read the folders the service is given from its unit
(systemctl show signalith, as signalith secrets does) when it runs with the
same config file, and say so, so they find its file by themselves:
sudo signalith settings list -c /etc/signalith/signalith.yaml
sudo signalith settings reset -c /etc/signalith/signalith.yaml server.listen
sudo signalith settings reset -c /etc/signalith/signalith.yaml # every change
sudo systemctl restart signalith
Where the unit cannot be read (no systemd, or another config file), give the
file with -file, which always wins:
sudo signalith settings reset -c /etc/signalith/signalith.yaml -file /var/lib/signalith/lookups/settings.yaml server.listen
list shows what was changed on the page, by whom and when, and what was set
aside. Passwords and keys are never printed. When there is no settings file
where the command looks, it says so and names the service's file if it finds
one; it never claims to have reset anything. A file that cannot be read is kept
as settings.yaml.broken when reset starts a new one. signalith validate
takes -file too.
On Windows (PowerShell as administrator):
In Docker, see below.
Docker¶
In the quick start (deploy/docker/docker-compose.yml), signalith.yaml is
mounted read-only, and the page keeps its changes in the signalith-data volume.
- The page's file is
/var/lib/signalith/lookups/settings.yaml, in thesignalith-datavolume with Signalith's own certificate authority (tls) and master key (keys), so changes survive updates anddocker compose down. - Only settings set in the compose file's
environment:are locked on the page. In the quick start that is the public address, once you uncommentSIGNALITH_PUBLIC_URL, and the OpenSearch password or the AI model's API key if you add aSIGNALITH_..._FILEvariable for one (the admin password and ingest token it reads from files are not page settings). Change them indocker-compose.yml, thendocker compose -f deploy/docker/docker-compose.yml up -d. - The listen address, the OpenSearch connection and the other settings come from
the read-only
deploy/docker/signalith.yaml, so they can be changed on the page, and the page's value wins. Change the OpenSearch settings only if you run OpenSearch somewhere else: the quick start's own OpenSearch is set up for the client certificate insignalith.yaml. - A port Signalith listens on inside the container only reaches it when the
compose file publishes it under
ports:. The quick start publishes 8080 (web), 514 to the container's 5514 (syslog over UDP and TCP) and 6514 (syslog over TLS). If you change the listen port or a syslog address on the page, add the port toports:too (and for syslog set Port devices send to to the port on the host). The page reminds you on those settings when it runs in a container. - To undo a change from the command line:
docker compose -f deploy/docker/docker-compose.yml exec signalith signalith settings list
docker compose -f deploy/docker/docker-compose.yml exec signalith signalith settings reset server.listen
docker compose -f deploy/docker/docker-compose.yml restart signalith
Passwords and API keys¶
The OpenSearch password and the AI assistant's API key are never shown or sent back to the browser; the page only says whether one is set.
- One saved on the page shows as Saved encrypted, hidden, and one from
signalith.yamlas Saved, hidden. Replace opens a box to type a new one (Keep saved closes it again), and Remove removes it when you save. - One saved on the page that cannot be decrypted (the master key it was saved with is not there) is not used: its field says so, with what to do. Enter it again, or restore that master key. When OpenSearch refuses Signalith without it, a restart says why and sets none of the page's settings aside.
- A password is only ever sent to the address it was entered for (its scheme, host
and port). To point Signalith at another OpenSearch or AI provider, enter the
password or key again, or clear it; the page refuses to save otherwise. A password
from
signalith.yamlor the environment is likewise only sent to the address set there. - An address with a user name and password in it (
http://user:pass@host) or a key in its query is refused on the page: put them in their own fields. One that comes fromsignalith.yamlis shown, logged and exported without it.
Test connection checks OpenSearch with the values on the form, saved or not, and says plainly what is wrong: nothing answers, wrong password, a certificate that is not trusted, HTTP on an HTTPS port, or not an OpenSearch at all. It also says when the problem is OpenSearch itself, so that no setting here would fix it: its security settings aren't loaded, it is too busy, or it took the request but didn't answer in time. When this server can't use OpenSearch says what to do about each. Test for the AI assistant asks the model one fixed question ("failed logins in the last 24 hours") and shows the query it wrote. A result is marked out of date as soon as one of the settings it used changes.
Exporting settings¶
Download settings as YAML, in About this server, downloads the page's
settings in the format of signalith.yaml, for a second server or a backup.
Passwords and keys are left out, and settings that belong to this server only (its
addresses and certificate files) are marked. A public address worked out from the
listen address is left empty, so the other server works out its own.
About this server also shows the version, platform and how long Signalith has been running, where its files and folders are, and Reset all, which takes every change off the page.
Not on this page¶
| Setting | Where instead |
|---|---|
retention.days |
The data retention page. |
auth.admin_user, auth.admin_password_hash |
signalith.yaml and signalith passwd only: the built-in admin is the break-glass account, so no page can lock everyone out. |
auth.ldap |
The Users page sets up directory sign-in. |
auth.users_file, intel.feeds_file, notify.file, playbooks.file, detections.dir, dashboards.dir, lookups.dir |
signalith.yaml: pages save into these files and folders, and the lookups folder holds the Settings page's own file. The page shows where they are. |
ingest.tokens |
Shared agent tokens from older setups and the Docker quick start: signalith.yaml (ingest.tokens) or SIGNALITH_INGEST_TOKEN (SIGNALITH_INGEST_TOKEN_FILE in Docker). New agents get their own token on Add data, under Agent tokens, where shared tokens can also be retired; see agent-tokens.md. The page shows how many tokens are active and how many shared tokens are still accepted. |
intel.feeds |
The Threat intel page. |
Audit log¶
Every save, test and restart is logged with audit=true, who did it and from which
address. Values of settings are logged; passwords and keys never are (they show as
(changed) or (none)).
| Message | Fields |
|---|---|
settings saved |
by, client, changes (key=value pairs), reset, cleared, retried, reset_all, applied_now, after_restart, file, backup |
settings tested |
by, client, what (opensearch or assistant), the address, ok |
restart requested |
by, client, pending, local_only |
restarted with the saved settings |
by, client, settings, took_ms |
restart failed |
by, client, settings, rolled_back, set_aside, reason |
new web address confirmed |
by, client, host |
went back to the previous web address |
settings, reason |
Addresses are logged without any password in them.
level=INFO msg="settings saved" audit=true by=ann client=10.0.0.12 changes="opensearch.index_prefix=siem2 opensearch.password=(changed) search.max_events=5000" applied_now=search.max_events after_restart=opensearch.password,opensearch.index_prefix
level=ERROR msg="restart failed" audit=true by=ann client=10.0.0.12 settings=server.listen rolled_back=false reason="Signalith cannot listen on 0.0.0.0:443 (bind: permission denied). Signalith kept running with the previous settings. Choose another address or port."
API¶
Every route is for admins. Requests from a browser that change something must come from the Signalith page itself.
| Route | What it does |
|---|---|
GET /api/settings |
Every setting by section, with its value, source, whether it is locked, applies at once or after a restart, and is waiting for one; what is waiting; the last restart; paths and version |
PUT /api/settings |
Saves changes: {"values": {key: value}, "clear": [keys], "reset": [keys], "retry": [keys], "reset_all": false}. With "check_only": true it saves nothing and answers {"ok": true, "changed": [...], "confirm": [...]}: what to ask before saving |
POST /api/settings/test/opensearch |
Tests OpenSearch with {"values": {...}} over the saved settings; one test at a time (429 busy otherwise) |
POST /api/settings/test/assistant |
Tests the AI assistant the same way |
POST /api/settings/restart |
Restarts with the saved settings; answers 202 at once. 409 with code restarting, awaiting (a move waits for confirmation), settings_invalid, or local_only (send {"local_only": true} to go ahead) |
POST /api/settings/restart/confirm |
From the new address after a move: confirms it (GET /api/me by an admin does too) |
GET /api/settings/export |
{"yaml": "...", "filename": "signalith-settings.yaml"}; ?download=1 downloads the file |
One setting in GET /api/settings:
{"key": "opensearch.password", "label": "Password", "type": "secret",
"help": "Only sent to the address it was entered for.",
"value": null, "set": true, "sent_to": "https://opensearch.corp.example:9200",
"source": {"kind": "page", "by": "ann", "at": "2026-10-12T18:57:24Z"},
"env": "SIGNALITH_OPENSEARCH_PASSWORD", "locked": false,
"apply": "restart", "dangerous": false, "pending": true,
"reset_to": {"value": null, "set": false, "source": "default"}}
A save with problems saves nothing and answers 400 with each problem by setting:
{"error": "Nothing was saved. Fix the settings marked below.",
"fields": {"server.listen": "Must be host:port, for example 0.0.0.0:8080",
"server.tls_cert": "Enter the full path of your certificate file."},
"problems": []}
A restart answers at once, then GET /api/settings shows how it went under
restart.last:
{"restarting": true, "pending": ["server.listen"], "listen_changed": true,
"new_listen": "0.0.0.0:9443", "go_to": "https://siem.corp.example:9443/"}
{"available": true, "in_progress": false, "needed": true,
"last": {"at": "2026-10-12T18:54:45Z", "by": "ann", "ok": false, "keys": ["opensearch.url"],
"error": "OpenSearch did not answer with the new settings: Nothing answered at 10.0.0.9:9200. Check that OpenSearch is running, and the address and port. Signalith kept running with the previous settings.",
"took_ms": 1}}
While the components are being switched, a request that waits more than 30 seconds
is answered 503 with {"code": "restarting"} and Retry-After: 5.