Vulnerability Management #
How Deevnet learns about vulnerabilities in what it runs, checks its own code before it reaches a site, and decides when a patch goes in. Parts of this are practice today; parts are planned, and are marked so.
Knowing what is running #
Vulnerability management starts with an inventory, and Deevnet’s is the code: every host, OS image, container image and firmware version is declared in inventory or in an image factory, pinned by version or tag. “Are we affected?” is answered by searching the repositories, not by surveying hosts.
| Layer | Where the version is declared |
|---|---|
| Host OS | the Packer templates in deevnet-image-factory (Fedora, Proxmox VE) |
| Service images | deevnet-container-image-factory, built from source, tagged |
| Deevnet’s own services | release tags (the API, the log bridge, the provider), pinned in the Ansible roles |
| Network firmware | inventory, applied through the controller; each upgrade has a change record |
| Router | the OPNsense release and its bundled services, observed on the router and recorded in change records |
What all of that adds up to, every item with its version, is the Software Catalog, the system of record for versions. Checking it against what is actually running is Discovery.
Tracking advisories Planned #
Today: advisories are picked up manually β vendor release notes when a component is upgraded, and upstream security announcements for the pieces that matter most (OPNsense, Proxmox VE, Fedora, the MQTT broker, OpenBao).
Planned:
- a watched advisory source for every item in the Software Catalog, recorded and watched as Discovery requires
- each relevant advisory assessed against the inventory: affected, not affected, or not applicable β and the answer recorded
- an affected finding treated through the normal cycle: a change record to patch it, or a register entry accepting it
Checking code before production #
| Check | Status |
|---|---|
Secrets never committed in plaintext. A pre-commit hook in the inventory refuses any vault.yml that is not encrypted | In place |
Syntax and validation. ansible-playbook --syntax-check, packer validate, terraform validate before apply | In place (manual) |
| Tests on Deevnet’s own services. The API, provider and log bridge carry unit tests, run before a tag is cut | In place |
| Dependency and image scanning. Go module and container image vulnerability scans before a release is staged | Planned |
| CI. The checks above run automatically on every pull request | Planned |
A service reaches a site only as a tagged, staged artifact β the staging targets refuse a dirty or untagged tree β so what runs is always something that can be traced back to reviewed source.
Evaluating and applying patches #
A patch is a change, and goes through Change Management:
- Read the release notes before the upgrade, and quote them in the change record rather than paraphrasing β vendor behavior described from memory has been wrong before
- Know the way back. Every upgrade record carries its undo: the previous firmware, the data snapshot, the previous tag
- Stage it off the site first where it can be: a throwaway environment, as the change records do before applying
- Verify in the production context, not a convenient one: the check that proves a fix is the one that fails without it
Host patching mechanics β online, offline, and the local mirror decision β are Patching.
Response time by severity Planned #
| Severity | Target | Examples |
|---|---|---|
| Critical, exposed | as soon as a change can be run | remotely exploitable on something reachable from an untrusted segment |
| High | within a week | exploitable from a trusted segment, or needing a credential Deevnet issues |
| Medium / Low | next planned maintenance | local-only, or mitigated by segmentation |
“Exposed” is judged against the security controls: a flaw reachable only from the management network is a different risk from one reachable from the guest Wi-Fi.