Auto-enable trusted sloptrap capabilities and harden bash launcher

This commit is contained in:
Samuel Aubertin
2026-03-09 19:06:36 +01:00
parent da001da48f
commit 0ad137c6dc
9 changed files with 118 additions and 87 deletions

View File

@@ -1,5 +1,8 @@
#!/usr/bin/env bash
# sloptrap
if [ -z "${BASH_VERSION:-}" ]; then
exec bash "$0" "$@"
fi
set -euo pipefail
IS_MAC=false
@@ -166,7 +169,6 @@ usage() {
info_line "Options:\n"
comment_line " --dry-run Show planned container command(s) and exit\n"
comment_line " --print-config Display resolved manifest values\n"
comment_line " --enable-capability <name> Enable a trusted runtime capability for this run\n"
comment_line " --trust-capabilities Trust the manifest's requested capabilities for this build\n"
comment_line " -h, --help Show this message\n"
info_line "\n"
@@ -180,7 +182,7 @@ usage() {
comment_line " run Build if needed, then launch Codex\n"
comment_line " resume <id> Build if needed, then run 'codex resume <id>'\n"
comment_line " shell Drop into an interactive /bin/bash session\n"
comment_line " wizzard Create or update %s interactively\n" "$MANIFEST_BASENAME"
comment_line " wizard Create or update %s interactively\n" "$MANIFEST_BASENAME"
comment_line " clean Remove the project container/image cache\n"
comment_line " prune Remove dangling/unused sloptrap images\n"
}
@@ -226,7 +228,6 @@ declare -a SLOPTRAP_IGNORE_ENTRIES=()
declare -a IGNORE_MOUNT_ARGS=()
declare -a CODEX_ARGS_ARRAY=()
declare -a DEFAULT_TARGETS=()
declare -a ENABLED_CAPABILITIES_ARGS=()
MANIFEST_PRESENT=false
CURRENT_IGNORE_FILE=""
@@ -801,17 +802,6 @@ capability_list_contains() {
return 1
}
validate_enabled_capabilities() {
local enabled=$1
local requested=$2
local capability
for capability in $enabled; do
if ! capability_list_contains "$requested" "$capability"; then
error "runtime capability '$capability' is not requested by $MANIFEST_PATH"
fi
done
}
detect_container_engine() {
local override=${SLOPTRAP_CONTAINER_ENGINE-}
if [[ -n $override ]]; then
@@ -878,12 +868,12 @@ prompt_manifest_value() {
printf '%s [%s]: ' "$label" "$default_value" >"$tty_path"
printf '%b' "$RESET" >"$tty_path"
if ! IFS= read -r input <"$tty_path"; then
error "wizzard requires an interactive terminal"
error "wizard requires an interactive terminal"
fi
printf '%s' "$input"
}
validate_wizzard_name() {
validate_wizard_name() {
local value=$1
[[ -n $value ]] || error "$MANIFEST_PATH: name must not be empty"
if [[ ! $value =~ $VALID_NAME_REGEX ]]; then
@@ -891,7 +881,7 @@ validate_wizzard_name() {
fi
}
normalize_wizzard_allow_host_network() {
normalize_wizard_allow_host_network() {
local value=${1,,}
case "$value" in
1|true|yes) printf 'true' ;;
@@ -900,13 +890,13 @@ normalize_wizzard_allow_host_network() {
esac
}
run_wizzard() {
run_wizard() {
local manifest_path=$1
if [[ -L $manifest_path ]]; then
error "$manifest_path: manifest must not be a symlink"
fi
if [[ ! -t 0 ]]; then
error "wizzard requires an interactive terminal"
error "wizard requires an interactive terminal"
fi
if [[ ! -f $manifest_path ]]; then
print_banner
@@ -934,7 +924,7 @@ run_wizzard() {
value=$(prompt_manifest_value "name" "$default_name")
value=$(trim "$value")
[[ -n $value ]] || value=$default_name
validate_wizzard_name "$value"
validate_wizard_name "$value"
default_name=$value
break
done
@@ -951,12 +941,25 @@ run_wizzard() {
break
done
while true; do
info_line "capabilities: Optional privileged features (%s).\n" "${SLOPTRAP_SUPPORTED_CAPABILITIES[*]}"
value=$(prompt_manifest_value "capabilities" "$default_capabilities")
value=$(trim "$value")
[[ -n $value ]] || value=$default_capabilities
value=$(normalize_capability_list "$value")
if [[ -n $value ]]; then
validate_capability_list "capabilities" "$value" "$manifest_path"
fi
default_capabilities=$value
break
done
while true; do
info_line "allow_host_network: Use host networking instead of an isolated bridge.\n"
value=$(prompt_manifest_value "allow_host_network" "$default_allow_host_network")
value=$(trim "$value")
[[ -n $value ]] || value=$default_allow_host_network
default_allow_host_network=$(normalize_wizzard_allow_host_network "$value")
default_allow_host_network=$(normalize_wizard_allow_host_network "$value")
break
done
@@ -1028,12 +1031,16 @@ print_manifest_summary() {
}
build_runtime_context_prompt() {
local manifest_present prompt requested enabled network_mode
local manifest_present prompt manifest_capabilities trusted enabled network_mode
manifest_present="false"
if [[ -f $MANIFEST_PATH ]]; then
manifest_present="true"
fi
requested=${REQUESTED_CAPABILITIES:-none}
manifest_capabilities=${REQUESTED_CAPABILITIES:-none}
trusted="none"
if [[ -n $REQUESTED_CAPABILITIES ]] && capability_trust_matches_current; then
trusted=$REQUESTED_CAPABILITIES
fi
enabled=${ENABLED_CAPABILITIES:-none}
network_mode="isolated"
if [[ $SLOPTRAP_NETWORK_NAME == "host" ]]; then
@@ -1058,7 +1065,8 @@ Current resolved sloptrap state:
- manifest_present=$manifest_present
- project_name=$PROJECT_NAME
- packages_extra=${PACKAGES_EXTRA:-none}
- requested_capabilities=$requested
- manifest_capabilities=$manifest_capabilities
- trusted_capabilities=$trusted
- enabled_capabilities=$enabled
- network_mode=$network_mode
- runtime_flags=$CODEX_ARGS_DISPLAY
@@ -1755,8 +1763,8 @@ dispatch_target() {
build_if_missing
run_shell_target
;;
wizzard)
run_wizzard "$MANIFEST_PATH"
wizard)
run_wizard "$MANIFEST_PATH"
exit 0
;;
stop)
@@ -1789,12 +1797,6 @@ while [[ $# -gt 0 ]]; do
PRINT_CONFIG=true
shift
;;
--enable-capability)
shift
[[ $# -gt 0 ]] || error "--enable-capability requires a capability name"
ENABLED_CAPABILITIES_ARGS+=("$1")
shift
;;
--trust-capabilities)
TRUST_CAPABILITIES=true
shift
@@ -1844,11 +1846,11 @@ fi
if [[ ${#TARGETS_INPUT[@]} -gt 0 ]]; then
target_index=0
while (( target_index < ${#TARGETS_INPUT[@]} )); do
if [[ ${TARGETS_INPUT[$target_index]} == "wizzard" ]]; then
if [[ ${TARGETS_INPUT[$target_index]} == "wizard" ]]; then
if (( ${#TARGETS_INPUT[@]} > 1 )); then
warn "wizzard runs standalone; ignoring other targets"
warn "wizard runs standalone; ignoring other targets"
fi
run_wizzard "$MANIFEST_PATH"
run_wizard "$MANIFEST_PATH"
exit 0
fi
((target_index+=1))
@@ -1858,13 +1860,13 @@ fi
if [[ ! -f $MANIFEST_PATH ]]; then
if targets_need_build "${TARGETS_INPUT[@]}"; then
if [[ -t 0 ]]; then
run_wizzard "$MANIFEST_PATH"
run_wizard "$MANIFEST_PATH"
SKIP_BUILD_BANNER=true
MANIFEST=()
MANIFEST_PRESENT=true
parse_manifest "$MANIFEST_PATH"
else
warn "missing $MANIFEST_BASENAME; proceeding with defaults (run '$0 $CODE_DIR wizzard' to create one)"
warn "missing $MANIFEST_BASENAME; proceeding with defaults (run '$0 $CODE_DIR wizard' to create one)"
fi
fi
fi
@@ -1902,9 +1904,11 @@ if [[ -n $REQUESTED_CAPABILITIES ]]; then
ensure_safe_for_make "capabilities" "$REQUESTED_CAPABILITIES"
fi
validate_capability_list "capabilities" "$REQUESTED_CAPABILITIES"
ENABLED_CAPABILITIES=$(normalize_capability_list "${ENABLED_CAPABILITIES_ARGS[*]-}")
validate_capability_list "--enable-capability" "$ENABLED_CAPABILITIES" "command line"
validate_enabled_capabilities "$ENABLED_CAPABILITIES" "$REQUESTED_CAPABILITIES"
if [[ -n $REQUESTED_CAPABILITIES ]] && { $TRUST_CAPABILITIES || capability_trust_matches_current; }; then
ENABLED_CAPABILITIES="$REQUESTED_CAPABILITIES"
else
ENABLED_CAPABILITIES=""
fi
if [[ -n ${MANIFEST[allow_host_network]-} ]]; then
case "${MANIFEST[allow_host_network],,}" in
1|true|yes)