Skip to content

Commit 7aa324f

Browse files
committed
fix(cloud-iac): address Greptile review on PR #7890
Three issues raised by Greptile on the initial commit: P1 deploy user had no SSH authorized_keys, so the auto-deploy workflow (which SSHes as `deploy`, not root) would fail until keys were copied out-of-band. cloud-init now expands the same operator key list into the deploy user via a Terraform-template loop, so first-boot the user is reachable. P2 (sec) Replaced `curl get.docker.com | sh` with the official Docker apt repo + GPG-verified keyring (cloud-init handles the keyring). Replaced `curl bun.sh/install | bash` with a pinned GitHub release download whose SHA-256 is verified against the same release's SHASUMS256.txt before extracting. P2 Keyed hcloud_ssh_key.operators by sha256(key) prefix instead of list index, so inserting an operator at the start of var.ssh_public_keys no longer cascades into renames/recreates of every subsequent SSH key resource.
1 parent 3a896d4 commit 7aa324f

2 files changed

Lines changed: 37 additions & 8 deletions

File tree

packages/cloud-infra/cloud/terraform/hetzner/control-plane/cloud-init/bootstrap.yaml.tftpl

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,29 @@ users:
2323
shell: /bin/bash
2424
sudo: ALL=(ALL) NOPASSWD:ALL
2525
lock_passwd: true
26+
# Mirror operator SSH keys onto the deploy user. Hetzner only injects
27+
# `hcloud_ssh_key` entries into root by default, but the
28+
# `.github/workflows/deploy-eliza-provisioning-worker.yml` workflow SSHes
29+
# in as `deploy`. Without this list the first auto-deploy would fail.
30+
ssh_authorized_keys:
31+
%{ for key in operator_ssh_keys ~}
32+
- ${key}
33+
%{ endfor ~}
2634

2735
package_update: true
2836
package_upgrade: false
2937

38+
apt:
39+
sources:
40+
docker:
41+
source: "deb [arch=amd64 signed-by=$KEY_FILE] https://download.docker.com/linux/ubuntu $RELEASE stable"
42+
keyid: 9DC858229FC7DD38854AE2D88D81803C0EBFCD88
43+
3044
packages:
3145
- curl
46+
- docker-ce
47+
- docker-ce-cli
48+
- containerd.io
3249
- git
3350
- jq
3451
- nginx
@@ -44,13 +61,21 @@ write_files:
4461
export ELIZA_DEPLOY_BRANCH="${deploy_branch}"
4562

4663
runcmd:
47-
# Docker (official convenience installer — pin sha if you want it
48-
# auditable; we keep it simple for the bootstrap).
49-
- curl -fsSL https://get.docker.com | sh
64+
# Docker is installed via the `apt` block above using the official
65+
# Docker apt repo (GPG-verified keyring), not `curl get.docker.com | sh`.
5066
- systemctl enable --now docker
5167

52-
# Bun runtime for the deploy user (the daemons run under bun/tsx).
53-
- su - deploy -c 'curl -fsSL https://bun.sh/install | bash -s "bun-v1.3.13"'
68+
# Bun runtime for the deploy user. We download a pinned release tarball
69+
# AND its SHASUMS256 manifest from the same GitHub release, then verify
70+
# the binary against the published hash before extracting. This avoids
71+
# the `curl bun.sh/install | bash` supply-chain pattern flagged in the
72+
# PR review — we still trust GitHub's HTTPS, but the manifest commits
73+
# the publisher to a specific hash that an attacker can't forge mid-flight.
74+
- install -d -o deploy -g deploy /home/deploy/.bun /home/deploy/.bun/bin
75+
- su - deploy -c 'curl -fsSL -o /tmp/bun.zip https://github.com/oven-sh/bun/releases/download/bun-v1.3.13/bun-linux-x64.zip'
76+
- su - deploy -c 'curl -fsSL -o /tmp/bun-SHASUMS256.txt https://github.com/oven-sh/bun/releases/download/bun-v1.3.13/SHASUMS256.txt'
77+
- su - deploy -c 'cd /tmp && grep "bun-linux-x64.zip" bun-SHASUMS256.txt | sha256sum -c -'
78+
- su - deploy -c 'cd /tmp && unzip -q bun.zip && install -m 0755 bun-linux-x64/bun /home/deploy/.bun/bin/bun && rm -rf /tmp/bun.zip /tmp/bun-linux-x64 /tmp/bun-SHASUMS256.txt'
5479

5580
# Repo checkout — the GitHub deploy workflow then takes over for code updates.
5681
- mkdir -p /opt/eliza && chown deploy:deploy /opt/eliza

packages/cloud-infra/cloud/terraform/hetzner/control-plane/main.tf

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ locals {
1010
}
1111

1212
resource "hcloud_ssh_key" "operators" {
13-
for_each = { for idx, key in var.ssh_public_keys : idx => key }
13+
# Key the map by a short SHA-256 prefix of the public key rather than the
14+
# list index — keeps Terraform plans stable when operators are
15+
# inserted/reordered in `var.ssh_public_keys`.
16+
for_each = { for key in var.ssh_public_keys : substr(sha256(key), 0, 12) => key }
1417

1518
name = "eliza-cp-${var.environment}-op-${each.key}"
1619
public_key = each.value
@@ -30,8 +33,9 @@ resource "hcloud_server" "control_plane" {
3033
})
3134

3235
user_data = templatefile("${path.module}/cloud-init/bootstrap.yaml.tftpl", {
33-
hostname = "eliza-cp-${var.environment}-${each.value}"
34-
deploy_branch = var.deploy_branch
36+
hostname = "eliza-cp-${var.environment}-${each.value}"
37+
deploy_branch = var.deploy_branch
38+
operator_ssh_keys = var.ssh_public_keys
3539
})
3640

3741
# Keep server alive across refactors: changing labels or user_data

0 commit comments

Comments
 (0)