Files
beer_data/.gitea/workflows
hermes ce6f5b7962
Build and Push Image / Unit tests (push) Successful in 46s
Build and Push Image / Build and push image (push) Skipped
Build and Push Image / Deploy to the cluster (push) Skipped
fix(ci): pin the cluster CA fingerprint instead of trusting a fetched CA
The review was right on both counts, and both are fixed.

1. MITM. Fetching the CA over an unverified connection (`curl -sk`) and then
   trusting it is a privilege-escalation hole: the runner holds cluster-admin
   credentials, so an attacker able to intercept the fetch could hand us a CA
   of their choosing and then read everything sent over the connection.

   The CA is now PINNED. It is still fetched over an insecure connection, but
   it is only USED if its SHA-256 fingerprint matches
   `KUBE_SERVER_CA_FINGERPRINT`. An intercepted CA will not hash to the
   pinned value, so it is refused. If the secret is not set, the job fails
   rather than trusting an unverified CA.

2. The hardcoded cluster name. `kubectl config set-cluster default` creates a
   NEW cluster entry when the kubeconfig's entry is called something else,
   leaving the original (and its stale CA) in use. The name is now read from
   the kubeconfig: `{.clusters[0].name}`.

The bash is also moved out of the YAML into `scripts/kube-ca-refresh.sh`, so
it can be read, reviewed and tested on its own rather than as a wall of
shell inside a workflow file.

All three paths are tested against the live API server:

- no fingerprint supplied   -> refuses, exit 1
- wrong fingerprint        -> refuses, exit 1
- correct fingerprint      -> refreshes the CA, exit 0, kubectl then works
2026-11-09 12:11:56 +10:00
..