fix(TST-25,SEC): stop CI SSH key leaking in cleartext CI logs
ci / portable (push) Successful in 7m28s
ci / java (push) Successful in 1m59s
ci / nightly-windev (push) Has been skipped
ci / windows-x86 (push) Successful in 1m6s

The windows-x86 acceptance check 'no key material in logs' failed: run #37's
job log printed the full WINDEV_SSH_KEY PEM in the step env echo. Gitea's
secret masker is line-oriented, so a multiline PEM rendered as one line with
literal \n escapes never matches the real-newline secret value and is not
redacted.

Fix: store WINDEV_SSH_KEY base64-encoded (single line) so the masker redacts
it to ***; run-windev-ci.sh auto-decodes a base64 PEM (still accepts a raw PEM
for local hand-testing). Drop the redundant WINDEV_SSH_KNOWN_HOSTS from the job
env (host keys are public and come from the committed windev.known_hosts pin),
removing another cleartext env line. Document the base64 requirement in the
bring-up README.

Operationally: the previously-exposed CI key has been rotated on windev
(old pubkey revoked from administrators_authorized_keys, new key installed) and
the Gitea WINDEV_SSH_KEY secret replaced with the new key's base64.
This commit is contained in:
Joseph Doherty
2026-07-13 10:45:16 -04:00
parent b42cbd0730
commit 6803bab79a
3 changed files with 30 additions and 9 deletions
+14 -3
View File
@@ -12,8 +12,12 @@
#
# Environment:
# CI_SHA commit to test (default: `git rev-parse HEAD` in this checkout)
# WINDEV_SSH_KEY private key PEM (Gitea secret). If empty, falls back to the
# runner's default ssh identity/agent (used for local hand-testing).
# WINDEV_SSH_KEY private key (Gitea secret). Store it BASE64-ENCODED (one line):
# Gitea's secret masker is line-oriented, so a raw multiline PEM in
# the step `env:` echo is NOT redacted and leaks in cleartext, whereas
# the single-line base64 is masked to *** (TST-25 acceptance: no key
# material in logs). A raw PEM is still accepted for local hand-testing
# (auto-detected). If empty, falls back to the runner's default identity.
# WINDEV_SSH_KNOWN_HOSTS pinned host keys (Gitea secret). If empty, uses the committed
# scripts/ci/windev.known_hosts.
# WINDEV_SSH_USER ssh user on windev (default: ci)
@@ -60,9 +64,16 @@ fi
SSH_OPTS+=(-o "UserKnownHostsFile=$KNOWN_HOSTS")
# Private key: secret if provided, else fall back to the default identity/agent.
# CI stores it base64-encoded (single line) so Gitea's line-oriented secret masker redacts it
# in the step env echo — a raw multiline PEM leaks in cleartext. Decode when it is valid base64
# wrapping a PEM; otherwise treat the value as a raw PEM (local hand-testing convenience).
if [ -n "${WINDEV_SSH_KEY:-}" ]; then
KEY="$WORK/id_ci"
( umask 077; printf '%s\n' "$WINDEV_SSH_KEY" > "$KEY" )
if printf '%s' "$WINDEV_SSH_KEY" | base64 -d 2>/dev/null | grep -q 'PRIVATE KEY'; then
( umask 077; printf '%s' "$WINDEV_SSH_KEY" | base64 -d > "$KEY" )
else
( umask 077; printf '%s\n' "$WINDEV_SSH_KEY" > "$KEY" )
fi
SSH_OPTS+=(-o IdentitiesOnly=yes -i "$KEY")
fi