Outcall
SpecificationsS009 · Dynamic Rules

S009 · Dynamic Rules

Specification module 009-dynamic-rules

S009: Dynamic Rules

FieldValue
SpecS009
FeatureDynamic Rules
Date2026-04-22
StatusImplemented
Author@marktopper

Overview

Dynamic rules allow outcalld to insert and remove per-container or per-network nftables rules at runtime, without restarting the daemon or reloading the full ruleset. This is the enforcement mechanism that translates rule engine verdicts (S003) into actual packet filtering decisions at the bridge level (S001).

The base nftables ruleset (S001) blocks everything by default. Dynamic rules punch holes — allowing specific traffic flows for specific containers based on the loaded policy. When a container is stopped or a rule is revoked, the corresponding nftables rules are removed and traffic is blocked again.

User Scenarios

S009-US-001 [P1] As outcalld, I want to insert nftables allow rules when the rule engine grants a verdict, so that approved traffic can flow through the bridge.

S009-US-002 [P1] As outcalld, I want to remove nftables rules when a container is stopped or a rule is revoked, so that traffic is re-blocked immediately.

S009-US-003 [P2] As a host operator, I want to list active dynamic rules so that I can see what traffic is currently allowed.

Requirements Summary

IDTypePriorityTitleStatus
S009-FR-001FunctionalP1Insert allow rules via nftablesImplemented
S009-FR-002FunctionalP1Remove rules on revocation or expiryImplemented
S009-FR-003FunctionalP1Rule keyed to container + destinationImplemented
S009-FR-004FunctionalP1Remove all rules on container stopImplemented
S009-FR-005FunctionalP1Base rules untouchedImplemented
S009-FR-006FunctionalP2List active dynamic rulesImplemented
S009-FR-007FunctionalP1Rule handle trackingImplemented
S009-FR-008FunctionalP1Atomic insert/removeImplemented
S009-FR-009FunctionalP2Flush all dynamic rulesImplemented
S009-FR-010FunctionalP1No dynamic rules survive daemon restartImplemented
S009-FR-011FunctionalP1Default-BLOCK inheritanceImplemented
S009-FR-012FunctionalP1Managed source-IP identityImplemented
S009-FR-013FunctionalP1Typed inputs and bounded operationsImplemented
S009-FR-014FunctionalP1Failed deletion restores base policyImplemented
S009-FR-015FunctionalP1Bounded temporary-rule expirationImplemented
S009-FR-016FunctionalP1Source-aware duplicate renewalImplemented
S009-AS-001AcceptanceP1Allow rule inserted, traffic flowsDraft
S009-AS-002AcceptanceP1Rule removed, traffic re-blockedDraft
S009-AS-003AcceptanceP1Container stopped, all its rules removedDraft
S009-AS-004AcceptanceP2List shows active rulesDraft
S009-AS-005AcceptanceP1Base drop rules still apply to unmatched trafficDraft
S009-AS-006AcceptanceP1Failed deletion restores deny policyImplemented
S009-AS-007AcceptanceP1Temporary rule expiresImplemented
S009-IF-001InterfaceP2GET /api/v1/rules/activeImplemented
S009-IF-002InterfaceP2POST /api/v1/rules/flushImplemented
S009-IF-003InterfaceP1POST /api/v1/rule/allowImplemented
S009-EC-001Edge CaseP1nft insert failsImplemented
S009-EC-002Edge CaseP1Stale rule for stopped containerImplemented
S009-EC-003Edge CaseP2Duplicate rule insertImplemented
S009-EC-004Edge CaseP1Daemon crash with rules activeImplemented
S009-EC-005Edge CaseP1Malformed dynamic rule inputImplemented
S009-EC-006Edge CaseP1Bounded nft and DNS operationsImplemented
S009-EC-007Edge CaseP1Invalid temporary-rule expiryImplemented
S009-EC-008Edge CaseP1Partial expiry cleanup failureImplemented
S009-SC-001SuccessP1E2E: dynamic allow lets traffic throughDraft
S009-SC-002SuccessP1E2E: rule removal re-blocks trafficDraft
S009-SC-003SuccessP1No leaked rules after container stopDraft

Cross-Spec Dependencies

  • Depends on: S001 (nftables base ruleset)
  • Depends on: S003 (verdicts trigger rule insertion)
  • Required by: S008

On this page