fix(runner): harden non110 registration ceremony [skip ci]
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
## 2026-06-28 — 21:09 non-110 runner registration ceremony hardening
|
||||
|
||||
**完成內容**:
|
||||
- `ops/runner/register-awoooi-non110-runner.sh` 補上正式 `--check` / `--dry-run` check-mode。
|
||||
- registration helper 現在明確拒絕 `RUNNER_TOKEN` environment,避免 runner token 透過 env / process context 進入 Codex 或 shell 流程;仍只允許互動 TTY silent prompt 與 stdin registration。
|
||||
- `ops/runner/README.md` 同步 188 check-mode 與正式註冊邊界:Codex 不接觸 token、不使用 `--token` argv、不列印 token、不讀 `.runner` 內容。
|
||||
|
||||
**驗證結果**:
|
||||
- `bash -n ops/runner/register-awoooi-non110-runner.sh ops/runner/install-awoooi-non110-runner-user-service.sh ops/runner/check-awoooi-non110-runner-readiness.sh`:通過。
|
||||
- `python3.11 -m pytest ops/runner/test_register_awoooi_non110_runner.py ops/runner/test_check_awoooi_non110_runner_readiness.py ops/runner/test_guard_gitea_runner_pressure.py -q`:`12 passed`。
|
||||
- `python3 ops/runner/guard-gitea-runner-pressure.py --root .`:`GITEA_RUNNER_PRESSURE_GUARD_OK workflow_files=10 scheduled_workflows=3 auto_branch_events_on_110=0 generic_runner_labels=0`。
|
||||
- 188 registration helper check-mode:`dry_run=true`、`runner_token_in_argv=false`、`raw_runner_registration_read=false`、`safe_next_step=run_this_script_from_interactive_tty_without_capturing_token`。
|
||||
- 188 readiness verifier:`READY_CONFIG_COUNT=1`、`READY_BINARY_COUNT=1`、`READY_SERVICE_COUNT=1`、`READY_REGISTRATION_COUNT=0`、`READY_ACTIVE_SERVICE_COUNT=0`、`UNMANAGED_RUNNER_CONTAINERS=none`、`HEAVY_PROCESS_COUNT=0`、`BLOCKER_COUNT=3`。
|
||||
|
||||
**邊界**:沒有讀 `.runner` 內容、runner token、secret、raw session、SQLite、auth 或 `.env`;沒有啟動 runner service;沒有重開 110 runner;沒有重啟 Docker / Nginx / firewall / K3s / DB;沒有使用 GitHub。
|
||||
|
||||
## 2026-06-28 — 20:45 Delivery Workbench non-110 runner readiness 投影
|
||||
|
||||
**完成內容**:
|
||||
|
||||
@@ -484,6 +484,18 @@ ssh ollama@192.168.0.188 'bash -s' \
|
||||
< ops/runner/check-awoooi-non110-runner-readiness.sh
|
||||
```
|
||||
|
||||
runner registration 只能由 operator 在互動 TTY 執行;Codex 不得接觸 token。
|
||||
註冊 helper 的 check-mode 不需要 token,也不得接受 `RUNNER_TOKEN` environment:
|
||||
|
||||
```bash
|
||||
ssh ollama@192.168.0.188 'bash -s -- --check' \
|
||||
< ops/runner/register-awoooi-non110-runner.sh
|
||||
```
|
||||
|
||||
正式註冊時,helper 會用 silent TTY 讀取 runner token,透過 stdin 餵給
|
||||
`act_runner register`,不使用 `--token` argv、不列印 token、不讀 `.runner`
|
||||
內容;若 `.runner` 已存在,預設只回報下一步 enable / verifier,不覆寫。
|
||||
|
||||
`--enable` 只允許在 `AWOOOI_NON110_ENABLE=1`、`act_runner` executable、
|
||||
`config.yaml` present、`.runner` present 且 service 已由 verifier 證明 target / limits
|
||||
正確後使用。installer 不會讀 `.runner` 內容,也不會寫 runner token;rollback 只會
|
||||
|
||||
@@ -17,7 +17,7 @@ RUNNER_REGISTRATION="${RUNNER_REGISTRATION:-${RUNNER_DIR}/.runner}"
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage:
|
||||
DRY_RUN=1 ops/runner/register-awoooi-non110-runner.sh
|
||||
ops/runner/register-awoooi-non110-runner.sh --check
|
||||
ops/runner/register-awoooi-non110-runner.sh
|
||||
|
||||
Environment overrides:
|
||||
@@ -27,6 +27,7 @@ Environment overrides:
|
||||
Safety contract:
|
||||
- requires an interactive TTY for token entry
|
||||
- reads the runner token with terminal echo disabled
|
||||
- refuses RUNNER_TOKEN from the environment
|
||||
- feeds the token to act_runner over stdin, not argv
|
||||
- never prints the token or .runner content
|
||||
- refuses to overwrite an existing non-empty registration unless
|
||||
@@ -114,10 +115,23 @@ main() {
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
if [ "${1:-}" = "--check" ] || [ "${1:-}" = "--dry-run" ]; then
|
||||
DRY_RUN=1
|
||||
export DRY_RUN
|
||||
shift
|
||||
fi
|
||||
if [ "$#" -gt 0 ]; then
|
||||
usage >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
umask 077
|
||||
trap 'unset RUNNER_TOKEN 2>/dev/null || true' EXIT
|
||||
|
||||
if [ "${RUNNER_TOKEN+x}" = "x" ]; then
|
||||
die "runner_token_env_not_allowed"
|
||||
fi
|
||||
|
||||
metadata
|
||||
preflight
|
||||
|
||||
|
||||
@@ -15,11 +15,43 @@ USER_SERVICE_INSTALLER = ROOT / "ops/runner/install-awoooi-non110-runner-user-se
|
||||
def test_register_helper_has_no_token_argv_path() -> None:
|
||||
text = REGISTER.read_text(encoding="utf-8")
|
||||
assert "--token" not in text
|
||||
assert "runner_token_env_not_allowed" in text
|
||||
assert "runner_token_in_argv=false" in text
|
||||
assert "runner_token_echoed=false" in text
|
||||
assert "raw_runner_registration_read=false" in text
|
||||
|
||||
|
||||
def test_register_helper_rejects_runner_token_env(tmp_path: Path) -> None:
|
||||
runner_dir = tmp_path / "runner"
|
||||
runner_dir.mkdir(parents=True)
|
||||
binary = runner_dir / "act_runner"
|
||||
binary.write_text("#!/usr/bin/env bash\nexit 99\n", encoding="utf-8")
|
||||
binary.chmod(0o755)
|
||||
config = runner_dir / "config.yaml"
|
||||
config.write_text("runner:\n capacity: 1\n", encoding="utf-8")
|
||||
|
||||
result = subprocess.run(
|
||||
["bash", str(REGISTER), "--check"],
|
||||
check=False,
|
||||
env={
|
||||
**os.environ,
|
||||
"RUNNER_TOKEN": "fake-token-that-must-not-be-accepted",
|
||||
"RUNNER_DIR": str(runner_dir),
|
||||
"RUNNER_BINARY": str(binary),
|
||||
"RUNNER_CONFIG": str(config),
|
||||
"RUNNER_REGISTRATION": str(runner_dir / ".runner"),
|
||||
},
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
assert result.returncode != 0
|
||||
assert "runner_token_env_not_allowed" in result.stderr
|
||||
assert "fake-token-that-must-not-be-accepted" not in result.stdout
|
||||
assert "fake-token-that-must-not-be-accepted" not in result.stderr
|
||||
|
||||
|
||||
def test_user_installer_has_no_token_argv_path() -> None:
|
||||
wrapper = COMPAT_WRAPPER.read_text(encoding="utf-8")
|
||||
installer = USER_SERVICE_INSTALLER.read_text(encoding="utf-8")
|
||||
@@ -39,11 +71,10 @@ def test_register_helper_dry_run_requires_no_token(tmp_path: Path) -> None:
|
||||
config.write_text("runner:\n capacity: 1\n", encoding="utf-8")
|
||||
|
||||
result = subprocess.run(
|
||||
["bash", str(REGISTER)],
|
||||
["bash", str(REGISTER), "--check"],
|
||||
check=False,
|
||||
env={
|
||||
**os.environ,
|
||||
"DRY_RUN": "1",
|
||||
"RUNNER_DIR": str(runner_dir),
|
||||
"RUNNER_BINARY": str(binary),
|
||||
"RUNNER_CONFIG": str(config),
|
||||
|
||||
Reference in New Issue
Block a user