@@ -58,24 +58,8 @@ print_json_summary() {
5858 printf ' ,"secret_scan_count":%s}\n' " $secret_scan_count "
5959}
6060
61- emit_app_runtime_boundary_files () {
62- find_matching_files " $HOME /.openclaw" \
63- \( -path " $HOME /.openclaw/agents" \
64- -o -path " $HOME /.openclaw/browser" \
65- -o -path " $HOME /.openclaw/credentials" \
66- -o -path " $HOME /.openclaw/devices" \
67- -o -path " $HOME /.openclaw/identity" \
68- -o -path " $HOME /.openclaw/plugin-runtime-deps" \
69- -o -path " $HOME /.openclaw/plugin-runtime-deps.*" \
70- -o -path " $HOME /.openclaw/service-env" \
71- -o -path ' */node_modules' \
72- -o -path ' */.tmp' \) -prune \
73- -o -type f \( -name ' *.bak' -o -name ' *.last-good' -o -name ' *.env.*' \)
74- }
75-
7661emit_devbox_secret_scan_paths () {
7762 emit_home_dotfiles
78- emit_app_runtime_boundary_files
7963 emit_path_if_exists " $HOME /.aws"
8064 emit_path_if_exists " $HOME /.config/process-compose"
8165 emit_path_if_exists " $HOME /.docker"
@@ -129,213 +113,6 @@ system_resolves_host() {
129113 fi
130114}
131115
132- check_app_service_env_boundary () {
133- local service_env_dir=" $HOME /.openclaw/service-env"
134- local service_env_file
135- local env_owner
136-
137- section " application service env boundary"
138-
139- if [ ! -e " $service_env_dir " ]; then
140- ok " no optional application service env directory"
141- return
142- fi
143-
144- check_mode_any fail " $service_env_dir " 700
145- if [ " $( owner_of " $service_env_dir " ) " = " $devbox_user " ]; then
146- ok " $service_env_dir owner $devbox_user "
147- else
148- fail_check " $service_env_dir owner is $( owner_of " $service_env_dir " ) , expected $devbox_user "
149- fi
150-
151- while IFS= read -r service_env_file; do
152- [ -n " $service_env_file " ] || continue
153-
154- if [ -L " $service_env_file " ]; then
155- fail_check " $service_env_file must not be a symlink"
156- continue
157- fi
158-
159- check_mode_any fail " $service_env_file " 600
160- env_owner=" $( owner_of " $service_env_file " ) "
161- if [ " $env_owner " = " $devbox_user " ]; then
162- ok " $service_env_file owner $env_owner "
163- else
164- fail_check " $service_env_file owner is $env_owner , expected $devbox_user "
165- fi
166- done < <( find " $service_env_dir " -maxdepth 1 -type f -name ' *.env' -print 2> /dev/null | sort)
167- }
168-
169- check_openclaw_runtime_env_boundary () {
170- local env_file=" $HOME /.openclaw/.env"
171- local env_owner
172-
173- section " OpenClaw runtime env boundary"
174-
175- if [ ! -e " $env_file " ]; then
176- if [ -e " $HOME /.openclaw" ]; then
177- warn " OpenClaw state exists but $env_file is missing"
178- else
179- ok " no optional OpenClaw runtime env file"
180- fi
181- return
182- fi
183-
184- if [ -L " $env_file " ]; then
185- fail_check " $env_file must be a direct file, not a symlink"
186- return
187- fi
188-
189- check_mode_any fail " $env_file " 600
190- env_owner=" $( owner_of " $env_file " ) "
191- if [ " $env_owner " = " $devbox_user " ]; then
192- ok " $env_file owner $env_owner "
193- else
194- fail_check " $env_file owner is $env_owner , expected $devbox_user "
195- fi
196- }
197-
198- emit_openclaw_owned_paths () {
199- local node_installs_dir=" $HOME /.local/share/mise/installs/node"
200-
201- emit_path_if_exists " $HOME /.npm"
202- emit_path_if_exists " $HOME /.openclaw"
203-
204- if [ -d " $node_installs_dir " ]; then
205- find " $node_installs_dir " \
206- \( -path ' */lib/node_modules/openclaw' -o -path ' */bin/openclaw' \) \
207- -print 2> /dev/null || true
208- fi
209- }
210-
211- check_openclaw_owned_path () {
212- local path=" $1 "
213- local bad_path
214-
215- [ -e " $path " ] || return
216-
217- bad_path=" $(
218- find " $path " -maxdepth 8 \( -user root -o ! -user " $devbox_user " \) -print -quit 2> /dev/null || true
219- ) "
220- if [ -n " $bad_path " ]; then
221- fail_check " OpenClaw path contains root/non-$devbox_user -owned file: $bad_path "
222- else
223- ok " $path ownership stays with $devbox_user "
224- fi
225- }
226-
227- json_config_value () {
228- local path=" $1 "
229- local key=" $2 "
230-
231- if [ -r " $path " ] && command -v plutil > /dev/null 2>&1 ; then
232- plutil -extract " $key " raw -o - " $path " 2> /dev/null | tr -d ' \n' || true
233- fi
234- }
235-
236- check_openclaw_tmp () {
237- if [ " $( owner_of /private/tmp 2> /dev/null || true) " != " root" ]; then
238- fail_check " /private/tmp owner is $( owner_of /private/tmp 2> /dev/null || echo unknown) , expected root"
239- else
240- ok " /private/tmp owner root"
241- fi
242-
243- if [ " $( mode_of /private/tmp 2> /dev/null || true) " != " 777" ]; then
244- fail_check " /private/tmp mode is $( mode_of /private/tmp 2> /dev/null || echo unknown) , expected 777 with sticky bit"
245- else
246- ok " /private/tmp mode 777"
247- fi
248-
249- if [ -k /private/tmp ]; then
250- ok " /private/tmp sticky bit set"
251- else
252- fail_check " /private/tmp sticky bit is not set"
253- fi
254- }
255-
256- check_openclaw_service_node () {
257- local plist_path=" $HOME /Library/LaunchAgents/ai.openclaw.gateway.plist"
258- local wrapper_path=" $HOME /.local/bin/openclaw-gateway-mise-wrapper"
259- local path
260- local checked=0
261-
262- if [ ! -e " $HOME /.openclaw" ] && ! command -v openclaw > /dev/null 2>&1 ; then
263- ok " OpenClaw is not installed for this user"
264- return
265- fi
266-
267- if [ ! -e " $plist_path " ]; then
268- warn " OpenClaw state exists but gateway LaunchAgent is not installed"
269- return
270- fi
271-
272- check_mode_any fail " $plist_path " 600
273-
274- for path in " $plist_path " " $wrapper_path " ; do
275- [ -e " $path " ] || continue
276- checked=$(( checked + 1 ))
277-
278- if grep -Eq ' /opt/homebrew/(opt/)?node.*/bin/node|/opt/homebrew/bin/node' " $path " ; then
279- fail_check " $path references Homebrew Node"
280- else
281- ok " $path does not reference Homebrew Node"
282- fi
283-
284- if grep -Eq " $HOME /.local/share/mise/installs/node|mise" " $path " ; then
285- ok " $path references mise"
286- fi
287- done
288-
289- if [ " $checked " -eq 1 ]; then
290- warn " OpenClaw gateway wrapper is missing; checked LaunchAgent only"
291- fi
292- }
293-
294- check_openclaw_tailscale_serve () {
295- local config_path=" $HOME /.openclaw/openclaw.json"
296- local gateway_port
297- local tailscale_reset_on_exit
298- local serve_status
299-
300- if [ ! -e " $config_path " ]; then
301- ok " no OpenClaw config for Tailscale check"
302- return
303- fi
304-
305- gateway_port=" $( json_config_value " $config_path " " gateway.port" ) "
306- gateway_port=" ${gateway_port:- 18789} "
307- tailscale_reset_on_exit=" $( json_config_value " $config_path " " gateway.tailscale.resetOnExit" ) "
308-
309- if ! command -v tailscale > /dev/null 2>&1 ; then
310- warn " tailscale is missing for OpenClaw Serve drift check"
311- return
312- fi
313-
314- serve_status=" $( tailscale serve status 2> /dev/null || true) "
315- if ! grep -Fq " http://127.0.0.1:$gateway_port " <<< " $serve_status" ; then
316- ok " no Tailscale Serve route for OpenClaw port $gateway_port "
317- elif [ " $tailscale_reset_on_exit " = " true" ]; then
318- ok " OpenClaw resets Tailscale Serve for gateway port $gateway_port "
319- else
320- fail_check " Tailscale Serve proxies OpenClaw port $gateway_port but OpenClaw resetOnExit is not enabled"
321- fi
322- }
323-
324- check_openclaw_drift () {
325- local path
326-
327- section " OpenClaw runtime drift"
328-
329- check_openclaw_tmp
330- while IFS= read -r path; do
331- [ -n " $path " ] || continue
332- check_openclaw_owned_path " $path "
333- done < <( emit_openclaw_owned_paths | sort -u)
334-
335- check_openclaw_service_node
336- check_openclaw_tailscale_serve
337- }
338-
339116while [ " $# " -gt 0 ]; do
340117 case " $1 " in
341118 --config)
@@ -467,10 +244,6 @@ if [ -e "$HOME/.docker/config.json" ]; then
467244 scan_file_for_secret_pattern " $HOME /.docker/config.json" ' "auth"[[:space:]]*:' " inline Docker auth material"
468245fi
469246
470- check_app_service_env_boundary
471- check_openclaw_runtime_env_boundary
472- check_openclaw_drift
473-
474247section " Codex trust boundaries"
475248
476249codex_config=" $HOME /.codex/config.toml"
0 commit comments