ci/woodpecker/push/build-ci-images Pipeline was successful
Replaces the inline-Python approach before it grows a tenth copy. Today the fleet carries ~130 lines of Python embedded in YAML strings across 9 manifests, with auth/kubernetes/login duplicated in all 9 and the call()/merge-patch helpers in 4 — none of it lintable, testable, or reviewable as code. The Home Assistant rotator would have been the worst of them: a hand-rolled WebSocket handshake with frame masking inside a YAML string. HA mints long-lived access tokens only over its WebSocket API (verified against 2026.7.2 — auth/long_lived_access_token and auth/delete_refresh_token both exist; the REST API has no equivalent). Ships as a static musl binary in FROM scratch: 4.85 MB, one file, no libc, no shell, no package manager. Nothing to patch and nothing for a compromised rotator to exec. rustls with webpki-roots compiles the trust store into the binary, so TLS works without a CA bundle on disk — in-cluster traffic is plain HTTP, but that keeps the door open to take over the Cloudflare and Proxmox rotators. ha-token mode is make-before-break, and the ordering is load-bearing: list existing token ids for the client_name BEFORE minting (so the new token can never land in the revocation set), mint, write to OpenBao, and only then revoke. If the OpenBao write fails, the old token is still valid and still stored, so the run is a no-op rather than an outage. A failed revoke is deliberately non-fatal but logged loudly: the new token is already live, and a token meant to be retired that is still valid is a real finding, not noise. Verified: static-pie linked and stripped; image contains only the binary (3.2 MB binary, 4.85 MB image); /bin/sh absent; exits non-zero on usage error; cargo test passes. The pipeline path trigger now includes secret-rotator/**, without which source changes would silently not rebuild the image. No CronJob uses it yet — the Home Assistant rotator needs a network decision first: the home-assistant namespace is default-deny-ingress, so openbao cannot reach it, and the public name hairpins off the ingress LB. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2 lines
8 B
Plaintext
2 lines
8 B
Plaintext
target/
|