Session-scoped network rules with layered resolution#48
Merged
Conversation
Add the ability for greywall to send network rules as part of session creation. Rules are scoped to the session lifetime and auto-deleted when the session ends or expires. Key changes: - Migration 12: session_id column on rules, allow_all on sessions, built-in localhost rules (127.0.0.1, ::1, localhost) - SessionCreateInput gains NetworkRules and AllowAll fields - Layered rule resolution: global > session > builtin > default-deny - Per-container allow_all for learning mode (skips ACL for that container) - Heartbeat extends session rule expiry alongside session TTL - UI shows source badges (session/builtin) on rules list - Comprehensive tests for the full lifecycle
Session rules were leaking into newer sessions for the same container.
If session 1 was still alive (not expired/deleted) and session 2 was
created for the same container with no network rules, session 1's rules
kept matching session 2's traffic. The JOIN we added earlier only
verified the rule's session was still alive -- not that it was the
container's current session.
Enforce in FindMatchingRule that a session rule only matches when its
session is the most recently created active session for the connecting
container. Tie-break on rowid because datetime('now') has second-level
precision and two sessions created back-to-back can share created_at.
tito
added a commit
that referenced
this pull request
Apr 14, 2026
## Summary - Document the session/global/built-in source layers in `rules.md`, including the resolution order and the "current session per container" invariant added in #48. - Document how greywall's profile network rules become session-scoped rules in `using-with-greywall.md`, and explain how `--no-network-rules` interacts with session supersession. ## Test plan - [x] Verify both pages render via local Docusaurus build (or visual inspection of the markdown) - [x] Cross-link from the matching greywall PR (GreyhavenHQ/greywall#80) once both land
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
global > session > builtin > default-deny. Within a layer, specificity wins and deny beats allow at equal specificity.allow_allfor greywall learning mode (skips ACL for that container).127.0.0.1,::1,localhost) seeded at the lowest priority so loopback always works.sessionstable at match time, and a session rule only matches when its session is the most recently created active session for the connecting container. This prevents an older session's rules from leaking into a newer session started for the same container (e.g. greywall run with `--no-network-rules`).Test plan