404 lines
22 KiB
Plaintext
404 lines
22 KiB
Plaintext
# digest-engine configuration template.
|
|
#
|
|
# Copy this to the container host as (for example) /opt/smart-home/digest/digest-engine.env,
|
|
# fill in the real values, and `chmod 600` it. That file is what the compose
|
|
# service loads via env_file; it must never be committed (the repo .gitignore
|
|
# already covers .env / *.env, keeping this in line with the restic-password
|
|
# convention in hosts/container-host/scripts/setup-container-host.sh).
|
|
#
|
|
# Every toggle below is the string "true" or "false", matching the ENABLE_X
|
|
# convention used throughout this repo.
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Run behaviour
|
|
# ---------------------------------------------------------------------------
|
|
# How far back each source looks. Should match the digest cadence (4x/day = 6h).
|
|
DIGEST_LOOKBACK_HOURS=6
|
|
DIGEST_OUTPUT_DIR=/output
|
|
LOG_LEVEL=INFO
|
|
|
|
# Which slot a run belongs to is derived from the container's local wall clock —
|
|
# it is NOT passed in by systemd, because the timer runs a bare
|
|
# `docker compose run --rm digest-engine` and a manual run is the same command.
|
|
# Keep DIGEST_SCHEDULE in step with DIGEST_SCHEDULE in
|
|
# hosts/container-host/scripts/setup-container-host.sh, which is what actually
|
|
# sets the timer's OnCalendar.
|
|
DIGEST_SCHEDULE=00,06,12,18
|
|
# The "I'm done working" slot. Only this run gets the recipe + shopping-list
|
|
# suggestion in the household section; the other three omit it entirely. Must be
|
|
# one of the DIGEST_SCHEDULE hours or no run will ever qualify.
|
|
DIGEST_EVENING_HOUR=18
|
|
# Testing override — makes any run behave as the evening run, so the recipe
|
|
# feature can be checked without waiting for 18:00. Leave false in production.
|
|
DIGEST_FORCE_EVENING=false
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Who wants which digest — read from identity (Phase 6) at the start of a run.
|
|
# Each person ticks their sections (network / household / social / political) in
|
|
# identity's admin panel; this run generates the union of what the household
|
|
# asked for, and a section nobody wants costs no LLM call and no ingestion.
|
|
#
|
|
# Leave IDENTITY_URL blank to skip the lookup entirely and always generate all
|
|
# four — which is also what happens if identity is unreachable or the token is
|
|
# wrong. Failing that way round is deliberate: one unreachable container must
|
|
# never silently cost the household its whole digest. See preferences.py.
|
|
#
|
|
# identity is on the same compose network, so the container name resolves; the
|
|
# port is `ports.identity` in CoreSystemConfig.json (8097 by default). The token
|
|
# is the SAME value as identity.env's IDENTITY_TOKEN (`secrets.identity_token`
|
|
# in CoreSystemConfig.json) — it is a shared secret between the two, exactly
|
|
# like the one the door panel and kitchen display are built with.
|
|
# ---------------------------------------------------------------------------
|
|
IDENTITY_URL=http://identity:8097
|
|
IDENTITY_TOKEN=
|
|
IDENTITY_TIMEOUT=10
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# "Your digest is ready" — a push to the self-hosted ntfy this stack already runs
|
|
# for chores and identity (notify.py). Costs no extra LLM call: the summary is
|
|
# assembled from each section's own compact narration, plus the political to-do
|
|
# count and any withheld/unverified marks, so it can never claim something the
|
|
# digest itself doesn't say.
|
|
#
|
|
# WHO GETS WHAT: people are grouped by their own ntfy topic from identity (the
|
|
# same one arrival notifications use), and each topic gets only the sections the
|
|
# people behind it actually asked for — a person who switched the political
|
|
# section off gets no political content on their phone either. NTFY_TOPIC is the
|
|
# household fallback for anyone with no topic of their own, and the single
|
|
# destination when identity is unreachable.
|
|
#
|
|
# On Android the notification relays to a Pebble or any other watch with nothing
|
|
# else installed. ntfy stays LAN-only; away from home it is reached over the
|
|
# WireGuard split tunnel (docs/network-integration.md §2.2), never a port forward.
|
|
#
|
|
# DIGEST_WEB_URL makes the notification tappable, opening that person's own
|
|
# digest. Leave it blank for a push with no link.
|
|
# ---------------------------------------------------------------------------
|
|
ENABLE_DIGEST_NOTIFY=true
|
|
NTFY_URL=http://ntfy
|
|
NTFY_TOPIC=digest
|
|
DIGEST_WEB_URL=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# The archive — the digest's long memory (archive.py). Every ingested item and
|
|
# every measured number is kept in a SQLite database in the same /data volume,
|
|
# so a run can say "up from 5.1% in June", "this signature has fired every night
|
|
# for a week", or "this story first appeared on Monday" instead of only ever
|
|
# seeing the last six hours.
|
|
#
|
|
# READ THIS BEFORE LEAVING IT ON: it persists your mail, messages and calendar
|
|
# entries for the whole retention window, where previously only the last few
|
|
# runs' context.json did. Nothing leaves the host, and the file sits next to the
|
|
# Telegram session on the same volume — but it is a real change in how long
|
|
# personal content is kept. DIGEST_ARCHIVE_EXCLUDE_SOURCES takes a comma-
|
|
# separated list of ingest keys (email, signal, telegram, discord, whatsapp,
|
|
# news, rci_social, calendar, grocy) to keep out of it entirely; the trend
|
|
# features for financial, traffic and IDS data work regardless of what you
|
|
# exclude here.
|
|
# ---------------------------------------------------------------------------
|
|
ENABLE_DIGEST_ARCHIVE=true
|
|
DIGEST_ARCHIVE_DB_PATH=/data/digest-archive.db
|
|
DIGEST_ARCHIVE_RETENTION_DAYS=400
|
|
DIGEST_ARCHIVE_EXCLUDE_SOURCES=
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Meeting agendas (agenda.py) — a "Tagesordnung" PDF arriving by mail or
|
|
# WhatsApp is attached to the calendar event it belongs to. Comma-separated
|
|
# keywords matched case-insensitively in a file name, subject or message; the
|
|
# bare abbreviations TO and TOP are always recognised too, but only as
|
|
# standalone tokens in a file name or subject (matching "to" in body text would
|
|
# flag half your mail). The document itself is never opened — only its name.
|
|
# ---------------------------------------------------------------------------
|
|
AGENDA_KEYWORDS=tagesordnung,traktanden,traktandenliste,agenda,einladung
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# LLM synthesis — the existing Phase 3 Ollama host
|
|
# ---------------------------------------------------------------------------
|
|
OLLAMA_HOST=http://llm-host:11434
|
|
OLLAMA_MODEL=qwen2.5:14b-instruct
|
|
OLLAMA_TIMEOUT=600
|
|
OLLAMA_TEMPERATURE=0.4
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Counter run — the final hallucination filter, see synth/counter_run.py.
|
|
# Runs against OLLAMA_HOST/OLLAMA_TIMEOUT above unless overridden here.
|
|
# ---------------------------------------------------------------------------
|
|
# Leave unset to verify with the same model that generated the digest.
|
|
# Set this if you want verification done by a second, larger/different model.
|
|
COUNTER_RUN_MODEL=
|
|
# Lower than OLLAMA_TEMPERATURE on purpose: verification should be as
|
|
# deterministic as the model allows, not creative.
|
|
COUNTER_RUN_TEMPERATURE=0.1
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# "Was the last digest viewed?" — see viewed_tracker.py. Same Mosquitto broker
|
|
# every HA/thinclient-agent already uses; digest-engine only ever subscribes,
|
|
# never publishes, to the smarthome/digest/viewed topic. Defaults assume the
|
|
# same-Docker-network reachability every other container-host service relies on.
|
|
# ---------------------------------------------------------------------------
|
|
MQTT_BROKER_HOST=mosquitto
|
|
MQTT_BROKER_PORT=1883
|
|
MQTT_USERNAME=
|
|
MQTT_PASSWORD=
|
|
# How long to wait for a retained message before giving up and assuming "viewed"
|
|
# (the safe default — see viewed_tracker.last_viewed_at()'s docstring).
|
|
MQTT_VIEWED_WAIT_SECONDS=3
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Ingestion toggles — every source is off until you have provisioned its
|
|
# credentials. A disabled or misconfigured source logs a warning and contributes
|
|
# nothing; it never fails the run.
|
|
# ---------------------------------------------------------------------------
|
|
ENABLE_EMAIL_INGEST=false
|
|
ENABLE_SIGNAL_INGEST=false
|
|
ENABLE_TELEGRAM_INGEST=false
|
|
ENABLE_DISCORD_INGEST=false
|
|
# Off by default — read digest-engine/README.md before enabling, real ban risk
|
|
# even with the headful-Chromium mitigation. Use a secondary/non-critical number.
|
|
ENABLE_WHATSAPP_INGEST=false
|
|
ENABLE_NEWS_INGEST=true
|
|
# How many entries each feed in curated-feeds.opml may contribute to one prompt.
|
|
# That file ships around three dozen feeds, so this multiplies: 5 x 40 feeds is
|
|
# already a large context for a 14B model. Raise it only with a bigger model.
|
|
NEWS_MAX_ENTRIES_PER_FEED=5
|
|
# The RCI's and your own section's social/media output (YouTube, podcast RSS, a
|
|
# public Telegram channel), listed in feeds/rci-social.json — no credentials
|
|
# needed for the RSS-based ones. Feeds the political section as "theory_social",
|
|
# and new episodes become its watch-later window. Telegram entries reuse the
|
|
# session TELEGRAM_* below already sets up, and are skipped without it.
|
|
ENABLE_RCI_SOCIAL_INGEST=true
|
|
RCI_SOCIAL_CONF_PATH=/app/feeds/rci-social.json
|
|
RCI_SOCIAL_MAX_PER_SOURCE=10
|
|
ENABLE_FINANCIAL_INGEST=true
|
|
# Off by default on purpose — read the OpenSky terms-of-use note further down
|
|
# before turning this on, it is a licensing decision, not a technical one.
|
|
ENABLE_FLIGHT_TRAFFIC_INGEST=false
|
|
# Off by default because it does nothing without AISSTREAM_API_KEY.
|
|
ENABLE_NAVAL_TRAFFIC_INGEST=false
|
|
# Off by default on purpose — this one talks to your firewall. Read the OPNsense
|
|
# section at the bottom of this file and IDSconf.json.example before enabling.
|
|
ENABLE_OPNSENSE_IDS_INGEST=false
|
|
# The two household sources. Off until you have made a Grocy API key and a
|
|
# Nextcloud app password — see their sections below.
|
|
ENABLE_CALDAV_INGEST=false
|
|
ENABLE_GROCY_INGEST=false
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Email (IMAP)
|
|
# ---------------------------------------------------------------------------
|
|
# Auth is an app-specific password, NOT OAuth2. For Gmail: enable 2FA, then
|
|
# generate one at myaccount.google.com -> Security -> App passwords. Other
|
|
# providers have an equivalent. The mailbox is opened read-only, so nothing is
|
|
# ever marked \Seen, archived or deleted.
|
|
EMAIL_IMAP_HOST=imap.gmail.com
|
|
EMAIL_IMAP_PORT=993
|
|
EMAIL_USERNAME=you@example.com
|
|
EMAIL_PASSWORD=
|
|
EMAIL_FOLDER=INBOX
|
|
# Overrides DIGEST_LOOKBACK_HOURS for mail only; leave unset to inherit it.
|
|
#EMAIL_LOOKBACK_HOURS=6
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Signal
|
|
# ---------------------------------------------------------------------------
|
|
# digest-engine does NOT run signal-cli. Add your own signal-cli JSON-RPC daemon
|
|
# as a separate compose service on the same network (linked as a secondary device
|
|
# to your account) and point this at it. See
|
|
# https://github.com/AsamK/signal-cli/blob/master/man/signal-cli-jsonrpc.5.adoc
|
|
SIGNAL_CLI_URL=http://signal-cli:8080
|
|
# Your registered number in E.164 form; only needed if the daemon serves more
|
|
# than one account.
|
|
SIGNAL_ACCOUNT=
|
|
SIGNAL_RECEIVE_TIMEOUT=10
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Telegram (Telethon / MTProto userbot)
|
|
# ---------------------------------------------------------------------------
|
|
# Get the API id/hash from https://my.telegram.org -> API development tools.
|
|
# The session file is created ONCE, interactively:
|
|
# docker compose run --rm --entrypoint python digest-engine ingest/telegram_login.py
|
|
TELEGRAM_API_ID=
|
|
TELEGRAM_API_HASH=
|
|
TELEGRAM_SESSION_PATH=/data/telegram.session
|
|
TELEGRAM_MAX_DIALOGS=25
|
|
TELEGRAM_MAX_MESSAGES_PER_DIALOG=50
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Discord
|
|
# ---------------------------------------------------------------------------
|
|
# A bot token from https://discord.com/developers/applications, with the
|
|
# "Message Content" privileged gateway intent enabled. The bot can only ever see
|
|
# guilds it was invited to — Discord enforces that, not this code.
|
|
DISCORD_BOT_TOKEN=
|
|
DISCORD_MAX_MESSAGES_PER_CHANNEL=50
|
|
DISCORD_TIMEOUT=120
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# WhatsApp (whatsapp-bridge sidecar)
|
|
# ---------------------------------------------------------------------------
|
|
# Path, inside the digest-engine container, of the JSON-lines file the bridge
|
|
# writes. Drained (renamed, read, deleted) once per run.
|
|
WHATSAPP_MESSAGES_PATH=/data/whatsapp-bridge/messages.jsonl
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# News
|
|
# ---------------------------------------------------------------------------
|
|
NEWS_OPML_PATH=/app/feeds/curated-feeds.opml
|
|
NEWS_MAX_ENTRIES_PER_FEED=15
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Financial
|
|
# ---------------------------------------------------------------------------
|
|
# Free FRED API key: https://fred.stlouisfed.org/docs/api/api_key.html
|
|
FRED_API_KEY=
|
|
# Comma-separated FRED series IDs. Default UNRATE = US unemployment rate.
|
|
# Browse more at https://fred.stlouisfed.org (e.g. UNRATE,CPIAUCSL,FEDFUNDS).
|
|
FRED_SERIES=UNRATE
|
|
# Comma-separated Stooq symbols (keyless CSV, no rate cap worth worrying about).
|
|
# ^spx / ^dax / ^ndq = indices, cl.f = WTI crude futures, gc.f = gold,
|
|
# aapl.us style = individual US equities.
|
|
STOOQ_SYMBOLS=^spx,^dax,cl.f
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Air traffic (OpenSky Network)
|
|
# ---------------------------------------------------------------------------
|
|
# Extra evidence for the political section, not a section of its own.
|
|
#
|
|
# LICENSING — decide this before setting ENABLE_FLIGHT_TRAFFIC_INGEST=true.
|
|
# OpenSky's Terms of Use (https://opensky-network.org/about/terms-of-use) license
|
|
# the data for non-profit research/education and personal use, and say that using
|
|
# the REST API "in any operational capacity — including integration into a live
|
|
# product, service, or automated system (even if only internal)" needs a prior
|
|
# written agreement. A timer-driven digest is arguably such a system. Personal,
|
|
# non-commercial household use is the intended case here; if that is not you,
|
|
# mail contact@opensky-network.org first. Attribution to OpenSky is required.
|
|
#
|
|
# RATE LIMITS — a daily credit budget per endpoint. Anonymous (by IP): 400/day,
|
|
# current state only, 10s resolution. With client credentials: 4,000/day, 5s
|
|
# resolution. Running an ADS-B feeder: 8,000/day. A /states/all call costs 1
|
|
# credit for a box <=25 sq deg, 2 for 25-100, 3 for 100-400, 4 for global. The
|
|
# default region list costs ~12 credits/run, ~48/day at 4 runs/day — fine even
|
|
# anonymously, which is why the credentials below are optional.
|
|
#
|
|
# Optional. Create an API client at https://opensky-network.org/my-opensky (the
|
|
# account page). Username/password basic auth stopped working on 2026-03-18.
|
|
OPENSKY_CLIENT_ID=
|
|
OPENSKY_CLIENT_SECRET=
|
|
# REVIEW THIS LIST. Semicolon-separated `Name:lamin,lomin,lamax,lomax` boxes in
|
|
# decimal degrees. What ships below is a placeholder set of currently-tense
|
|
# regions, in the same spirit as the placeholder outlets in curated-feeds.opml —
|
|
# conflict zones move and nothing here updates itself. Keep boxes small: cost per
|
|
# call and context size both scale with area.
|
|
FLIGHT_REGIONS=Eastern Mediterranean / Levant:30,32,37,37;Black Sea / Ukraine:44,29,53,41;Persian Gulf / Strait of Hormuz:24,50,30,60;Red Sea / Bab el-Mandeb:12,38,20,45;Taiwan Strait:21,117,27,124;Baltic / Kaliningrad:53,17,60,28
|
|
# Callsign prefixes treated as military. A heuristic that only catches aircraft
|
|
# flying under published national callsigns (REACH/ASCOT/CANFORCE and friends);
|
|
# anything with its transponder off is invisible to ADS-B entirely.
|
|
FLIGHT_MILITARY_CALLSIGN_PREFIXES=RCH,CNV,RRR,CFC,GAF,IAM,FAF,BAF,NAF,PLF,HAF,NATO,SVF
|
|
FLIGHT_MAX_MILITARY_PER_REGION=20
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Naval traffic (aisstream.io)
|
|
# ---------------------------------------------------------------------------
|
|
# Free key, no card, from https://aisstream.io after signing in (GitHub etc.).
|
|
# The service is WebSocket-only and self-describes as beta with no uptime SLA, so
|
|
# a run that returns nothing is normal rather than broken.
|
|
#
|
|
# What this measures: civil merchant traffic through chokepoints. What it does
|
|
# NOT measure: naval force posture. Warships sail with AIS off as a matter of
|
|
# routine and the AIS "military ops" type code is self-declared, so a quiet box
|
|
# here means nothing at all about warships. It is useful for the opposite
|
|
# reading — merchant traffic abandoning a route, which shows up in freight and
|
|
# insurance costs and pairs with the financial indicators above.
|
|
AISSTREAM_API_KEY=
|
|
# Same `Name:lamin,lomin,lamax,lomax` format as FLIGHT_REGIONS.
|
|
NAVAL_REGIONS=Red Sea / Bab el-Mandeb:12,38,20,45;Strait of Hormuz:24,54,28,58;Black Sea:41,27,47,42;Taiwan Strait:21,117,27,124;Suez Canal approaches:29,32,32,34
|
|
# Seconds the socket is held open per run. This is a density sample, not a
|
|
# census; raising it makes a oneshot digest sit on a socket for longer.
|
|
NAVAL_SAMPLE_SECONDS=20
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Household calendar (Nextcloud CalDAV, Phase 8)
|
|
# ---------------------------------------------------------------------------
|
|
# Auth is a Nextcloud APP PASSWORD, not your account password and not OAuth2 —
|
|
# same reasoning as the IMAP section above. Create one at Nextcloud -> Settings ->
|
|
# Security -> Devices & sessions -> Create new app password. It is mandatory once
|
|
# two-factor authentication is enabled (the DAV endpoints cannot prompt for a
|
|
# second factor) and it is revocable on its own if this host is ever compromised.
|
|
#
|
|
# Point CALDAV_URL at the DAV root; the client discovers the principal and its
|
|
# calendars from there. The per-user form
|
|
# https://cloud.example.com/remote.php/dav/principals/users/<username>/ also works.
|
|
#
|
|
# Read-only: this only ever issues CalDAV read requests. It never creates, moves
|
|
# or deletes an event.
|
|
CALDAV_URL=https://cloud.example.com/remote.php/dav
|
|
CALDAV_USERNAME=
|
|
CALDAV_PASSWORD=
|
|
# Comma-separated calendar display names to include. Empty = every calendar the
|
|
# account can see (which includes ones shared with you).
|
|
CALDAV_CALENDARS=
|
|
# The calendar window is asymmetric: DIGEST_LOOKBACK_HOURS backwards (to catch
|
|
# what already happened today and anything still in progress) and this forwards.
|
|
CALDAV_LOOKAHEAD_HOURS=48
|
|
CALDAV_MAX_EVENTS=100
|
|
# Only set false for a self-signed internal cert, and understand that it sends
|
|
# the app password over an unverified session.
|
|
CALDAV_VERIFY_TLS=true
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Kitchen inventory (Grocy, Phase 7)
|
|
# ---------------------------------------------------------------------------
|
|
# GROCY_URL is the container name on the shared compose network — Grocy listens
|
|
# on port 80 inside the container (published to the LAN as 9283, which this does
|
|
# not need to go through). Use http://<host-ip>:9283 only if Grocy runs elsewhere.
|
|
#
|
|
# The API key is per user: Grocy -> Settings -> Manage API keys -> add. Note that
|
|
# a Grocy key is NOT scoped — it carries that user's full read and write rights,
|
|
# so give this one its own Grocy user. The read-only guarantee comes from
|
|
# ingest/grocy.py issuing GETs and nothing else; see the invariant at the top of
|
|
# that file, which also names the write endpoints it deliberately never calls.
|
|
#
|
|
# Nothing in this component ever adds to Grocy's shopping list, consumes stock,
|
|
# executes a chore or charges a battery — including the evening recipe feature,
|
|
# whose shopping list is a suggestion printed in the digest for you to act on.
|
|
GROCY_URL=http://grocy
|
|
GROCY_API_KEY=
|
|
# Days ahead a product counts as "due soon" (Grocy's /stock/volatile default is 5).
|
|
GROCY_DUE_SOON_DAYS=5
|
|
# Days ahead a chore or battery charge is worth mentioning.
|
|
GROCY_TASK_HORIZON_DAYS=7
|
|
# Cap on the in-stock product list, which is only sent on the evening run so the
|
|
# recipe's shopping list can tell "already have it" from "buy it". Raise it if
|
|
# your pantry is bigger than this, or the shopping list will suggest things you
|
|
# already own (a warning is logged when the cap bites).
|
|
GROCY_MAX_STOCK_ITEMS=200
|
|
|
|
# ---------------------------------------------------------------------------
|
|
# Home network intrusion detection (OPNsense + Suricata)
|
|
# ---------------------------------------------------------------------------
|
|
# Feeds a short "is anything wrong with the home network" item into the
|
|
# HOUSEHOLD section. Everything except the toggle and the path below lives in
|
|
# IDSconf.json, because that file carries an API key/secret — copy
|
|
# IDSconf.json.example to the digest data volume, chmod 600 it, and read its
|
|
# _readme keys; they cover creating the OPNsense API key and scoping the user.
|
|
#
|
|
# Suricata is part of OPNsense core (no os-suricata plugin to install), but it
|
|
# is OFF on a stock install — enable it at Services -> Intrusion Detection and
|
|
# download a ruleset first, or every run will honestly report that the IDS was
|
|
# not running.
|
|
#
|
|
# This is a pure pull over HTTPS: GET /api/ids/service/status and POST
|
|
# /api/ids/service/query_alerts (a POST that only reads /var/log/suricata/
|
|
# eve.json), and nothing else, ever. It never starts a packet capture, never
|
|
# reconfigures or restarts Suricata, and never clears an alert log.
|
|
#
|
|
# POSTURE NOTE: the container host and the firewall sit on the same flat LAN —
|
|
# no VLAN segmentation is implemented in this project yet (docs/project-plan.md
|
|
# only plans one for cameras). Scope the OPNsense user to the single "Services:
|
|
# Intrusion Detection" privilege and nothing else. Be aware that OPNsense ACLs
|
|
# are page-level: that privilege still covers the IDS start/stop endpoints, so
|
|
# the read-only guarantee comes from this code, not from the firewall.
|
|
#
|
|
# Path INSIDE the container. /data is the bind-mounted digest data volume.
|
|
OPNSENSE_IDS_CONF_PATH=/data/IDSconf.json
|