1
+ @startuml macOS Process Isolation and Proxy Communication
2
+
3
+ title macOS Network Isolation with PF Rules and Process Groups
4
+
5
+ participant "User" as User
6
+ participant "jail main" as Main
7
+ participant "MacOSJail" as MacOS
8
+ participant "ProxyServer" as Proxy
9
+ participant "RuleEngine" as Rules
10
+ participant "TLS Manager" as TLS
11
+ participant "dscl/dseditgroup" as Groups
12
+ participant "PF (Packet Filter)" as PF
13
+ participant "Target Process" as Process
14
+ participant "External Server" as Server
15
+
16
+ User -> Main : jail --allow "github.com" -- curl https://github.com
17
+ Main -> Rules : ParseAllowSpecs(["github.com"])
18
+ Rules -> Main : Return allow rules
19
+ Main -> TLS : NewCertificateManager()
20
+ TLS -> Main : Return cert manager + CA cert
21
+ Main -> MacOS : NewJail(config, logger)
22
+ MacOS -> Main : Return MacOSJail instance
23
+
24
+ Main -> MacOS : Setup(httpPort=8040, httpsPort=8043)
25
+ MacOS -> MacOS : ensureGroup()
26
+ MacOS -> Groups : dscl . -read /Groups/network PrimaryGroupID
27
+ alt Group exists
28
+ Groups -> MacOS : Return existing GID
29
+ else Group doesn 't exist
30
+ MacOS -> Groups : dseditgroup -o create network
31
+ Groups -> MacOS : Group created
32
+ MacOS -> Groups : dscl . -read /Groups/network PrimaryGroupID
33
+ Groups -> MacOS : Return new GID
34
+ end
35
+ MacOS -> MacOS : setupPFRules()
36
+ MacOS -> MacOS : getDefaultInterface()
37
+ MacOS -> MacOS : route -n get default
38
+ MacOS -> MacOS : createPFRules() - Generate PF rules for group
39
+ note right : Creates rules to redirect traffic from group {GID}\nto loopback interface, then to proxy ports
40
+ MacOS -> PF : Write rules to /tmp/{name}.pf
41
+ MacOS -> PF : pfctl -a network -f /tmp/{name}.pf
42
+ MacOS -> PF : pfctl -E (enable PF)
43
+ MacOS -> PF : pfctl -f /tmp/{name}_main.pf (load main ruleset)
44
+ MacOS -> Main : Setup complete
45
+
46
+ Main -> Proxy : NewProxyServer(config)
47
+ Proxy -> Main : Return proxy instance
48
+ Main -> Proxy : Start(ctx)
49
+ Proxy -> Proxy : Start HTTP server on :8040
50
+ Proxy -> Proxy : Start HTTPS server on :8043 with TLS config
51
+
52
+ Main -> MacOS : Execute(["curl", "https://github.com"], extraEnv)
53
+ MacOS -> Process : exec.Command with SysProcAttr.Credential.Gid = {groupID}
54
+ note right : Process runs with network group membership\nand CA cert environment variables
55
+
56
+ Process -> PF : Connect to github.com:443
57
+ PF -> PF : Match group {GID} traffic rule
58
+ PF -> PF : route-to (lo0 127.0.0.1) for port 443
59
+ PF -> PF : rdr pass on lo0 port 443 -> 127.0.0.1:8043
60
+ Process -> Proxy : HTTPS request to 127.0.0.1:8043
61
+ Proxy -> TLS : Generate certificate for github.com
62
+ TLS -> Proxy : Return certificate
63
+ Proxy -> Process : TLS handshake with generated cert
64
+ Process -> Proxy : HTTPS request (decrypted)
65
+ Proxy -> Rules : Evaluate("GET", "https://github.com")
66
+ Rules -> Proxy : Allow (matches "github.com" rule)
67
+ Proxy -> Server : Forward HTTPS request to real github.com
68
+ Server -> Proxy : HTTPS response
69
+ Proxy -> Process : Forward response (re-encrypted)
70
+ Process -> MacOS : Exit with status code
71
+ MacOS -> Main : Command completed
72
+
73
+ Main -> MacOS : Cleanup()
74
+ MacOS -> PF : pfctl -a network -F all (flush anchor)
75
+ MacOS -> MacOS : Remove /tmp/{name}.pf and /tmp/{name}_main.pf
76
+ MacOS -> Main : Cleanup complete
77
+
78
+ @enduml
0 commit comments