@agenshield/sandbox 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/guarded-shell.d.ts +2 -2
- package/guarded-shell.d.ts.map +1 -1
- package/index.js +23 -15
- package/package.json +1 -1
package/guarded-shell.d.ts
CHANGED
|
@@ -25,10 +25,10 @@ export declare const GUARDED_SHELL_CONTENT = "#!/bin/zsh\n# guarded-shell: launc
|
|
|
25
25
|
* ZDOTDIR .zshenv — runs after /etc/zshenv (which calls path_helper on macOS).
|
|
26
26
|
* Overrides PATH to only include $HOME/bin.
|
|
27
27
|
*/
|
|
28
|
-
export declare const ZDOT_ZSHENV_CONTENT = "# AgenShield restricted .zshenv\n# Runs AFTER /etc/zshenv \u2014 overrides path_helper's full system PATH.\n\n# ALWAYS set HOME based on actual user, never inherit\nexport HOME=\"/Users/$(id -un)\"\nexport PATH=\"$HOME/bin\"\nexport SHELL=\"/usr/local/bin/guarded-shell\"\n\n# Clear any leftover env tricks\nunset DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_INSERT_LIBRARIES\nunset PYTHONPATH NODE_PATH RUBYLIB PERL5LIB\nunset SSH_ASKPASS LD_PRELOAD\n";
|
|
28
|
+
export declare const ZDOT_ZSHENV_CONTENT = "# AgenShield restricted .zshenv\n# Runs AFTER /etc/zshenv \u2014 overrides path_helper's full system PATH.\n\n# ALWAYS set HOME based on actual user, never inherit\nexport HOME=\"/Users/$(id -un)\"\nexport HISTFILE=\"$HOME/.zsh_history\"\n\n# Suppress locale to prevent /etc/zshrc from calling locale command\nexport LC_ALL=C LANG=C\n\nexport PATH=\"$HOME/bin\"\nexport SHELL=\"/usr/local/bin/guarded-shell\"\n\n# Clear any leftover env tricks\nunset DYLD_LIBRARY_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_INSERT_LIBRARIES\nunset PYTHONPATH NODE_PATH RUBYLIB PERL5LIB\nunset SSH_ASKPASS LD_PRELOAD\n";
|
|
29
29
|
/**
|
|
30
30
|
* ZDOTDIR .zshrc — interactive shell restrictions.
|
|
31
31
|
* Applies RESTRICTED mode, locks variables, disables builtins, installs hooks.
|
|
32
32
|
*/
|
|
33
|
-
export declare const ZDOT_ZSHRC_CONTENT = "# AgenShield restricted .zshrc\n# Applied to every interactive shell for the agent user.\n\nemulate -LR zsh\n\n# ---- Shell options ----\n# Note: NOT using setopt RESTRICTED as it disables cd entirely.\n# Instead we use preexec hooks and builtin disable for enforcement.\nsetopt NO_CASE_GLOB\nsetopt NO_BEEP\n\n# ---- Lock critical variables (readonly) ----\ntypeset -r PATH HOME SHELL\n\n# ---- Enforcement helpers ----\ndeny() {\n print -r -- \"Denied by policy\"\n return 126\n}\n\nis_allowed_cmd() {\n local cmd=\"$1\"\n\n # Allow shell builtins we explicitly permit\n case \"
|
|
33
|
+
export declare const ZDOT_ZSHRC_CONTENT = "# AgenShield restricted .zshrc\n# Applied to every interactive shell for the agent user.\n\nemulate -LR zsh\n\n# ---- Shell options ----\n# Note: NOT using setopt RESTRICTED as it disables cd entirely.\n# Instead we use preexec hooks and builtin disable for enforcement.\nsetopt NO_CASE_GLOB\nsetopt NO_BEEP\n\n# ---- Lock critical variables (readonly) ----\ntypeset -r PATH HOME SHELL\n\n# ---- Enforcement helpers ----\ndeny() {\n print -r -- \"Denied by policy\"\n return 126\n}\n\nis_allowed_cmd() {\n local cmd=\"$1\"\n\n # Allow shell builtins we explicitly permit\n case \"$cmd\" in\n cd|pwd|echo|printf|test|true|false|exit|return|break|continue|shift|set|unset|export|typeset|local|declare|readonly|let|read|print|pushd|popd|dirs|jobs|fg|bg|kill|wait|times|ulimit|umask|history|fc|type|whence|which|where|rehash)\n return 0\n ;;\n esac\n\n # Deny path execution outright\n [[ \"$cmd\" == */* ]] && return 1\n\n # Resolve command path\n local resolved\n resolved=\"$(whence -p -- \"$cmd\" 2>/dev/null)\" || return 1\n\n # Must live under HOME/bin exactly\n [[ \"$resolved\" == \"$HOME/bin/\"* ]] && return 0\n return 1\n}\n\n# ---- Block dangerous builtins ----\ndisable -r builtin command exec eval hash nohup setopt source unfunction functions alias unalias 2>/dev/null || true\n\n# ---- Intercept every interactive command before execution ----\npreexec() {\n local line=\"$1\"\n local cmd=\"${line%%[[:space:]]*}\"\n\n # Empty / whitespace lines\n [[ -z \"$cmd\" ]] && return 0\n\n # Deny anything with slash in the command token (direct path execution)\n [[ \"$cmd\" == */* ]] && { print -r -- \"Denied: direct path execution\"; kill -KILL $$; }\n\n # Deny anything not allowed\n if ! is_allowed_cmd \"$cmd\"; then\n print -r -- \"Denied: $cmd (not in $HOME/bin)\"\n kill -KILL $$\n fi\n}\n\n# ---- Also intercept non-interactive \\`zsh -c\\` cases ----\nTRAPDEBUG() {\n local line=\"${ZSH_DEBUG_CMD:-$1}\"\n local cmd=\"${line%%[[:space:]]*}\"\n [[ -z \"$cmd\" ]] && return 0\n\n [[ \"$cmd\" == */* ]] && { print -r -- \"Denied: direct path execution\"; return 126; }\n is_allowed_cmd \"$cmd\" || { print -r -- \"Denied: $cmd\"; return 126; }\n return 0\n}\n\n# ---- Ensure accessible working directory ----\ncd \"$HOME\" 2>/dev/null || cd /\n";
|
|
34
34
|
//# sourceMappingURL=guarded-shell.d.ts.map
|
package/guarded-shell.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guarded-shell.d.ts","sourceRoot":"","sources":["../src/guarded-shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,kBAAkB,iCAAiC,CAAC;AACjE,eAAO,MAAM,QAAQ,yBAAyB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,mjBAgBjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,
|
|
1
|
+
{"version":3,"file":"guarded-shell.d.ts","sourceRoot":"","sources":["../src/guarded-shell.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,kBAAkB,iCAAiC,CAAC;AACjE,eAAO,MAAM,QAAQ,yBAAyB,CAAC;AAE/C;;;GAGG;AACH,eAAO,MAAM,qBAAqB,mjBAgBjC,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,ulBAiB/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,swEA4E9B,CAAC"}
|
package/index.js
CHANGED
|
@@ -45,6 +45,11 @@ exec /bin/zsh
|
|
|
45
45
|
|
|
46
46
|
# ALWAYS set HOME based on actual user, never inherit
|
|
47
47
|
export HOME="/Users/$(id -un)"
|
|
48
|
+
export HISTFILE="$HOME/.zsh_history"
|
|
49
|
+
|
|
50
|
+
# Suppress locale to prevent /etc/zshrc from calling locale command
|
|
51
|
+
export LC_ALL=C LANG=C
|
|
52
|
+
|
|
48
53
|
export PATH="$HOME/bin"
|
|
49
54
|
export SHELL="/usr/local/bin/guarded-shell"
|
|
50
55
|
|
|
@@ -77,7 +82,7 @@ is_allowed_cmd() {
|
|
|
77
82
|
local cmd="$1"
|
|
78
83
|
|
|
79
84
|
# Allow shell builtins we explicitly permit
|
|
80
|
-
case "
|
|
85
|
+
case "$cmd" in
|
|
81
86
|
cd|pwd|echo|printf|test|true|false|exit|return|break|continue|shift|set|unset|export|typeset|local|declare|readonly|let|read|print|pushd|popd|dirs|jobs|fg|bg|kill|wait|times|ulimit|umask|history|fc|type|whence|which|where|rehash)
|
|
82
87
|
return 0
|
|
83
88
|
;;
|
|
@@ -88,10 +93,10 @@ is_allowed_cmd() {
|
|
|
88
93
|
|
|
89
94
|
# Resolve command path
|
|
90
95
|
local resolved
|
|
91
|
-
resolved="
|
|
96
|
+
resolved="$(whence -p -- "$cmd" 2>/dev/null)" || return 1
|
|
92
97
|
|
|
93
98
|
# Must live under HOME/bin exactly
|
|
94
|
-
[[ "
|
|
99
|
+
[[ "$resolved" == "$HOME/bin/"* ]] && return 0
|
|
95
100
|
return 1
|
|
96
101
|
}
|
|
97
102
|
|
|
@@ -104,14 +109,14 @@ preexec() {
|
|
|
104
109
|
local cmd="\${line%%[[:space:]]*}"
|
|
105
110
|
|
|
106
111
|
# Empty / whitespace lines
|
|
107
|
-
[[ -z "
|
|
112
|
+
[[ -z "$cmd" ]] && return 0
|
|
108
113
|
|
|
109
114
|
# Deny anything with slash in the command token (direct path execution)
|
|
110
|
-
[[ "
|
|
115
|
+
[[ "$cmd" == */* ]] && { print -r -- "Denied: direct path execution"; kill -KILL $$; }
|
|
111
116
|
|
|
112
117
|
# Deny anything not allowed
|
|
113
|
-
if ! is_allowed_cmd "
|
|
114
|
-
print -r -- "Denied:
|
|
118
|
+
if ! is_allowed_cmd "$cmd"; then
|
|
119
|
+
print -r -- "Denied: $cmd (not in $HOME/bin)"
|
|
115
120
|
kill -KILL $$
|
|
116
121
|
fi
|
|
117
122
|
}
|
|
@@ -120,10 +125,10 @@ preexec() {
|
|
|
120
125
|
TRAPDEBUG() {
|
|
121
126
|
local line="\${ZSH_DEBUG_CMD:-$1}"
|
|
122
127
|
local cmd="\${line%%[[:space:]]*}"
|
|
123
|
-
[[ -z "
|
|
128
|
+
[[ -z "$cmd" ]] && return 0
|
|
124
129
|
|
|
125
|
-
[[ "
|
|
126
|
-
is_allowed_cmd "
|
|
130
|
+
[[ "$cmd" == */* ]] && { print -r -- "Denied: direct path execution"; return 126; }
|
|
131
|
+
is_allowed_cmd "$cmd" || { print -r -- "Denied: $cmd"; return 126; }
|
|
127
132
|
return 0
|
|
128
133
|
}
|
|
129
134
|
|
|
@@ -1265,22 +1270,25 @@ function createDirectoryStructure(config) {
|
|
|
1265
1270
|
group: socketGroupName
|
|
1266
1271
|
},
|
|
1267
1272
|
[`${agentHome}/bin`]: {
|
|
1268
|
-
mode:
|
|
1269
|
-
//
|
|
1273
|
+
mode: 1533,
|
|
1274
|
+
// setgid + group-writable
|
|
1270
1275
|
owner: brokerUsername,
|
|
1271
1276
|
// broker owns bin, can create skill wrappers
|
|
1272
1277
|
group: socketGroupName
|
|
1273
1278
|
// agent can read+exec via group
|
|
1274
1279
|
},
|
|
1275
1280
|
[`${agentHome}/.openclaw`]: {
|
|
1276
|
-
mode:
|
|
1277
|
-
|
|
1281
|
+
mode: 1533,
|
|
1282
|
+
// setgid + group-writable for broker
|
|
1283
|
+
owner: brokerUsername,
|
|
1284
|
+
// broker needs write access
|
|
1278
1285
|
group: socketGroupName
|
|
1279
1286
|
},
|
|
1280
1287
|
[`${agentHome}/.openclaw/skills`]: {
|
|
1281
1288
|
mode: 1533,
|
|
1282
1289
|
// setgid bit, group-writable for broker to create subdirectories
|
|
1283
|
-
owner:
|
|
1290
|
+
owner: brokerUsername,
|
|
1291
|
+
// broker needs write access
|
|
1284
1292
|
group: socketGroupName
|
|
1285
1293
|
},
|
|
1286
1294
|
[`${agentHome}/workspace`]: {
|