Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions runner-layer/runner
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@
set -euo pipefail

# Imp passes the one-time registration payload through this environment
# variable. It must never be written to logs, image metadata, or disk.
# variable. It must never be written to logs, image metadata, disk, or argv.
: "${IMP_GITHUB_JITCONFIG:?IMP_GITHUB_JITCONFIG is required}"

# actions-runner's run.sh consumes the JIT payload from this environment
# variable. Keep it out of argv and remove Imp's handoff variable immediately.
export ACTIONS_RUNNER_INPUT_JITCONFIG="$IMP_GITHUB_JITCONFIG"
unset IMP_GITHUB_JITCONFIG

# The guest agent runs this entrypoint as root. actions-runner requires this
# explicit opt-in even though the guest itself is ephemeral.
export RUNNER_ALLOW_RUNASROOT=1

cd /home/runner/actions-runner
./config.sh --jitconfig "$IMP_GITHUB_JITCONFIG" --unattended
unset IMP_GITHUB_JITCONFIG
exec ./run.sh
33 changes: 16 additions & 17 deletions smoke.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ fail() {
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
wrapper="$repo_root/runner-layer/runner"

# Keep this check explicit: a JIT config is consumed by config.sh once, then
# removed before the long-running runner process starts. Do not expose it in
# trace output, image metadata, or wrapper output.
grep -Fqx './config.sh --jitconfig "$IMP_GITHUB_JITCONFIG" --unattended' "$wrapper" \
|| fail "wrapper does not configure from IMP_GITHUB_JITCONFIG"
# Keep these checks explicit: the JIT config is handed to run.sh through its
# environment only. Do not expose it in argv, trace output, image metadata, or
# wrapper output.
expected_export="export ACTIONS_RUNNER_INPUT_JITCONFIG=\"\$IMP_GITHUB_JITCONFIG\""
grep -Fqx "$expected_export" "$wrapper" \
|| fail "wrapper does not export ACTIONS_RUNNER_INPUT_JITCONFIG"
grep -Fqx 'unset IMP_GITHUB_JITCONFIG' "$wrapper" \
|| fail "wrapper retains the JIT config after configuration"
|| fail "wrapper retains Imp's JIT config handoff variable"
grep -Fqx 'exec ./run.sh' "$wrapper" \
|| fail "wrapper does not exec the runner"
grep -Fqx 'export RUNNER_ALLOW_RUNASROOT=1' "$wrapper" \
|| fail "wrapper does not support root execution"
! grep -Eq 'config\.sh|--jitconfig' "$wrapper" \
|| fail "wrapper puts the JIT config in argv"
! grep -Eq '(^|[[:space:]])set[[:space:]].*x|echo.*IMP_GITHUB_JITCONFIG|printf.*IMP_GITHUB_JITCONFIG' "$wrapper" \
|| fail "wrapper could log the JIT config"

Expand Down Expand Up @@ -67,30 +70,26 @@ tar -xOf "$tmp/$layer" usr/local/bin/runner >"$tmp/image-runner"
cmp -s "$wrapper" "$tmp/image-runner" || fail "runner image wrapper differs from source"

# Exercise the wrapper as root with a harmless synthetic JIT value. The fake
# runner verifies argument order and that JIT data is absent from run.sh's env;
# no real registration payload is printed or persisted.
# runner verifies the environment handoff, empty argv, and removal of Imp's
# variable; no real registration payload is printed or persisted.
mkdir -p "$tmp/actions-runner"
cat >"$tmp/actions-runner/config.sh" <<'CONFIG'
#!/usr/bin/env bash
set -euo pipefail
[[ "${RUNNER_ALLOW_RUNASROOT:-}" == 1 ]]
[[ "$#" == 3 && "$1" == --jitconfig && "$2" == "$EXPECTED_JITCONFIG" && "$3" == --unattended ]]
printf 'config-ok\n'
CONFIG
cat >"$tmp/actions-runner/run.sh" <<'RUN'
#!/usr/bin/env bash
set -euo pipefail
[[ "$#" == 0 ]]
[[ "${ACTIONS_RUNNER_INPUT_JITCONFIG:-}" == "$EXPECTED_JITCONFIG" ]]
[[ -z "${IMP_GITHUB_JITCONFIG+x}" ]]
[[ "${RUNNER_ALLOW_RUNASROOT:-}" == 1 ]]
printf 'run-ok\n'
RUN
chmod 0755 "$tmp/actions-runner/config.sh" "$tmp/actions-runner/run.sh"
chmod 0755 "$tmp/actions-runner/run.sh"
output="$(docker run --rm --user 0:0 \
--mount "type=bind,src=$tmp/actions-runner,dst=/home/runner/actions-runner,readonly" \
--mount "type=bind,src=$wrapper,dst=/usr/local/bin/runner,readonly" \
-e IMP_GITHUB_JITCONFIG=synthetic-jit-smoke-value \
-e EXPECTED_JITCONFIG=synthetic-jit-smoke-value \
--entrypoint /usr/local/bin/runner "$BASE_IMAGE")"
[[ "$output" == $'config-ok\nrun-ok' ]] || fail "wrapper root execution failed"
[[ "$output" == 'run-ok' ]] || fail "wrapper root execution failed"
[[ "$output" != *synthetic-jit-smoke-value* ]] || fail "wrapper leaked JIT config to logs"

echo "smoke passed: wrapper/root execution, runner image executable, and base CA/git HTTPS/DNS/eth0 prerequisites"
Loading