Skip to content

Commit 0abc848

Browse files
authored
refactor: extract run_agent_with_token_protection helper function
1 parent b1deb90 commit 0abc848

1 file changed

Lines changed: 43 additions & 66 deletions

File tree

containers/agent/entrypoint.sh

Lines changed: 43 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,45 @@ unset_sensitive_tokens() {
397397
done
398398
}
399399

400+
# Run a command with signal handling, one-shot token protection, and clean exit.
401+
# Usage: run_agent_with_token_protection <command> [args...]
402+
# The command is launched in the background so that sensitive tokens can be unset
403+
# from the parent shell's environment once the agent has had time to cache them.
404+
run_agent_with_token_protection() {
405+
# Setup signal handler to forward signals to agent process and perform cleanup
406+
cleanup_and_exit() {
407+
if [ -n "$AGENT_PID" ]; then
408+
kill -TERM "$AGENT_PID" 2>/dev/null || true
409+
wait "$AGENT_PID" 2>/dev/null || true
410+
fi
411+
exit 143 # Standard exit code for SIGTERM
412+
}
413+
trap cleanup_and_exit TERM INT
414+
415+
# SECURITY: Run agent command in background, then unset tokens from parent shell
416+
# This prevents tokens from being accessible via /proc/1/environ after agent starts
417+
# The one-shot-token library caches tokens in the agent process, so agent can still read them
418+
"$@" &
419+
AGENT_PID=$!
420+
421+
# Wait for agent to initialize and cache tokens (up to 1 second)
422+
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
423+
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
424+
for _i in 1 2 3 4 5 6 7 8 9 10; do
425+
kill -0 "$AGENT_PID" 2>/dev/null || break
426+
sleep 0.1
427+
done
428+
429+
# Unset all sensitive tokens from parent shell environment
430+
unset_sensitive_tokens
431+
432+
# Wait for agent command to complete and capture its exit code
433+
wait $AGENT_PID
434+
EXIT_CODE=$?
435+
trap - TERM INT
436+
exit $EXIT_CODE
437+
}
438+
400439
echo "[entrypoint] Switching to awfuser (UID: $(id -u awfuser), GID: $(id -g awfuser))"
401440
echo "[entrypoint] Executing command: $@"
402441
echo ""
@@ -848,43 +887,12 @@ AWFEOF
848887
LD_PRELOAD_CMD="export LD_PRELOAD=${ONE_SHOT_TOKEN_LIB};"
849888
fi
850889

851-
# Setup signal handler to forward signals to agent process and perform cleanup
852-
cleanup_and_exit() {
853-
if [ -n "$AGENT_PID" ]; then
854-
kill -TERM "$AGENT_PID" 2>/dev/null || true
855-
wait "$AGENT_PID" 2>/dev/null || true
856-
fi
857-
exit 143 # Standard exit code for SIGTERM
858-
}
859-
trap cleanup_and_exit TERM INT
860-
861-
# SECURITY: Run agent command in background, then unset tokens from parent shell
862-
# This prevents tokens from being accessible via /proc/1/environ after agent starts
863-
# The one-shot-token library caches tokens in the agent process, so agent can still read them
864-
chroot /host /bin/bash -c "
890+
run_agent_with_token_protection chroot /host /bin/bash -c "
865891
cd '${CHROOT_WORKDIR}' 2>/dev/null || cd /
866892
trap '${CLEANUP_CMD}' EXIT
867893
${LD_PRELOAD_CMD}
868894
exec capsh --drop=${CAPS_TO_DROP} --user=${HOST_USER} -- -c 'exec ${SCRIPT_FILE}'
869-
" &
870-
AGENT_PID=$!
871-
872-
# Wait for agent to initialize and cache tokens (up to 1 second)
873-
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
874-
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
875-
for _i in 1 2 3 4 5 6 7 8 9 10; do
876-
kill -0 "$AGENT_PID" 2>/dev/null || break
877-
sleep 0.1
878-
done
879-
880-
# Unset all sensitive tokens from parent shell environment
881-
unset_sensitive_tokens
882-
883-
# Wait for agent command to complete and capture its exit code
884-
wait $AGENT_PID
885-
EXIT_CODE=$?
886-
trap - TERM INT
887-
exit $EXIT_CODE
895+
"
888896
else
889897
# Original behavior - run in container filesystem
890898
# Drop capabilities and privileges, then execute the user command
@@ -915,41 +923,10 @@ else
915923
# unset from the environment so /proc/self/environ is cleared
916924
export LD_PRELOAD=/usr/local/lib/one-shot-token.so
917925

918-
# Setup signal handler to forward signals to agent process and perform cleanup
919-
cleanup_and_exit() {
920-
if [ -n "$AGENT_PID" ]; then
921-
kill -TERM "$AGENT_PID" 2>/dev/null || true
922-
wait "$AGENT_PID" 2>/dev/null || true
923-
fi
924-
exit 143 # Standard exit code for SIGTERM
925-
}
926-
trap cleanup_and_exit TERM INT
927-
928-
# SECURITY: Run agent command in background, then unset tokens from parent shell
929-
# This prevents tokens from being accessible via /proc/1/environ after agent starts
930-
# The one-shot-token library caches tokens in the agent process, so agent can still read them
931926
if [ -n "$CAPS_TO_DROP" ]; then
932-
capsh --drop=$CAPS_TO_DROP -- -c "exec gosu awfuser $(printf '%q ' "$@")" &
927+
run_agent_with_token_protection capsh --drop=$CAPS_TO_DROP -- -c "exec gosu awfuser $(printf '%q ' "$@")"
933928
else
934929
# No capabilities to drop - just switch to unprivileged user
935-
gosu awfuser "$@" &
930+
run_agent_with_token_protection gosu awfuser "$@"
936931
fi
937-
AGENT_PID=$!
938-
939-
# Wait for agent to initialize and cache tokens (up to 1 second)
940-
# The one-shot-token LD_PRELOAD library caches tokens in ~100ms during process init.
941-
# Poll every 100ms so fast commands (e.g. 'echo ok') don't pay the full wait.
942-
for _i in 1 2 3 4 5 6 7 8 9 10; do
943-
kill -0 "$AGENT_PID" 2>/dev/null || break
944-
sleep 0.1
945-
done
946-
947-
# Unset all sensitive tokens from parent shell environment
948-
unset_sensitive_tokens
949-
950-
# Wait for agent command to complete and capture its exit code
951-
wait $AGENT_PID
952-
EXIT_CODE=$?
953-
trap - TERM INT
954-
exit $EXIT_CODE
955932
fi

0 commit comments

Comments
 (0)