Skip to main content

Network Rules

Network rules let Santa authorize, deny, or audit network connections on macOS hosts. Rules match flows by the local process, the remote peer, and the transport (ports, protocols, direction), and apply an action when a flow matches.

Requirements

Network rules require Santa's network extension, which is gated behind the network extension tenant feature. The Network rules tab and the CreateNetworkFlowRule API are unavailable until it is enabled.

Overview

Each rule is scoped to a tag and identified by a name that is unique within that tag. A rule describes:

  • Who — the local process initiating or receiving the flow
  • Where — the remote peer (hostname, domain, or IP/CIDR)
  • How — the transport: port ranges, IANA protocol numbers, and direction
  • What to do — the action to take when a flow matches

Flows that match no rule fall back to the host's effective default action.

Actions

ActionBehavior
AllowAllow matching flows.
DenyDeny matching flows and notify the user.
Silent DenyDeny matching flows without notifying the user.
AuditAllow matching flows, but log them for auditing.

Direction

DirectionMatches
AnyBoth incoming and outgoing flows (the default).
OutgoingFlows initiated by the host.
IncomingFlows initiated by a remote peer.

A direction-specific rule matches only that direction. In particular it does not match a flow whose direction is unknown.

Matchers

A rule must specify at least one process or remote matcher. Ports, protocols, and direction alone would match every flow; an intentional match-everything policy belongs in the default action, not in a rule.

Within a single field, multiple values are OR'd (any value matches). Across fields, conditions are AND'd (every populated field must match).

Process matchers

Identify the local process by code signing identity.

  • CDHash — the code directory hash of a specific binary.
  • Signing ID — the signing identifier, prefixed with the Team ID (ABCDE12345:com.example.app), or platform: for platform binaries.
  • Team ID — the Apple Developer Team ID (ABCDE12345).

Remote matchers

Identify the remote peer:

  • Hostname — an exact hostname (api.example.com).
  • Domain — a domain that matches itself and its subdomains (example.com also matches api.example.com).
  • Address — an IP address or CIDR prefix (10.0.0.1, 10.0.0.0/8, 2001:db8::/32).

Transport matchers

  • Ports — single ports (443) or inclusive ranges (8000-8080), each between 1 and 65535. Empty matches any port.
  • Protocols — IANA protocol numbers 0–255 (6 = TCP, 17 = UDP, 1 = ICMP, 58 = ICMPv6). Empty matches any protocol.

Default action

network_flow_default_action is a per-tag network extension setting that decides flows no rule matches. It is the right place for a broad default-allow or default-deny posture; individual rules then carve out the exceptions.

When a host carries several tags that each set a default action, the highest-priority tag's setting wins (see Tags).

Precedence

Two independent precedence systems apply, in order. First Workshop decides which rule to send to a host when the same rule name exists across several of the host's tags (tag precedence). Then, on the host, Santa's network extension (santanetd) decides which of the rules that match a given flow wins (on-host evaluation precedence).

Tag precedence

Rule names are unique per tag, but a host usually carries several tags, and the same name may be defined on more than one of them. Santa keys network rules by name (a stable slot), so Workshop resolves each name to a single winner before syncing it to the host.

A host's tags are ordered by the admin-configured tag order, highest priority first (see Tags). For a given name, the rule on the highest-priority tag wins and is the one sent to the host.

On-host evaluation precedence

For a single flow, santanetd collects every rule whose conditions all hold, then picks the strongest by comparing this tuple field-by-field (earlier fields dominate; on a tie it moves to the next):

  1. Priority / rank — a rule marked priority outranks every ranked rule. Otherwise the higher rank wins; an unranked rule is rank 0. priority and rank are mutually exclusive.
  2. Process specificity — of the matched process key: CDHash > Signing ID > Team ID > any-process. A rule is ranked by the key it actually matched through, not its most specific declared key.
  3. Remote tier — exact IP > CIDR > hostname > domain > any-remote.
  4. Within-tier specificity — a longer CIDR prefix or deeper domain label depth wins (the more specific match).
  5. Port narrowness — the narrowest matching port range wins.
  6. Protocol-specific — a rule that names protocols beats one that does not.
  7. Direction-specific — a rule that names a direction beats one that does not.
  8. Action class — deny > silent-deny > allow > audit.
  9. Rule ID — final tiebreak: the higher (newer) rule ID wins.

The winning rule's action becomes the flow's verdict; the other matched rules are recorded as competing rule IDs in telemetry ("why didn't my rule win?") but do not affect enforcement. If no rule matches, the default action decides.

Best practices

  • Start with Audit. Use the Audit action (or a default-allow posture) to see which flows your rules would match before you enforce a denial.
  • Match on signing identity. Prefer CDHash / Signing ID / Team ID over matching broad remote ranges; process identity is the strongest signal.
  • Be specific. More specific matchers (exact IP, longer CIDR, named ports) win under on-host precedence, so narrow rules reliably override broad ones.
  • Use tags deliberately. Put broad defaults on low-priority tags and exceptions on higher-priority tags.