AI-assisted transparent firewall for macOS. Outbound TCP is redirected through a local Python proxy; the proxy reads TLS Server Name Indication (SNI) without decrypting TLS, resolves the originating app via psutil, then applies allowlist / blocklists, entropy heuristics, a composite trust score, and optionally an LLM judge that calls WHOIS, DNS, VirusTotal, and HTTP fetch tools. A Flask dashboard streams live activity over Server-Sent Events.
- pf-based redirection to a local listener (teardown pattern in
network/reset.sh). - Fast path: allowlist and curated lists under
links/, plus DGA-style entropy scoring (modules/entropy.py). - Slow path: trust score (
modules/trustscore.py); borderline domains can escalate toaijudgement(modules/judge.py) with verdict caching and per-domain locking. - Dashboard (
app.py): start/stop the proxy, metrics, allowlist/blocklist toggles, editstorage/config.json, and a live terminal fed by proxy stdout — default UI athttp://127.0.0.1:8080.
flowchart TB
subgraph macOS["macOS"]
APP[Applications]
PF["pf redirect"]
PROXY["proxy.py\nSNI + policy"]
APP --> PF --> PROXY
end
subgraph fast["Fast path"]
ALLOW[Allowlist]
BLOCK[Blocklists]
ENT[Entropy]
end
subgraph slow["Slow path"]
TS[Trust score]
AI[LLM judge\nOpenAI-compatible API]
W[WHOIS]
D[DNS over HTTPS]
V[VirusTotal]
H[HTTP FETCH]
end
PROXY --> ALLOW
PROXY --> BLOCK
PROXY --> ENT
PROXY --> TS
TS --> AI
AI --> W & D & V & H
PROXY -->|allow| FWD[Forward to origin]
PROXY -->|block| LOG["storage/blocked.txt"]
subgraph dash["Dashboard"]
FLASK["app.py :8080"]
SSE["SSE /api/events"]
end
PROXY -. stdout .-> FLASK
FLASK --> SSE
- macOS with
pf, and ability to runsudo(pfctl,sysctlas used innetwork/reset.shand the dashboard lifecycle). - Python 3.11+ recommended.
- Python packages: Flask, psutil, requests, tldextract (≥ 5.0). Install after resolving any merge markers in
requirements.txt, or install these packages directly into your environment. - Optional — AI judge: an OpenAI-compatible server (e.g. LM Studio) at the URL in
storage/config.json→adaptive_learning.api_url(defaulthttp://127.0.0.1:1234/v1/chat/completions). - Optional — VirusTotal: API credentials as expected by
modules/tools/virustotal.py(seeenvironments/virustotal/).
storage/config.json drives the proxy listener, which blocklist files under links/ are active, allowlist file name, entropy and trust-score thresholds, AI rounds/timeouts, and logging. Values are merged with defaults in modules/config.py.
| Section | Role |
|---|---|
proxy |
Bind host/port, max connections |
blocklists / allowlist |
List files in links/ |
entropy / trustscore |
Heuristic thresholds and weights |
adaptive_learning |
Model id, API URL, rounds, cache |
logging |
e.g. storage/blocked.txt, verbosity |
Copy & Paste quick start:
pip install -r requirements.txt
sudo python app.py| Path | Purpose |
|---|---|
proxy.py |
Proxy entry: policy, SNI handling, forwarding |
app.py |
Flask dashboard, SSE, proxy start/stop |
main.py |
Runs setup.sh, proxy.py, then reset.sh |
storage/config.json |
Runtime configuration |
modules/ |
Entropy, trust score, judge, forwarding, tools |
links/ |
Allowlist and blocklist sources |
templates/ |
Dashboard HTML |
modules/styles.css, modules/script.js |
Dashboard assets |
storage/blocked.txt |
Block log (tab-separated rows) |
storage/DEVPOST.md |
Design write-up (math, challenges, roadmap) |
- Touches system firewall and typically runs as root for
pfand the proxy. Review rules before use on important systems. - Decisions use SNI hostname visibility, not full TLS payloads; edge cases (IPs, non-TLS) need separate handling.
- PID / port correlation via
psutilcan be racy under load. - LLM verdicts depend on model and prompts; the stack uses parsing, caching, and locks to keep behavior stable.
Inspired by firewall products that prompt per connection; Resolagent automates verdicts with heuristics plus an optional tool-using model. See storage/DEVPOST.md for the full story.


