Security page; nginx/CSRF/envsubst gotchas
New Security page. The wiki had no security coverage at all, which is a gap
now that the project is public and pullable: a hardening checklist for anyone
moving past a local lab, the security-relevant settings, the CSP trade-off,
and the review history.
The settings needed a home in particular. IRIS_CORS_ALLOWED_ORIGINS appeared
only in a changelog row, and the three analytics variables were documented
nowhere in the wiki despite shipping in August. Both are the kind of setting
someone reaches for while debugging something unrelated, so each says plainly
when NOT to set it -- CORS is a browser policy and does nothing for n8n, API
clients or LLM backends, and the analytics variables silently disable each
other unless all three agree on the host.
Development Guide: the add_header/always rule (both nginx conf files are live,
editing one is half a fix), validate_on_submit versus hand-rolling
is_submitted() + validate(), and the envsubst allowlist being wrong in both
directions -- a missing variable emits a literal ${VAR} into the CSP, an extra
one is CERT_DIR, which nginx never reads.
Corrects a contradiction: the Development Guide said not to open a public issue
for a vulnerability, while the SECURITY.md it linked to says to report by
creating one. It now points at the Security page. The repository file still
carries upstream's text and needs the maintainer's decision on a private
channel.
Getting Started links to the checklist from First login.
TLS certificates page; IRIS-NG-v1.2.0
New TLS Certificates page covering bring-your-own certificates: how CERT_DIR,
CERT_FILENAME and KEY_FILENAME resolve, the Let's Encrypt case, and the two
failure modes worth documenting because neither is guessable from the symptom
alone -- mounting live/<domain> without archive/, which leaves the symlinks
dangling inside the container while ls shows the file present on the host, and
a private key that root owns 0700 and the container's www-data cannot read.
Renewal not reloading nginx is included for the same reason: the site keeps
serving the expired certificate and nothing reports it.
Changelog: IRIS-NG-v1.2.0. Also records that v1.1.0 was never released -- the
note previously named only v1.0.3, though both were staged on main and neither
was ever tagged.
Kubernetes: chart 0.6.0, appVersion IRIS-NG-v1.2.0, pull examples retargeted.
Getting Started: link to the new page, and correct the cert-missing symptom --
nginx now preflights and names the resolved path and the variable behind it
rather than emitting a raw SSL error.
Correlation scoring rewrite, AI troubleshooting, dependency policy
Changelog: adds IRIS-NG-v1.0.2, and IRIS-NG-v1.1.0 marked pending release.
Records that IRIS-NG-v1.0.3 was never released — the version was staged on
main but no tag, release or images were produced, so nothing shipped under
that number and its changes land in v1.1.0.
IOC Correlation: the scoring sections described algorithms that no longer
match the code, and the how-it-works step repeated a misconception the
control's own label encouraged — that "Min shared IOCs" counts cases an
indicator appears in. It counts indicators a case PAIR must share. Rewritten
to state that plainly, with the consequence spelled out: an indicator's fate
is decided by its neighbours, not by itself, so two indicators each present
in exactly two cases can be treated differently.
Decay and confidence rewritten to match what ships in v1.1.0 — tags scale
the half-life rather than the score, age comes from the most recent sighting,
TLP no longer participates, and confidence weighs rarity and credibility
rather than counting indicators. Flags that figures will read lower than
earlier releases, which is a real change analysts will notice.
AI Features: per-surface timeout table replacing the stale 60-90s note, plus
a Troubleshooting section covering the three failures that are hard to tell
apart — an unrecognised model identifier, a model declining security content,
and a timeout — since before v1.1.0 all three displayed the same JSON parse
error.
New Dependency Policy page: why PostgreSQL, jQuery, Node, marshmallow and the
report generator stack are held back, and how to verify a dependency change.
A green build is not evidence a Python upgrade worked; the pkg_resources case
is the reference example, where the image builds cleanly and the application
dies at startup.
Version scheme IRIS-NG-v1.0.0; document the Sponsor tab and IOC history
Changelog: version-scheme section rewritten for IRIS-NG-v<x.y.z>, stating
plainly that the string is not SemVer-parseable and that 1.0.0 sorts below
every prior release, and that the upstream compatibility range moved to
Settings -> System rather than disappearing. The older +iris-ng.<build> scheme
is kept as a note since those releases are still published. New v1.0.0 row.
Kubernetes: chart 0.3.1 / appVersion IRIS-NG-v1.0.0, image tags repointed to
the IRIS-NG-v1.0.0 images now that they exist, and the "+ becomes -" note
reframed as applying to the older scheme only.
Home: Sponsor tab and IOC history added to the feature list.
Add Kubernetes page with DigitalOcean referral; link from Home and Getting Started
The Helm chart at deploy/kubernetes exists but is inherited from upstream and
is not deployable as committed. The page documents the three gaps rather than
implying a working one-command install:
- no images are published (the ghcr workflows fire only on a v*.*.* tag, and
no container packages currently exist), so users must build and push first
- values.yaml ships literal placeholders (<irisapp_image>, <host_name>, ...)
- the chart has no ai_worker, so AI summary and chat jobs enqueue and are
never consumed -- a silent failure, not an error
Also covers installing, persistence, sizing, and points at Docker Compose on a
single host as the tested path for evaluation. The DigitalOcean link is
disclosed as a referral link at both the wiki and README.
Add Case Notifications page; document the two navigation templates
New page covering the per-case updates bell: what counts as an update, the
durable per-(user, case) read watermark, the 14-day lookback on first sight
of a case, the panel, the three endpoints and the upgrade path.
- Home: Pages table entry and a Notifications section under what's new
- API Reference: Notifications endpoints under Cases
- Development Guide: new gotcha — the header exists twice
(navigation.html for dashboard/manage, navigation_ext.html for case
pages) and both are live, so shared header UI belongs in a partial
included from both
- Changelog: entry for the bell
- Scripts Reference: fix a broken anchor to the post-migration login
failure section (GitHub strips the em-dash, leaving two hyphens
from the two spaces, not four)
Add MISP Cluster Publishing page; document module config drift fix
New page: MISP Cluster Publishing — the IrisMISPCluster module. Covers
why the trigger is an explicit button rather than a hook, the mapping of
each content type to the MISP structure that models it (narrative to
Event Report, linked notes to analyst Notes on their indicator,
ioc_description to the attribute comment, tags, campaign galaxy), and
why the full typed pair list is used rather than the 20-value display
cap.
Documents the redaction model in full: terms derived on every push from
every client name in the instance plus the cluster's case names, the
stoplist that preserves incident and sector vocabulary (sector language
is the shareable context the narrative prompt deliberately produces),
IOC values never being redacted because a lookalike domain is the
intelligence, and the honest limit — term matching is not named-entity
recognition, so possible_unredacted_names exists to surface what the
heuristics cannot derive.
Development Guide: two new gotchas.
- Module config schemas are frozen at first registration. Adding a
parameter never reached an existing install, and an incomplete stored
entry raised KeyError in is_mod_configured(), surfacing as a 500 on
/manage/modules/list and an opaque DataTables Ajax error with no clue
to the cause. Documents the boot-time reconciliation that now fixes
it, and the complete-entry rule for anyone hand-editing module_config.
- MISP analyst-data returns a misleading 403 for two undocumented shape
requirements: the body must be wrapped as {"Note": {...}}, and
distribution must be 0-3 because analyst data rejects "inherit event".
Home, MISP Integration, IOC Correlation, API Reference and Changelog
updated with the new page, the Push to MISP button and the misp-push
endpoint.
Document manual override of AI summary and cluster narrative
AI Features: new "Manual override" section covering the shared mechanics
- the three case_ai_artifact columns, display_content/is_edited, the
serializer's content vs ai_content split, the HTTP 409 regeneration guard
and why it lives in the endpoint rather than the browser, provenance and
revert, a per-surface comparison table, and a four-step recipe for
extending it to another cached AI surface without a migration.
IOC Correlation: "Correcting a narrative by hand" under the cluster
narrative section, plus a note in the STIX section that edits are
exported - a corrected title becomes campaign.name and corrected prose
becomes campaign.description, with the caveat that the v2 prompt's
entity-name prohibition constrains model output, not text an analyst
types. Corrected the CaseAiArtifact field-name note to mention
display_content.
Development Guide: new gotcha for response_api_error() - its second
positional is `data`, not a status code, and it always emits 400, so
several existing calls that pass 503 are really 400s carrying data:503.
Documents building the body via response() when another status is needed.
API Reference, endpoint tables and Home updated with the four new routes
and the discard_edit parameter.
Brand wiki as Community Edition; fix release table accuracy
Home: new "Community Edition" and "Contributing and support" sections
(LGPL-3.0, no feature gates, no license key or activation, no telemetry,
self-hosted); title and intro updated.
Getting Started: state up front that no registration, activation or
license key is required anywhere in the install.
Development Guide: new "Contributing" section — branch table (`main` is
the PR target; `develop` is retired with unrelated history), pre-PR
checklist covering the roadmap, CODESTYLE, the three-layer rule, ORM
CHECK constraints and deploy verification, plus security-issue routing.
Changelog: version scheme corrected to `+iris-ng.<build>` with a note
explaining the `iris-next` -> `iris-ng` rename and the skipped `.5`.
Added the `v2.5.0-beta.1+iris-ng.6` release. Rows for `iris-next.5`,
`.1` and `.0` relabelled as milestones — only four releases are actually
published, and listing unpublished builds as tagged releases was
misleading.
Add Knowledge Map page; document setuptools/pkg_resources + rolldown window gotchas
- New Knowledge-Map page: the case Graph tab was undocumented. Covers the
four layers and their source tables, event vs direct edge kinds, the
three link tables feeding direct edges, API response shape, and the
three non-obvious behaviours (linked-only nodes, suppressed redundant
direct edges, IOC-centric Notes layer).
- Home: nav row + case-relationships bullet.
- Development Guide: window-exposure escape hatch for ui/src/pages files
that cannot move to ui/public (treeshake:false does not save uncalled
declarations under rolldown); new section on setuptools >= 83 --
pkg_resources removal only surfaces at app boot, so a green docker
build is not validation. Includes the 3-step acceptance bar.
- Scripts Reference: add seed_wayne_demo.py; expand
backfill_ioc_note_links.py with the PYTHONPATH and MSYS_NO_PATHCONV
requirements and the truncated-hash matching limit.
- Changelog: knowledge map, dependency sweep, setuptools shim.
Docs sync: fix Getting Started cert step, strip private Claude integration, add 3 pages
- Getting Started: add required generate_dev_certs.sh step + iris_helper.sh --init
one-shot; correct false "cert generated at container start" claim (certs are
host-generated and bind-mounted read-only); add nginx cert-perms troubleshooting.
- Remove Claude proxy sidecar + per-case Claude memory (not in the public repo):
AI-Features (sidecar/memory sections, backend row, timeout row), Architecture
(claudeProxy/ tree line), Getting Started (service row, port 7440, pointer).
Kept SYNTHESIZER_FAST_MODEL_MAP model routing (real public code).
- New pages: Analyst Time Tracking, Analyst Skills and Teams, Case Export / Import.
- Home: nav rows + at-a-glance links for the three new pages.
Update wiki: sortable inventory, timeline sort, analytics page, User.user gotcha
[ADD] wiki: Evidence-Inventory page + reasoning model, Vite 8, retention policy updates
New page: Evidence-Inventory.md — drive lifecycle, status donut chart, data retention
policy, barcode lookup, auto-link in evidence modal, wipe/rotate workflow, API endpoint
table, 6-touch pattern for new drive fields.
Updated pages:
- AI-Features.md: reasoning model support section (Gemma-4 channel format, DeepSeek/Qwen
<think> tags, _last_json_object fallback, max_tokens guidance for reasoning models)
- Development-Guide.md: Vite 8/rolldown 1.1.4 gotcha (import-free JS → ui/public/,
vite-plugin-static-copy >=3.3.0 for Vite 8)
- Changelog.md: iris-next.5 entry (status donut chart + data retention policy)
- Home.md: Evidence Inventory page link in table, Dashboard + Settings bullet updates
Add initial wiki (11 pages)