# S12 — Network listeners + system integrity

This surface is where exposure actually lives: TCP listeners, classic macOS sharing toggles, system extensions, root-level privileged helpers, third-party kernel extensions, and the Application Firewall. Re-surveyed 2026-08-07 (snapshot 2026-08-08 01:49 UTC; previous pass 2026-07-28 13:19 UTC) under **degrade rung 2** — unprivileged `lsof` only, because `/Users/wolf/Projects/mac-atlas/captures/lsof-network.txt` is absent. Root-owned listeners, if any exist, are **not visible** from this census.

**29 inventory items:** 16 itemized listening sockets · 2 system extensions · 5 privileged helper tools · 1 third-party kext · 1 firewall-state · 4 sharing-service presence rows. Unknowns: **0** — the 2026-07-28 unknown (an Agentify Python server on 8788) is gone from the machine and its row was retired with it. The fresh unprivileged snapshot held 20 listeners: the 16 rows below plus a summarized class of four rotating, loopback-only dynamic-range sockets. This follows the spec’s `ephemeral_port_rule`: a local app, build, or model session that receives a new dynamic port is not a new persistent inventory item.

## Bind-address risk summary (the core finding)

| Class | Count | What |
| --- | ---: | --- |
| Wildcard-bound (`*:port`) | **6** sockets (3 ports × IPv4+IPv6) | World-reachable on the LAN; all itemized |
| Fixed/registered loopback-only (`127.0.0.1` / `[::1]`) | **10** sockets | Not reachable from other machines; all itemized |
| Rotating loopback dynamic range (49152–65535) | **4** sockets | Not reachable from other machines; summarized class, not individual rows |
| Application Firewall | **disabled** (State = 0) | Does not filter inbound app traffic |

The six world-reachable sockets are **all Apple’s own**:

- **ControlCenter** `*:7000` and `*:5000` (IPv4 + IPv6 each) — AirPlay Receiver / Continuity media ports
- **rapportd** `*:58381` (IPv4 + IPv6) — Continuity / Rapport. **This port rotated** since the last survey (it was `*:62998` on 2026-07-28): rapportd picks a fresh dynamic port each time it starts, so the daemon — not the number — is the stable identity. Being wildcard-bound, it stays itemized regardless of its port.

No third-party process is listening on a wildcard address in the unprivileged view. That is the single most valuable security read of this unit: **every non-Apple listener is loopback-only**.

Because the Application Firewall is **off**, those six Apple wildcards are not subject to per-app inbound filtering. On a modern Mac with AirPlay/Handoff, that is a common posture, but it is not neutral — it means LAN reachability of Continuity ports is real, not theoretical.

## What owns each loopback listener

| Port(s) | Process | Owner / cross-ref |
| --- | --- | --- |
| 6379 v4+v6 | `redis-server` | Homebrew Redis — S1 `homebrew.mxcl.redis`, S5 brew services (started) |
| 5432 v4+v6 | `postgres` | Homebrew PostgreSQL 14 — S1 `homebrew.mxcl.postgresql@14`, S5 (started) |
| 44950, 44960 | `figma_agent` | Figma desktop agent — S7 Applications (`Figma.app`) |
| 11434 | `ollama serve` | Ollama API — S10 models; **not** under brew services at scan time (process live outside `brew services`) |
| 8787 | `observify.py` | Wolf project — S1 `observify.runtimecards.8787` |
| 24314 | VS Code `Code Helper (Plugin)` (pid 22162) | S7 Visual Studio Code — new since 2026-07-28 |
| 13329 | VS Code `Code Helper (Plugin)` (pid 87572, a second editor window) | S7 Visual Studio Code — new since 2026-07-28 |

All of the above are flagged **transient** where they ride an editor, model, or project session: sockets vanish when the owning process exits; that is registration lifecycle for this kind, not a defect.

### Rotating loopback dynamic-port class (excluded from individual rows)

The same snapshot contained **four** loopback-only listeners in IANA’s dynamic range, all excluded only because they satisfy **both** conditions in the conductor rule. **VS Code `Code Helper` processes held three** (`127.0.0.1:63954` on pid 22162, `:61172` on pid 87538, `:61239` on pid 87572) and **Ollama `llama-server` held one** (`127.0.0.1:54350`, pid 33153, started 2026-08-07 21:24 for a model load). The three **java** sockets summarized on 2026-07-28 are gone — no java process was listening at this scan. Their assigned ports rotate with editor, build, and model sessions; they are not network-reachable and are not a changing set of persistent services. A wildcard listener in this port range would still be itemized and fail parity if absent — which is why rapportd’s wildcard `*:58381` remains an individual row even though 58381 is itself in the dynamic range.

## Sharing services (File / Screen / Remote Login / Remote Management)

All four canonical daemon plists are **present** under `/System/Library/LaunchDaemons`:

| Service | Label | Plist file | Canonical port in LISTEN? |
| --- | --- | --- | --- |
| Remote Login (SSH) | `com.openssh.sshd` | **`ssh.plist`** (label ≠ filename) | 22 — **no** |
| File Sharing (SMB) | `com.apple.smbd` | `com.apple.smbd.plist` | 445 — **no** |
| Screen Sharing | `com.apple.screensharing` | `com.apple.screensharing.plist` | 5900 — **no** |
| Remote Management | `com.apple.RemoteDesktop.PrivilegeProxy` | matching plist | 3283 — **no** |

**Best determination without root:** none of the four ports appear in the unprivileged LISTEN list. That is **evidence they are currently off**, not proof — a launchd socket-activated service can exist without an open listener until first connection. Authoritative enabled-state needs Wolf to fire a pre-authorized `sudo launchctl print system` (or System Settings → Sharing). Legacy AFP (`com.apple.AppleFileServer`) is **absent** on this OS version.

## Privileged helper tools (root-level persistence)

Exactly five files under `/Library/PrivilegedHelperTools`, all root:wheel. Unlike the 2026-07-28 pass, the exact-path `ps` probe ran cleanly this time, so every live state below is **freshly verified 2026-08-07** (`com.docker.vmnetd` as root pid 575, `com.nordvpn.macos.helper` as root pid 70708):

| Helper | Owning app | Live now? |
| --- | --- | --- |
| `com.docker.socket` | Docker Desktop | dormant |
| `com.docker.vmnetd` | Docker Desktop | **running** (root) |
| `com.macpaw.CleanMyMac5.Agent` | CleanMyMac 5 | dormant |
| `com.nordvpn.macos.helper` | NordVPN | **running** (root) |
| `us.zoom.ZoomDaemon` | Zoom | dormant |

Every privileged helper is **security-sensitive** by definition (root reach), live or not. Dormant is a normal on-demand state, not a clean bill of health. NordVPN’s LaunchDaemon plist is mode `700` root-only — content not fully readable without privilege; no credential **values** were obtained or recorded.

## System extensions

Both extensions reported **`activated enabled`** in a clean, first-hand `systemextensionsctl list` this survey (2026-08-07):

1. **Tailscale** `io.tailscale.ipn.macsys.network-extension` — network extension for the Tailscale mesh VPN path (team W5364U7YZB).
2. **NordVPN Threat Protection Pro** `com.nordvpn.macos.Shield` — endpoint-security extension for DNS/content filtering (team W5W395V82Y).

Both are security-sensitive unconditionally: they sit on the network / endpoint path with system approval.

## Kernel extension

A clean `kmutil showloaded --collection auxiliary` this survey (2026-08-07) found one third-party kext: **`com.paragon-software.filesystems.extfs` (33.0.14)**, index 267 — Paragon extFS for Mac (read/write Linux ext2/3/4). Apple/kpi kexts (the OS itself) are summarized only: **281** bare-kernel rows this scan, up from 263 on 2026-07-28.

**Still needed?** Only if Wolf still mounts Linux ext volumes. Without it, those volumes become unreadable/unwritable from macOS; ordinary APFS/HFS/exFAT use is unaffected. Cross-ref S1 Paragon notification agent.

## Application Firewall posture

`socketfilterfw --getglobalstate` → **Firewall is disabled. (State = 0)** — re-verified 2026-08-07, unchanged since 2026-07-25. This project reports the setting and never changes it; enabling it is Wolf's call.

Does that make sense here?

- VPN (NordVPN helper + Shield) and Tailscale mesh provide *their own* network trust boundaries when connected.
- Almost all third-party listeners are loopback-only.
- The residual LAN surface is Apple Continuity/AirPlay wildcards.

So the posture is **coherent for a developer Mac behind VPN/mesh**, but it is still a deliberate trade-off: **inbound app filtering is off**, so any future process that binds `*` is immediately LAN-reachable with no Application Firewall backstop. Worth revisiting if Wolf ever runs third-party services that bind wildcard, or if AirPlay Receiver is unused and can be turned off to shrink the wildcard set.

## Coverage gaps (honest)

1. **No sudo lsof capture** — root-owned listeners (e.g. some VPN/system daemons) may be missing.
2. **Sharing enabled-state** — presence + port cross-check only; not root launchctl/systemsetup.
3. **NordVPN helper LaunchDaemon** — file mode prevents unprivileged full parse; no secrets read.
4. **Privileged-registry liveness — gap CLOSED this survey.** The 2026-07-28 pass had to retain older states because `systemextensionsctl` returned `OSSystemExtensionErrorDomain error 1`, the exact-path helper `ps` probes returned `operation not permitted`, and `kmutil` returned a kernel internal error. All three ran cleanly on 2026-08-07, so every extension/helper/kext state here is first-hand and current.
5. **Sockets move under the scan.** Observify's `127.0.0.1:8787` listener cycled *during* this survey (pid 80466 exited with status -15; launchd restarted it as pid 86725 seconds later). The itemized row records the surviving pid. This is normal for a launchd-supervised service and is exactly why socket rows carry the `transient` flag.

## Dispositions

### Keep (expected / in active use)

- **ControlCenter `*:7000` / `*:5000` (all four family rows)** — keep while AirPlay/Handoff is wanted; investigate turning AirPlay Receiver off if Continuity media is unused (shrinks wildcard surface).
- **rapportd `*:58381` (both families)** — keep; core Continuity. Its port is dynamic (it rotated from `*:62998` since the last survey) but its wildcard bind is still itemized and security-sensitive. Investigate only if Continuity is deliberately unwanted.
- **redis 6379 / postgres 5432 (loopback)** — keep while local dev DBs are needed; both already loopback-bound (good). Prune via brew services when projects no longer need them.
- **ollama 11434 (loopback)** — keep while local models are used; its `llama-server` child is represented in the rotating loopback dynamic-port class rather than a port-specific row.
- **observify 8787 (loopback)** — keep while the runtime dashboard is used; S1 owns the LaunchAgent.
- **Agentify Python 8788** — RETIRED: not listening at the 2026-08-07 survey; the row and this surface's only `[unknown]` were removed with it. If it returns, re-open the question of its exact server role.
- **Tailscale network extension** — keep while Tailscale is used; revoke only when leaving the tailnet permanently.
- **NordVPN Shield + nordvpn helper** — keep while NordVPN is used; both security-sensitive by design.
- **Docker vmnetd + docker.socket** — keep with Docker Desktop; prune only by uninstalling Docker if containers are abandoned.
- **application-firewall item** — keep as posture record; **investigate enabling** if wildcard third-party listeners ever appear.

### Investigate

- **AirPlay Receiver / Continuity ports with firewall off** — confirm Wolf still wants AirPlay Receiver on; if not, disable in System Settings to remove four of six wildcards.
- **Enabling the Application Firewall** — low cost backstop for future wildcard binds; does not replace loopback discipline.
- **Sharing services “actually off?”** — if certainty matters, Wolf should run pre-authorized `sudo launchctl print system` (or check Sharing UI once).
- **Paragon extFS kext** — confirm Linux ext volumes are still in the workflow; if not, candidate for product uninstall (removes the only third-party kext).
- **CleanMyMac Agent / ZoomDaemon** — dormant root helpers; keep with the apps, but if those apps are unused, uninstall the apps (helpers leave with them).
- **Root-owned listener gap** — obtain `captures/lsof-network.txt` via human-fired `sudo lsof -i -P -n` for full coverage.

### Prune candidates (only with product uninstall / service stop)

- **figma_agent ports** — prune by quitting/uninstalling Figma if unused.
- **VS Code Code Helper (the itemized 24314 and 13329 rows plus three dynamic-port sockets)** — ephemeral with the editor; no independent prune; close workspaces/quit VS Code when not needed.
- **Java dynamic-port class** — GONE as of 2026-08-07 (no java listener at scan time). Nothing to prune; expect it back whenever VS Code Java tooling or a Gradle daemon runs.
- **redis / postgres** — prune with `brew services stop` when no local project needs them (S1/S5 kill paths).
- **CleanMyMac / Zoom helpers** — prune only by uninstalling CleanMyMac_5 / zoom.us if those products are abandoned.
- **Paragon kext** — prune via Paragon’s uninstaller if extFS is unused.
- **All four sharing-service presence rows** — keep as OS capability records; investigate only if Wolf wants an authoritative enabled-state or decides to expose one of these services.

## Self-use answers (spec `dossier_questions`)

1. **Wildcard listeners?** Six sockets on three ports — ControlCenter 7000+5000 (AirPlay Receiver) and rapportd 58381 (Continuity/Handoff) — **all Apple**, each on IPv4 and IPv6. No third-party wildcards in the unprivileged view.
2. **Loopback owners?** Itemized: Redis, Postgres, Figma agent, Ollama, Observify, and two VS Code Code Helper sockets; ownership/cross-references are stated above. Every one of Wolf's own services (Observify 8787, the Ollama API on 11434, Redis 6379) is loopback-bound. Summarized rotating dynamic ports: three VS Code Code Helper sockets and one Ollama `llama-server` socket.
3. **Sharing on?** Best unprivileged read: **appear off** (no 22/445/5900/3283 listeners); plists present. Certainty requires root or System Settings.
4. **Five helpers?** Docker socket (dormant), Docker vmnetd (**live**, root pid 575), CleanMyMac Agent (dormant), NordVPN helper (**live**, root pid 70708), ZoomDaemon (dormant) — freshly verified 2026-08-07 by exact-path `ps` — apps Docker, CleanMyMac_5, NordVPN, Zoom.
5. **Tailscale + NordVPN extensions active?** Both are `activated enabled` in a clean first-hand registry call on 2026-08-07; Tailscale owns the mesh network path and Nord Shield is endpoint-security/Threat Protection Pro.
6. **Paragon extFS still needed?** Only for Linux ext volume R/W; without it those mounts fail; ordinary Mac volumes unaffected. Confirmed loaded first-hand on 2026-08-07 (`kmutil showloaded --collection auxiliary`, index 267).
7. **Firewall on/off?** **Off.** Coherent with VPN+Tailscale+loopback-heavy stack, but worth revisiting as a backstop and if AirPlay wildcards are unused.
