Repository navigation
Conversation
A transient Vault failure (e.g. a spurious 403) when reading the test analytics token left BUILDKITE_ANALYTICS_TOKEN unset. The test-collector plugin's pre-exit hook hard-requires that variable, so it failed the job with exit 1 even after a fully green test run. Route the analytics-token lookup through a small retry helper so an intermittent Vault error no longer fails an otherwise-passing build, and collapse the per-platform if/elif chain into a single case mapping.
|
Pinging @elastic/ml-core (Team:ML) |
Apply vault_read_field_with_retry to the build-timings analytics credentials, the sccache GCS key, the Hugging Face token and the docker registry credentials. The docker registry read in particular had no fallback, so a transient Vault error would hard-fail build_pytorch_docker_image in the same way the analytics-token read failed the macOS test job.
The retry helper swallowed Vault errors with 2>/dev/null, which hid the real cause when a read ultimately failed (e.g. the macOS analytics-token read). Capture each attempt's stderr and log it, distinguishing a permission-denied (403) from a connection/timeout error, while keeping the field value clean on stdout for the caller. Co-authored-by: Cursor <cursoragent@cursor.com>
On very slow macOS/Orka checkouts (GitHub transfer rates have collapsed to ~100 KiB/s due to a MacStadium firewall issue, making clones take 20+ min), the VAULT_TOKEN minted at job start expires before post-checkout runs, so secret reads fail with 'permission denied / invalid token'. When the retry helper sees 'invalid token', it now mints a fresh token via the same OIDC/JWT flow the agent uses (vault_reauth) and retries, so the read succeeds regardless of how long the clone took. Best-effort: never fails the job if re-auth is unavailable. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
🟡 Changes recommended
Command substitution prevents the refreshed Vault token from propagating to the hook’s parent shell.
1 open finding
What changed in this PR
Hardens Buildkite post-checkout Vault access against expired tokens and transient failures.
Changes:
- Adds retry/error logging for Vault reads.
- Adds OIDC-based Vault reauthentication.
- Routes secret reads through a shared helper.
| File | Description |
|---|---|
.buildkite/hooks/post-checkout |
Adds resilient Vault authentication and reads. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| pset="${BUILDKITE_ORGANIZATION_SLUG}-${BUILDKITE_PIPELINE_SLUG}-pipeline" | ||
| tok=$(vault write -field=token auth/buildkite-oidc/login role="${pset}" jwt="${oidc}" 2>/dev/null) || return 1 | ||
| [ -n "${tok}" ] || return 1 | ||
| export VAULT_TOKEN="${tok}" |
There was a problem hiding this comment.
Good catch — fixed in cac6d57. The helper now takes an output-variable name and assigns via printf -v, and is called in the parent shell rather than inside $(...). A VAULT_TOKEN refreshed by vault_reauth now propagates to the hook, so multi-secret steps re-authenticate at most once (subsequent reads reuse the fresh token) and later hook commands see the refreshed token.
Addresses review feedback: the retry helper was called inside $(...) command substitution, so a VAULT_TOKEN refreshed by vault_reauth was lost when the subshell exited -- multi-secret steps re-authenticated once per field and later hook commands kept the expired token. The helper now takes an output-variable name and assigns via printf -v, and is invoked in the parent shell, so a single refresh propagates to the hook and to subsequent reads (which reuse the fresh token). Co-authored-by: Cursor <cursoragent@cursor.com>

Summary
Makes the
post-checkouthook's Vault reads resilient to slow Buildkite checkouts, which were red-failing otherwise-green macOS test jobs.Background
The macOS/Orka agents have recently been seeing abysmal GitHub transfer rates (as low as ~100 KiB/s) caused by a MacStadium firewall issue (packet discards; tracked by Platform Eng Productivity). On ml-cpp PR builds this pushed the macOS-aarch64 checkout from ~2.4 min (Oct 9) to 11–20 min (Oct 13).
The agent's
environmenthook mintsVAULT_TOKENonce, at job start. When the clone takes longer than the token's TTL, the token has expired by the timepost-checkoutruns, so its secret reads fail withpermission denied / invalid token. For the test steps the only read isBUILDKITE_ANALYTICS_TOKEN; leaving it empty makes thetest-collectorplugin's pre-exit hook exit 1 — failing a job in which all tests passed. (The same expiry silently disables sccache on build steps.)This is intermittent, tracking the firewall degradation — which is why only macOS, and only on slow-clone days, was affected.
Changes
Built up over a few commits, all scoped to
.buildkite/hooks/post-checkout:2>/dev/null— this is what surfaced theinvalid tokenroot cause.vault_reauth: when a read fails withinvalid token(the slow-checkout/expiry symptom), mint a freshVAULT_TOKENusing the same OIDC/JWT flow as the agent (elastic/vault-buildkite-plugin) and retry. Best-effort — never fails the job if re-auth is unavailable.All Vault reads in the hook route through the shared helper, so analytics and sccache/other reads all benefit.
Testing
invalid token, the read then succeeds, stdout stays clean, and the best-effort fallback never fails whenbuildkite-agent/vaultare unavailable.The real root-cause fix (firewall upgrade) is infra-owned; this change makes our builds resilient in the meantime and to any future slow-checkout episode.