Skip to content

santad: persist network flow rules in SNTRuleTable#969

Merged
mlw merged 1 commit into
mainfrom
mlw/network-rules-santad-table
May 26, 2026
Merged

santad: persist network flow rules in SNTRuleTable#969
mlw merged 1 commit into
mainfrom
mlw/network-rules-santad-table

Conversation

@mlw
Copy link
Copy Markdown
Contributor

@mlw mlw commented May 26, 2026

Summary

  • Adds a third sub-table network_flow_rules (migration v12 → v13) holding raw NetworkFlowRule.Add proto blobs keyed by rule_id.
  • Extends addExecutionRules:fileAccessRules:… to also take networkFlowRules:, so all three rule types from a single RuleDownloadResponse apply in one transaction. The 3-arg legacy wrapper is preserved for the compiler/standalone callers.
  • Adds networkFlowRulesHash to SNTRuleTableRulesHash, populated via hashOfHashes. Xxhash128 over the blobs in rule_id ASC order — rule_id is field 1 of the proto so it's not hashed separately.
  • Retrieve and hash loops use indexed-column FMDB access; enterprise blocklists are expected to reach 100k+ rules.

Dependencies

Stacked on #965 (mlw/network-rules-common, currently in review). This PR's base is that branch — please merge #965 first; GitHub will retarget this PR to main automatically. The two are intended to stand independently in review.

XPC delivery to santanetd and the corresponding SNTDaemonControlController entry are out of scope here and will follow in a later PR.

Test plan

  • bazel test //Source/santad:SNTRuleTableTest — 16 new tests covering persist / upsert / remove / remove-nonexistent / CleanAll / CleanNonTransitive / CleanupExecutionRules-preserves / empty-array rejection / network-only non-empty guard / hash stability / hex length / blob sensitivity / order independence / empty-table.
  • bazel test //Source/santad:SNTDaemonControlControllerTest //Source/santad:SNTCompilerControllerTest //Source/santad:SNTExecutionControllerTest — existing tests still pass with the 5-arg signature.
  • bazel build //Source/santad:Santad
  • Testing/check_test_suites.sh clean.

@mlw mlw requested a review from a team as a code owner May 26, 2026 15:14
@github-actions github-actions Bot added comp/santad Issues or PRs related to the daemon lang/objc++ PRs modifying files in ObjC++ size/m Size: medium labels May 26, 2026
@mlw
Copy link
Copy Markdown
Contributor Author

mlw commented May 26, 2026

@coderabbitai full review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

✅ Actions performed

Full review triggered.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 26, 2026

Review Change Stack

📝 Walkthrough

Walkthrough

This PR adds comprehensive support for network flow rules to Santa's rule persistence layer: new public APIs, DB migration (v13) with a network_flow_rules table, deterministic hashing and cache invalidation, transactional write/cleanup integration, bulk retrieval, updated callers/build deps, and extensive tests.

Changes

Network Flow Rules Feature

Layer / File(s) Summary
Public API Contract
Source/santad/DataLayer/SNTRuleTable.h
Header declares networkFlowRulesHash property on SNTRuleTableRulesHash, networkFlowRuleCount and retrieveAllNetworkFlowRules methods on SNTRuleTable, and updates addExecutionRules signature to accept networkFlowRules array parameter.
Schema Migration & Core Operations
Source/santad/DataLayer/SNTRuleTable.mm
Schema version incremented to 13; migration creates network_flow_rules table with rule_id primary key and rule_blob payload; networkFlowRuleCount returns row count from table; addNetworkFlowRules validates rule state and performs insert-or-replace/delete operations.
Hash Computation & Cache Integration
Source/santad/DataLayer/SNTRuleTable.mm
SNTRuleTableRulesHash initializer accepts networkFlowRulesHash parameter; networkFlowRulesHashSerialized computes stable hashes from ordered network_flow_rules blobs; hashOfHashes includes networkFlowRulesHash in aggregate hash object.
Write Path Integration & Cleanup
Source/santad/DataLayer/SNTRuleTable.mm
addExecutionRules accepts networkFlowRules parameter, validates combined non-emptiness of execution/file/network arrays, deletes network_flow_rules during cleanup phases, executes addNetworkFlowRules within transaction, and invalidates networkFlowRulesHash on success.
Bulk Retrieval
Source/santad/DataLayer/SNTRuleTable.mm
retrieveAllNetworkFlowRules queries network_flow_rules ordered by rule_id, deserializes each rule_blob into SNTNetworkFlowRule objects, and returns the complete array.
Test Coverage
Source/santad/DataLayer/SNTRuleTableTest.mm
Imports SNTNetworkFlowRule and updates existing test invocations of addExecutionRules to pass networkFlowRules argument; extends testHashOfHashes to verify networkFlowRulesHash computation and order-independence; adds comprehensive "Network Flow Rules" test section covering add/upsert/remove, cleanup semantics per mode, and hash stability.
Caller Integration & Build
Source/santad/BUILD, Source/santad/SNTDaemonControlController.mm
SNTDaemonControlController.databaseRuleAddExecutionRules: passes networkFlowRules:nil into ruleTable addExecutionRules call; SNTRuleTable and SNTRuleTableTest build targets now depend on //Source/common:SNTNetworkFlowRule.

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs:

  • northpolesec/santa#965: Wires SNTNetworkFlowRule into SNTRuleTable (DB table, hashing, add/retrieve APIs) and updates tests/callers to pass networkFlowRules.
🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: adding persistence for network flow rules to SNTRuleTable, which aligns with the core objective of the changeset.
Description check ✅ Passed The description is comprehensive and directly related to the changeset, covering database migration, method signatures, hashing strategy, test coverage, and dependencies.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mlw/network-rules-santad-table

Comment @coderabbitai help to get the list of available commands and usage tips.

russellhancox
russellhancox previously approved these changes May 26, 2026
Base automatically changed from mlw/network-rules-common to main May 26, 2026 17:17
@mlw mlw dismissed russellhancox’s stale review May 26, 2026 17:17

The base branch was changed.

Adds a third sub-table (network_flow_rules) and extends the combined
addExecutionRules:fileAccessRules:... entry point to accept a
networkFlowRules: parameter so all three rule types apply in a single
transaction (matching how sync delivers them together in
RuleDownloadResponse). networkFlowRulesHash joins
SNTRuleTableRulesHash and is computed via hashOfHashes alongside the
other two.

Storage holds the raw NetworkFlowRule.Add proto blob as received over
the wire; santad does not deserialize or re-serialize it. Hash is
Xxhash128 over the blobs in rule_id ASC order — rule_id is field 1
of the proto so it does not need to be hashed separately.

Retrieve and hash loops use indexed-column FMDB access because
enterprise blocklists are expected to reach 100k+ rules.

XPC delivery to santanetd and the corresponding XPC entry on
SNTDaemonControlController will follow in a later PR.
@mlw mlw force-pushed the mlw/network-rules-santad-table branch from fadb0b7 to f061a8c Compare May 26, 2026 17:22
@mlw mlw requested a review from russellhancox May 26, 2026 17:22
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
Source/santad/DataLayer/SNTRuleTableTest.mm (1)

842-954: ⚡ Quick win

Add a mixed-rule rollback atomicity test.

Coverage is strong for network-flow behavior, but it doesn’t explicitly verify all-or-nothing rollback when a combined execution/file-access/network write fails. Add one failing mixed-input case and assert all three table counts remain unchanged.

Proposed test addition
+ - (void)testAddMixedRulesFailureRollsBackAllTables {
+  SNTRule* validExec = [self _exampleBinaryRule];
+  SNTFileAccessRule* validFAA = [self _exampleFileAccessAddRuleWithName:@"mixed"];
+  SNTNetworkFlowRule* validNF = [self _exampleNetworkFlowAddRuleWithId:500 blob:@"ok"];
+
+  SNTRule* invalidExec = [[SNTRule alloc] init];
+  invalidExec.identifier = @"7ae80b9ab38af0c63a9a81765f434d9a7cd8f720eb6037ef303de39d779bc258";
+  invalidExec.type = SNTRuleTypeCertificate;
+  // Intentionally missing state -> invalid.
+
+  NSArray<NSError*>* errors;
+  XCTAssertFalse([self.sut addExecutionRules:@[ validExec, invalidExec ]
+                             fileAccessRules:@[ validFAA ]
+                            networkFlowRules:@[ validNF ]
+                                 ruleCleanup:SNTRuleCleanupNone
+                                      errors:&errors]);
+  XCTAssertGreaterThan(errors.count, 0u);
+  XCTAssertEqual(self.sut.executionRuleCount, 0);
+  XCTAssertEqual(self.sut.fileAccessRuleCount, 0);
+  XCTAssertEqual(self.sut.networkFlowRuleCount, 0);
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Source/santad/DataLayer/SNTRuleTableTest.mm` around lines 842 - 954, Add a
test that verifies atomic rollback when a mixed add (execution + file-access +
network) fails: use the existing helpers (_exampleBinaryRule,
_exampleFileAccessRuleWithId:, _exampleNetworkFlowAddRuleWithId:) to insert one
of each, arrange inputs so the
addExecutionRules:fileAccessRules:networkFlowRules:ruleCleanup:errors: call
fails (e.g. include an invalid rule to trigger failure), then assert that all
three table counts (e.g. self.sut.executionRuleCount,
self.sut.fileAccessRuleCount, self.sut.networkFlowRuleCount) are unchanged after
the failure; this should mirror existing tests like
testAddNetworkFlowRulesPersists and testAddAllEmptyArraysWithoutCleanupFails and
ensure full rollback atomicity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@Source/santad/DataLayer/SNTRuleTableTest.mm`:
- Around line 842-954: Add a test that verifies atomic rollback when a mixed add
(execution + file-access + network) fails: use the existing helpers
(_exampleBinaryRule, _exampleFileAccessRuleWithId:,
_exampleNetworkFlowAddRuleWithId:) to insert one of each, arrange inputs so the
addExecutionRules:fileAccessRules:networkFlowRules:ruleCleanup:errors: call
fails (e.g. include an invalid rule to trigger failure), then assert that all
three table counts (e.g. self.sut.executionRuleCount,
self.sut.fileAccessRuleCount, self.sut.networkFlowRuleCount) are unchanged after
the failure; this should mirror existing tests like
testAddNetworkFlowRulesPersists and testAddAllEmptyArraysWithoutCleanupFails and
ensure full rollback atomicity.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b42df6bf-a774-4c94-bc3e-4c70d66b06cd

📥 Commits

Reviewing files that changed from the base of the PR and between fadb0b7 and f061a8c.

📒 Files selected for processing (5)
  • Source/santad/BUILD
  • Source/santad/DataLayer/SNTRuleTable.h
  • Source/santad/DataLayer/SNTRuleTable.mm
  • Source/santad/DataLayer/SNTRuleTableTest.mm
  • Source/santad/SNTDaemonControlController.mm

@mlw mlw merged commit 402d5ab into main May 26, 2026
8 checks passed
@mlw mlw deleted the mlw/network-rules-santad-table branch May 26, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

comp/santad Issues or PRs related to the daemon lang/objc++ PRs modifying files in ObjC++ size/m Size: medium

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants