-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathportwing-with-exec.yaml
More file actions
188 lines (171 loc) · 7.1 KB
/
Copy pathportwing-with-exec.yaml
File metadata and controls
188 lines (171 loc) · 7.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
# Sockguard — Portwing with Exec Preset
#
# Extends the portwing preset with exec support for interactive terminal access
# through the Portwing agent (e.g. terminal-over-websocket or drydock-driven
# exec sessions in Portwing's edge mode).
#
# Allows: everything in portwing.yaml plus:
# POST /containers/{id}/exec — create an exec instance
# POST /exec/{id}/start — start the exec (raw HTTP/1.1 upgrade)
# POST /exec/{id}/resize — resize the PTY
# GET /exec/{id}/json — inspect exec state and exit code
#
# Exec body inspection: allow_privileged is disabled. allow_root_user is
# enabled because most container workloads run as root and the caller
# (Portwing or drydock) needs unrestricted exec for interactive sessions.
# If your deployment enforces non-root containers, set allow_root_user: false
# and optionally add allowed_commands to pin the permitted argv prefixes.
#
# insecure_allow_body_blind_writes: true is required because sockguard's
# startup validator considers exec endpoints "body-blind" unless
# allowed_commands is non-empty. Interactive sessions cannot be pinned to a
# fixed command argv, so the flag acknowledges that risk explicitly.
# The allow_privileged: false / allow_root_user enforcement layer still
# applies — it gates on the inspect payload, not on argv prefix matching.
# Operators who can constrain exec to known commands should instead replace
# allow_root_user with an allowed_commands list (see drydock-with-selfupdate.yaml
# for the pinned-command pattern) and drop insecure_allow_body_blind_writes.
#
# Use this preset instead of portwing.yaml when:
# - Portwing's terminal/exec feature is in use
# - Drydock drives exec calls through the Portwing edge mode
# - You need exec for container debugging via the Portwing UI
#
# Security note: exec grants arbitrary command execution inside any container
# that Portwing can reach. Keep the proxy socket access-controlled (unix peer
# credentials or client CIDR allowlist) so only the Portwing process can call
# the exec paths. See portwing.yaml for the exec-disabled baseline.
upstream:
socket: /var/run/docker.sock
log:
level: info
format: json
access_log: true
health:
enabled: true
path: /health
# Response redaction — all three disabled for the drydock passthrough topology.
# See portwing.yaml header for standalone-mode guidance.
#
# deny_verbosity: verbose — detailed denial reasons flow to portwing/drydock
# for operator-visible errors (portwing reads the reason field as of the
# release after 0.8.1). The denial consumer in this topology is the trusted
# Portwing agent / drydock controller, not an untrusted caller, so surfacing
# the detailed reason is the right default here.
response:
redact_mount_paths: false
redact_container_env: false
redact_network_topology: false
deny_verbosity: verbose
# Exec without pinned AllowedCommands requires insecure_allow_body_blind_writes;
# log streaming requires insecure_allow_read_exfiltration. See the header
# comment for the security-tradeoff rationale for each flag.
insecure_allow_body_blind_writes: true
insecure_allow_read_exfiltration: true
# Container-create and image-pull inspection mirrors portwing.yaml.
# Exec body inspection: allow_privileged denied, root user allowed for
# interactive sessions. To pin allowed commands, replace allow_root_user
# with an allowed_commands list (argv prefix allowlist).
request_body:
container_create:
allowed_bind_mounts: []
allowed_runtimes:
- runc
exec:
allow_privileged: false
allow_root_user: true
image_pull:
allow_all_registries: true
rules:
# Health and metadata
- match: { method: GET, path: "/_ping" }
action: allow
- match: { method: HEAD, path: "/_ping" }
action: allow
- match: { method: GET, path: "/version" }
action: allow
- match: { method: GET, path: "/info" }
action: allow
- match: { method: GET, path: "/events" }
action: allow
# Container reads — list, inspect, stats, top, changes, and logs.
# /containers/*/logs is required by Portwing's GetContainerLogs().
# /containers/*/archive, /containers/*/export, and /containers/*/attach
# are intentionally omitted — bulk-data exfiltration paths Portwing does not use.
- match: { method: GET, path: "/containers/json" }
action: allow
- match: { method: GET, path: "/containers/*/json" }
action: allow
- match: { method: GET, path: "/containers/*/logs" }
action: allow
- match: { method: GET, path: "/containers/*/stats" }
action: allow
- match: { method: GET, path: "/containers/*/top" }
action: allow
- match: { method: GET, path: "/containers/*/changes" }
action: allow
# Container lifecycle
- match: { method: POST, path: "/containers/*/start" }
action: allow
- match: { method: POST, path: "/containers/*/stop" }
action: allow
- match: { method: POST, path: "/containers/*/restart" }
action: allow
- match: { method: POST, path: "/containers/*/kill" }
action: allow
- match: { method: POST, path: "/containers/*/rename" }
action: allow
- match: { method: POST, path: "/containers/*/update" }
action: allow
- match: { method: POST, path: "/containers/*/wait" }
action: allow
- match: { method: DELETE, path: "/containers/*" }
action: allow
# Container creation (for orchestration and passthrough to drydock)
- match: { method: POST, path: "/containers/create" }
action: allow
# Exec — body-inspected per request_body.exec above.
# POST /exec/*/start triggers a raw HTTP/1.1 protocol upgrade (Connection:
# Upgrade, Upgrade: tcp); sockguard passes the upgrade through on this path.
# POST /exec/*/resize adjusts the PTY dimensions for interactive terminals.
- match: { method: POST, path: "/containers/*/exec" }
action: allow
- match: { method: POST, path: "/exec/*/start" }
action: allow
- match: { method: POST, path: "/exec/*/resize" }
action: allow
- match: { method: GET, path: "/exec/*/json" }
action: allow
# Image reads — list + inspect + history.
- match: { method: GET, path: "/images/json" }
action: allow
- match: { method: GET, path: "/images/**/json" }
action: allow
- match: { method: GET, path: "/images/**/history" }
action: allow
- match: { method: POST, path: "/images/create" }
action: allow
- match: { method: DELETE, path: "/images/**" }
action: allow
# Network read — list + inspect only.
- match: { method: GET, path: "/networks" }
action: allow
- match: { method: GET, path: "/networks/*" }
action: allow
# Volume read — list + inspect only.
- match: { method: GET, path: "/volumes" }
action: allow
- match: { method: GET, path: "/volumes/*" }
action: allow
# Distribution (registry digest checks for image freshness).
- match: { method: GET, path: "/distribution/**/json" }
action: allow
# Swarm services — list + inspect.
- match: { method: GET, path: "/services" }
action: allow
- match: { method: GET, path: "/services/*" }
action: allow
# Deny everything else
- match: { method: "*", path: "/**" }
action: deny
reason: "not allowed by portwing-with-exec preset"