Skip to content

feat(control-api): TTL / auto-expiry for dynamically-added denies - #302

Merged
ErenAri merged 1 commit into
mainfrom
feat/control-api-ttl
Aug 11, 2026
Merged

feat(control-api): TTL / auto-expiry for dynamically-added denies#302
ErenAri merged 1 commit into
mainfrom
feat/control-api-ttl

Conversation

@ErenAri

@ErenAri ErenAri commented Aug 11, 2026

Copy link
Copy Markdown
Owner

What & why

Closes the standing safety gap in automated response: a deny installed over the control API (POST /block/add, /network/deny/*) had no way to expire, so a transient signal — e.g. a Falco detection relayed by aegis-responder — could wedge a path or IP permanently until an operator cleared it. This was the responder's own #1 roadmap item.

How

Any add verb now accepts an optional trailing ttl=<seconds> token:

POST /block/add /usr/bin/suspicious ttl=300   -> {"status":"ok","ttl":300}
POST /network/deny/ip 203.0.113.7 ttl=600     -> {"status":"ok","ttl":600}
  • src/ttl_registry.{hpp,cpp} — kernel-free parse/partition/persistence for a timed-deny registry at /var/lib/aegisbpf/deny_ttl.db (<expiry-epoch> <verb> <arg>). Because a path may contain spaces, only the final token is treated as a ttl= marker; malformed markers (ttl=, ttl=abc, ttl=0) are left as part of the path (deny stays permanent).
  • src/daemon.cpp — the control callback parses the ttl, maintains the registry after the enforcement op succeeds, and a dedicated reaper thread (5 s granularity, started with the control API, joined on shutdown) re-issues the same CLI del command for expired entries. A mutex serializes registry read-modify-write between the socket thread and the reaper. Expiry is wall-clock so it survives a daemon restart; a backwards clock step only delays reaping.
  • Semantics: re-add with a new TTL extends it; re-add with no TTL makes the deny permanent again; POST /block/del / /block/clear drop the timer.
  • aegis-responder — per-rule ttl_seconds (config) forwarded as the ttl= token via decide/sendControl.

Tests

  • tests/test_ttl_registry.cpp — 11-case GTest (parse incl. paths-with-spaces + malformed rejection, partition, upsert/remove-by-verb, db round-trip, reap invokes del + persists survivors).
  • Go: TestDecide_PassesTTL, TestSendControl_AppendsTTL (+ existing suite updated for the new signatures). go vet + go test -race clean.
  • Local: aegisbpf + aegisbpf_test build clean; TTL + SocketApi suites 16/16; new files clang-format clean.

Docs

docs/CONTROL_API.md (new "Auto-expiry (TTL)" section), responder README/config.example.json/DaemonSet, CHANGELOG.

🤖 Generated with Claude Code

Copilot AI lite review requested due to automatic review settings August 11, 2026 12:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Any control-API add verb now accepts an optional trailing `ttl=<seconds>`
token; the deny is removed automatically when it expires, so a transient
signal (e.g. a Falco detection relayed by aegis-responder) can no longer
wedge a path or IP permanently.

- src/ttl_registry.{hpp,cpp}: kernel-free parse/partition/persistence
  helpers for a timed-deny registry (/var/lib/aegisbpf/deny_ttl.db).
- src/daemon.cpp: parse ttl in the control callback, maintain the registry
  after a successful op, and run a reaper thread (5s granularity) that
  re-issues the CLI del command for expired entries. A mutex serializes
  registry read-modify-write between the socket thread and the reaper.
  Wall-clock expiry survives restart; re-add extends, re-add-without-ttl
  makes permanent, del/clear drop the timer.
- aegis-responder: per-rule `ttl_seconds` forwarded as the `ttl=` token
  (decide/sendControl), with Go tests for passthrough + wire format.
- tests/test_ttl_registry.cpp: 11-case GTest suite (parse, partition,
  upsert/remove, db round-trip with spaces, reap).
- docs/CONTROL_API.md, responder README/config/DaemonSet, CHANGELOG.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@ErenAri
ErenAri force-pushed the feat/control-api-ttl branch from 5d28e4f to 7f026be Compare August 11, 2026 12:42
@ErenAri
ErenAri merged commit f794769 into main Aug 11, 2026
55 checks passed
@ErenAri
ErenAri deleted the feat/control-api-ttl branch August 11, 2026 13:12
@ErenAri ErenAri mentioned this pull request Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants