1.7.0 — MojoSec host sensor, and nodes that fetch their own releases
2026-08-09
Adds MojoSec — a settings-free host sensor for dedicated EC2 nodes that turns journald, nginx and file-integrity signals into bounded batches for the incident system. Edge nodes now fetch promoted web app releases from S3 themselves, verified per file. Also fixes a bug that made every edge converge fail on a standard Linux node.
Breaking
- Release manifests are capped at 1 GiB total (
EDGE_RELEASE_MAX_BYTES). A larger bundle is refused at registration; a file-count cap alone did not bound bytes, and every node fetches a release onto its own disk.
Added
- MojoSec host sensor (
mojo.mojosec) — reads a deliberately narrow signal set (SSH logins and failures, sudo, PAM sessions, systemd/kernel and OOM activity, exploit-path probes, 401/403 denials, 5xx, targeted file integrity), aggregates it, and delivers bounded batches. It never bans an address locally — the incident system stays the policy and enforcement authority. Sudo arguments are never persisted. POST /api/incident/mojosec/batch— machine-facing gzip receiver on the strictmojosec.batchv1 contract, with a durable handler outbox and replay.- New permission
mojosec_ingest. Each installation authenticates with its own API key carrying a protected profile that must name the same sensor. - Operator-only learning loop: append-only detector feedback and offline policy evaluation, global permissions only, API keys rejected.
- Edge nodes fetch promoted release bytes from S3 themselves, verified per file against the manifest, incremental, using the instance role.
- A web app's vhost may sit on a domain owned by its group or an ancestor, so one domain and one wildcard certificate can carry several teams.
- New settings:
MOJOSEC_RECEIPT_RETENTION_DAYS,MOJOSEC_LEARNING_EVALUATION_RETENTION_DAYS,EDGE_RELEASE_FETCH_TIMEOUT,EDGE_RELEASE_FETCH_BUDGET,EDGE_RELEASE_MAX_BYTES.EDGE_KEEP_RELEASESis now enforced.
Changed
- An unfetchable web app release degrades that vhost only — it keeps serving its previous release, or goes dark if it never served — instead of aborting the whole install. The converge retries until it heals.
Fixed
- The staged nginx pre-filter failed on every standard Linux node.
nginx -tbinds every listen it parses, and an unprivileged process gets EACCES on 443/80, which is fatal — so every converge died at the pre-filter and reverted. It passed development only because macOS allows unprivileged low-port binds. The pre-filter now validates a listen-remapped staging tree. - Certificate-material failures are retried on the next converge instead of leaving the vhost excluded until something unrelated moved.
- Generation pruning no longer fails a job whose install had succeeded.
Security
- Models carrying an AI-denial policy are refused by generic model-query tools and cannot be attached to assistant context.
- All MojoSec learning models are denied to AI/model-query tools.
Upgrade notes
- MojoSec is opt-in and inert until enrolled: it needs a per-installation API key, a root service install, and its own config file. See the sensor documentation and the enrollment/canary runbook.
- The staged-nginx fix introduces
EDGE_STAGED_HTTP_PORTandEDGE_STAGED_HTTPS_PORT(61080/61443). Make sure nothing else on the node uses them.