Security of DENIS itself

Security and trust

DENIS watches your network, so it has to be trustworthy itself. This page describes its security architecture, how it handles your data, how it was tested and how far, what is experimental, and how to report a vulnerability.

Independent assessmentAn independent penetration test is planned. It has not taken place yet, and nothing on this site should be read as its result. A summary will be published once it is done.

Security architecture

  • Self-hosted, one program. Capture, detection, the web console and the documentation run in one process on a machine you control. There is no DENIS cloud service and no DENIS account.
  • Out of band. DENIS reads a copy of the traffic and is never in the traffic path. On a mirror interface it only listens.
  • Least privilege. On Linux the installer runs it as an unprivileged denis user with only the two packet-capture capabilities, under a hardened service that may write only to its own folders.
  • Remote sites connect out. Collectors open an outbound TLS connection to the console; nothing listens at a remote site.
  • Changes to your network are opt-in. Response actions are off by default and go through one guarded path (see below).

The module-by-module design is in the architecture guide, and the threat model in docs/security.md.

Your data stays where you run DENIS

One local SQLite database. There is no DENIS cloud service and no telemetry. DENIS has no usage reporting: none of these tells anyone how you use it. A default install makes five kinds of outbound request on its own (the update check with its usedenis.com fallback counts as one), each can be switched off, and the one that carries anything about your network is the name lookup of an outside address. From docs/security.md:

Default outbound requests
WhatWhereHow oftenContains network data?Off with
Update checkapi.github.comevery 6 h (with automatic security updates on, also the release list for a new minor line and the download of an eligible release) no --no-update-check (the automatic install alone: Settings → System → Updates)
Update check, fallbackusedenis.com, only when GitHub cannot be reached; on by defaultwith the update check, only while GitHub fails it sees your address and the version asked for, nothing else Settings → System → Updates, or --no-update-check
GeoIP databasedb-ip.commonthly no Settings → Network Intelligence
End-of-support dataendoflife.dateweekly no Settings → Data
Known-exploited vulnerabilitiesCISA, NVD, FIRST (EPSS)weekly no Settings → Data
Reverse DNS of public IPs1.1.1.1 (configurable)as needed the looked-up address Settings → Network Intelligence

Anything else, such as notifications, exports, the abuse.ch and Spamhaus lists or an AI provider, is only contacted if you configure it.

Securing the console

  • HTTPS by default (TLS 1.2/1.3), with a local CA, automatic renewal and your own certificate if you prefer
  • Roles: viewer, editor, admin. Per-site access.
  • Passkeys (WebAuthn) with optional passkey-only sign-in
  • Authenticator apps (TOTP) with recovery codes, which can be required for admins or everyone. Since 4.2 their secrets are stored sealed (AES-256-GCM, with a key kept in a separate file), not in plain form; older plain entries are sealed once at the first start
  • OpenID Connect single sign-on
  • Since 4.3: API tokens with scopes, expiry, rotation and an acts-as mode, and site administrators who manage only their own sites (site-limited accounts can no longer change other sites through imports or new devices). Since 4.4: every customer has its own data key for stored passwords and keys, which can be rotated, together with the master key, while DENIS runs; a passphrase copy of the master key can be kept
  • Argon2id password hashing, lock-out with back-off and per-address throttling
  • No default credentials: a random one-time admin password, changed at first sign-in
  • An audit log of every security-relevant change
  • Strict Content-Security-Policy. The UI never builds HTML from network-supplied strings.

Hardened against hostile traffic

Every wire parser is bounds-checked and fuzz-tested, and protocol decoders verify signatures. DENIS never executes anything received from the network. On Linux it runs as an unprivileged user with only the two packet-capture capabilities.

Signed releases and safe updates

  • Release checksums are signed, and the public key is built into DENIS. Since 4.1.1 the installer, install.sh, is in the signed checksum list too, so it can be checked before it is run as root.
  • An update refuses any file that doesn’t match.
  • The new binary is test-run before anything is replaced.
  • The database is backed up first.
  • If the new version fails to start, the previous one comes back automatically.
  • DENIS checks GitHub for new versions: one anonymous request every six hours, and nothing about your network or data is sent. Updates come from GitHub. Only if GitHub cannot be reached (offline, blocked or rate limited) does DENIS ask usedenis.com instead, with the same checks: every release is verified against the release key built into the program, only newer versions are taken, the connection must be HTTPS, and a redirect to another host is refused. The fallback can be switched off in Settings, or entirely with --no-update-check.
  • Remote agents can be updated from the master’s console. By default nothing happens to an agent: an administrator presses Update for one agent, or Update all outdated. Optionally the master updates its agents by itself, and for sites without internet access the master can hand the verified release to its own agents. An agent always checks the signature of a release itself before installing anything, never installs a version that is not newer than its own, and puts the old version back if the new one does not start. Where an agent cannot replace its own program (for example a read-only program folder, or a platform without a published release) the console shows “manual update needed” with the reason.
  • Since 4.2, security updates install automatically by default on new installations: a signed, stable release of the minor line you run, through the same signature, checksum, backup and rollback steps as a manual update, and never while an enforcement action is running. New minor or major versions wait for an administrator. One setting (Settings → System, administrators only, audited) switches it off, and the console then shows a standing advisory. An installation that existed before 4.2 keeps its behaviour and is asked once.
  • Pre-release versions (release candidates) are offered only to installations where an administrator has switched that on.
  • For your own review: the dependencies are checked every day against the RustSec advisory database, software bills of materials (CycloneDX and SPDX) are produced by the release process, and the documentation has an architecture guide, an API reference and a Cyber Resilience Act readiness document. See the SBOM page for where the files are and what they do not cover.

Remote sites

Remote collectors connect outbound over TLS, pin the console’s CA and authenticate with a per-collector token that can be revoked. Since 4.1.1 the agent install command no longer contains the token: the installer asks for it, so other users of that machine cannot read it from the process list or the shell history.

Enforcement and MSP management

DENIS can change things on your network and can be opened by a service provider. Both are off until an administrator turns them on. Everything that acts by itself is experimental.

  • Enforcement is off by default. Every action is one administrator’s decision, shown in full before it runs and confirmed with the password. Releasing an action does not need the password. Blocking and releasing are separate permissions that an administrator must be granted.
  • Every action goes through one path with a kill switch, an hourly limit and a record of what DENIS changed, and a release removes only what DENIS made. Trunk, EtherChannel, management and CDP-neighbour switch ports are refused.
  • Verified with Cisco Catalyst switches, Palo Alto PAN-OS, FortiGate FortiOS, MikroTik RouterOS, UniFi OS and the TP-Link Omada controller (see which actions and versions). The Cisco Secure Firewall FDM and FMC block was verified in the Cisco DevNet sandbox on virtual devices, and AWS security groups in a lab AWS account. Every other connector, among them MikroTik Wi-Fi, the Cisco Catalyst 9800 wireless controller and Azure, is experimental and acts only after an administrator turns on two lab switches.
  • Since 4.2 the Respond menu offers a switch port or a firewall only when DENIS is sure it is on the device’s path, every plan states what it covers and what it does not, and an action never targets the device DENIS itself runs on. A device that moved is judged on its newest address.
  • Automation (policies and rules that block by themselves, and separately Autopilot) needs the password and a typed confirmation phrase to switch on, one click to switch off, and is never applied to DENIS itself, the gateway, industrial devices or network and server infrastructure. A rule can instead prepare a block for an administrator to approve; letting it act by itself needs a trial of at least 7 days first. Its actions are always time-limited and announced on every notification channel.
  • Experimental connectors (every product not listed as tested on real hardware) act only after an administrator switches on lab use. The supported infrastructure page lists each product, its actions and how far it was tested.
  • MSP management is off until a customer administrator pairs with an MSP, compares its key fingerprint and confirms with the password. The customer’s DENIS connects out, so nothing listens at the customer. The customer chooses the level, sees a banner while the MSP works, can require co-approval and disconnects with one click. Every MSP operator needs an authenticator app or a passkey.

Details: enforcement, Autopilot and MSP management.

Testing status

Four levels, kept apart on purpose. A pass at one level does not count for the next, and a result for one action does not carry over to another.

Real hardware

On real equipment, by the maintainer, as documented

  • Response through Cisco Catalyst 2960-X, Palo Alto PA-220, FortiGate 40F, MikroTik E50UG and UniFi Cloud Gateway Ultra, for the actions and versions on the supported infrastructure page
  • A permanent Linux service, including a real self-update with signature check and rollback
  • ARP-conflict detection on a live network
  • Remote collector and console across a real network
  • The optional AI features against real provider accounts and a local model

Automated and simulation

In DENIS’s own test suite

  • 4,000+ automated unit and integration tests, including negative authorisation tests on every route
  • Every enforcement connector against a simulated device of its vendor’s interface
  • Fuzz tests of every parser
  • Industrial decoders against real captures of each protocol
  • Test environments that are not real equipment: the Cisco Secure Firewall FDM and FMC block in the Cisco DevNet sandbox on virtual devices (29 October 2026), and AWS security groups in a lab AWS account (3 November 2026)
  • A daily dependency check against the RustSec advisory database

Experimental

Off by default; do not rely on it

  • Policies and rules that block by themselves, and Autopilot
  • Every connector not tested on real hardware
  • Mirrors delivered in tunnels (ERSPAN, GRE, VXLAN, Geneve)
  • New in 4.4: TP-Link Omada, MikroTik Wi-Fi and Cisco Catalyst 9800 connectors; two high-availability servers on one PostgreSQL database and customers in PostgreSQL; the own-rule counts and sequences; three of the twelve new detections (name poisoning, industrial)
  • New in 4.3: generic SNMP switch control, the Palo Alto firewall timeout, Meraki client reading; some UniFi wireless client fields are marked unverified

Not yet tested, or planned

Open, and said so

  • An independent penetration test: planned, not done
  • Industrial detections on live plant traffic
  • Imports from cloud, directory and vulnerability tools against real tenants
  • Some deployment options, such as IPv6, passkeys, Docker packet capture and two high-availability nodes on a managed PostgreSQL service
  • DENIS’s use of the Palo Alto firewall’s own timeout (new in 4.3, opt-in; the timeout itself was tried on a PA-220 only as a safety net)
  • Port actions on generic SNMP switches (new in 4.3, Experimental), tested only on simulators
  • PostgreSQL high availability (Experimental in 4.4): tested on PostgreSQL 16 in containers and in a local fault lab, not yet on a managed service or under a long soak; customers on PostgreSQL are Experimental until measured
  • The Not managed view, tested against fixtures, not yet against a real tenant
Independent assessment An independent penetration test is planned. It has not taken place yet, and nothing on this site should be read as its result. A summary will be published once it is done. Full list in the README’s “Security and limitations” →

The EU Cyber Resilience Act

DENIS is developed in the European Union (Slovakia) and is designed to align with the Cyber Resilience Act. It is being prepared for conformity assessment and is not yet assessed. What is in place and what is still to come.

What DENIS does not protect against

The short version of docs/security.md:

  • The database as a whole is not encrypted at rest (only integration credentials and authenticator secrets are sealed); use disk encryption.
  • Anyone who can read the database file is effectively an administrator. The key that seals integration credentials and authenticator secrets must be kept safely and separately from the database backups.
  • An attacker on the network can influence what is displayed, such as names, and can try to evade detection, as with any monitoring tool.
  • Device-type guesses can be spoofed.

Reporting a vulnerability

Please don’t open a public issue. Follow the security policy. The policy commits to:

  • acknowledgement within 3 working days
  • a fix or mitigation plan within 30 days for serious issues
  • coordinated disclosure within 90 days

You can also write to mail@usedenis.com.