ci: switch runner git clones from HTTPS+CF Access to SSH deploy key

This commit is contained in:
Will Anderson
2026-05-05 04:07:35 -05:00
parent 2e5655c583
commit c2900400a4
4 changed files with 78 additions and 51 deletions
+6 -14
View File
@@ -96,17 +96,9 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
# build containers with its own entrypoint to keep them alive between
# steps, and overriding it breaks job execution.
# In-cluster git redirect — GKE runners resolve the internal Gitea service
# directly, bypassing Cloudflare Access. This insteadOf rule rewrites any
# clone/fetch of the public URL to the in-cluster service URL so CI jobs work
# without CF Access headers inside the GKE cluster.
#
# On Legion runners this is overridden at runtime by git-cf-access-init.sh
# (which sets the reverse redirect + CF Access headers). The system-level rule
# here is a safe baseline; the init script wins because it runs after.
RUN git config --system \
url."http://gitea.gitea.svc.cluster.local:3000/".insteadOf \
"https://git.neuralplatform.ai/"
COPY git-cf-access-init.sh /usr/local/bin/git-cf-access-init.sh
RUN chmod +x /usr/local/bin/git-cf-access-init.sh
# SSH-based git clone init script.
# Sourced before every CI step via BASH_ENV (set in deployment.yaml).
# Writes GITEA_SSH_PRIVATE_KEY to ~/.ssh/gitea_key and rewrites HTTPS
# Gitea URLs to SSH so actions/checkout and git clone both use SSH auth.
COPY git-ssh-init.sh /usr/local/bin/git-ssh-init.sh
RUN chmod +x /usr/local/bin/git-ssh-init.sh
@@ -8,7 +8,7 @@ metadata:
labels:
app: gitea-runner
annotations:
config-version: "2026-05-05-gke-gitea-url"
config-version: "2026-05-05-ssh-clone"
spec:
replicas: 1
selector:
@@ -19,7 +19,7 @@ spec:
labels:
app: gitea-runner
annotations:
config-version: "2026-05-05-gke-gitea-url"
config-version: "2026-05-05-ssh-clone"
spec:
securityContext:
runAsNonRoot: false
@@ -52,9 +52,8 @@ spec:
# /usr/local/bin/git-cf-access-init.sh before every step,
# which sets up the redirect + headers.
env:
CF_ACCESS_CLIENT_ID: "${CF_ACCESS_CLIENT_ID}"
CF_ACCESS_CLIENT_SECRET: "${CF_ACCESS_CLIENT_SECRET}"
BASH_ENV: "/usr/local/bin/git-cf-access-init.sh"
GITEA_SSH_PRIVATE_KEY: "${GITEA_SSH_PRIVATE_KEY}"
BASH_ENV: "/usr/local/bin/git-ssh-init.sh"
extra_hosts: []
EOF
envFrom:
@@ -101,7 +100,7 @@ metadata:
labels:
app: neuron-technologies-runner
annotations:
config-version: "2026-05-05-gke-gitea-url"
config-version: "2026-05-05-ssh-clone"
spec:
replicas: 2
selector:
@@ -112,7 +111,7 @@ spec:
labels:
app: neuron-technologies-runner
annotations:
config-version: "2026-05-05-gke-gitea-url"
config-version: "2026-05-05-ssh-clone"
spec:
securityContext:
runAsNonRoot: false
@@ -145,9 +144,8 @@ spec:
# /usr/local/bin/git-cf-access-init.sh before every step,
# which sets up the redirect + headers.
env:
CF_ACCESS_CLIENT_ID: "${CF_ACCESS_CLIENT_ID}"
CF_ACCESS_CLIENT_SECRET: "${CF_ACCESS_CLIENT_SECRET}"
BASH_ENV: "/usr/local/bin/git-cf-access-init.sh"
GITEA_SSH_PRIVATE_KEY: "${GITEA_SSH_PRIVATE_KEY}"
BASH_ENV: "/usr/local/bin/git-ssh-init.sh"
extra_hosts: []
EOF
envFrom:
@@ -1,20 +1,19 @@
---
# gitea-runner-secret — neural-platform org runner token
#
# GITEA_INSTANCE_URL stays as the in-cluster URL — the act_runner daemon
# polls it constantly and we don't want every poll to hit Cloudflare Access.
# Build containers, however, need the public URL because they run with
# network: host and can't resolve gitea.git.svc.cluster.local. The
# git-cf-access-init.sh entrypoint in the ci-base image rewrites the
# in-cluster URL to https://git.neuralplatform.ai with the CF Access
# headers from CF_ACCESS_CLIENT_ID / CF_ACCESS_CLIENT_SECRET below.
# GITEA_INSTANCE_URL: act_runner daemon polls git.neuralplatform.ai via HTTPS.
# GITEA_SSH_PRIVATE_KEY: ED25519 deploy key for SSH-based git clones inside
# build containers. git-ssh-init.sh (sourced via BASH_ENV) writes this key
# to ~/.ssh/gitea_key and rewrites HTTPS Gitea URLs to SSH so that
# actions/checkout and plain `git clone` both use SSH auth without any
# HTTPS credential or CF Access token.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: gitea-runner-secret
namespace: ci
annotations:
force-sync: "2026-05-05-gke-gitea-url"
force-sync: "2026-05-05-ssh-clone"
spec:
refreshInterval: 1h
secretStoreRef:
@@ -27,21 +26,16 @@ spec:
data:
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
CF_ACCESS_CLIENT_ID: "{{ .cf_access_client_id }}"
CF_ACCESS_CLIENT_SECRET: "{{ .cf_access_client_secret }}"
GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}"
data:
- secretKey: runner_token
remoteRef:
key: secret/data/gitea
property: runner_token
- secretKey: cf_access_client_id
- secretKey: ci_ssh_private_key
remoteRef:
key: secret/data/gitea-runner-cf-access
property: client_id
- secretKey: cf_access_client_secret
remoteRef:
key: secret/data/gitea-runner-cf-access
property: client_secret
key: secret/data/gitea
property: ci_ssh_private_key
---
# neuron-technologies-runner-secret — neuron-technologies org runner token
apiVersion: external-secrets.io/v1beta1
@@ -50,7 +44,7 @@ metadata:
name: neuron-technologies-runner-secret
namespace: ci
annotations:
force-sync: "2026-05-05-gke-gitea-url"
force-sync: "2026-05-05-ssh-clone"
spec:
refreshInterval: 1h
secretStoreRef:
@@ -63,18 +57,13 @@ spec:
data:
GITEA_INSTANCE_URL: "https://git.neuralplatform.ai"
GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}"
CF_ACCESS_CLIENT_ID: "{{ .cf_access_client_id }}"
CF_ACCESS_CLIENT_SECRET: "{{ .cf_access_client_secret }}"
GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}"
data:
- secretKey: runner_token
remoteRef:
key: secret/data/gitea
property: neuron_technologies_runner_token
- secretKey: cf_access_client_id
- secretKey: ci_ssh_private_key
remoteRef:
key: secret/data/gitea-runner-cf-access
property: client_id
- secretKey: cf_access_client_secret
remoteRef:
key: secret/data/gitea-runner-cf-access
property: client_secret
key: secret/data/gitea
property: ci_ssh_private_key
@@ -0,0 +1,48 @@
#!/bin/sh
# git-ssh-init.sh
#
# Sets up SSH authentication for git operations inside CI build containers.
#
# How this gets invoked:
# act_runner runs each step via a non-interactive bash invocation.
# Setting BASH_ENV=/usr/local/bin/git-ssh-init.sh in act_runner's
# container.env causes bash to source this before any step's commands.
# (See servers/legion/k8s/gitea-runner/deployment.yaml.)
#
# What it does:
# 1. Writes GITEA_SSH_PRIVATE_KEY (from the runner secret) to ~/.ssh/gitea_key
# 2. Creates an ~/.ssh/config entry so git uses that key for git.neuralplatform.ai
# 3. Sets a git insteadOf rule to rewrite HTTPS Gitea URLs to SSH,
# so `actions/checkout` and any direct `git clone https://...` also use SSH
#
# Idempotent — safe to re-run on every step.
if [ -n "${GITEA_SSH_PRIVATE_KEY:-}" ]; then
mkdir -p ~/.ssh
chmod 700 ~/.ssh
# Write the private key
printf '%s\n' "${GITEA_SSH_PRIVATE_KEY}" > ~/.ssh/gitea_key
chmod 600 ~/.ssh/gitea_key
# SSH config — use this key for git.neuralplatform.ai, skip host key checking
# (build containers are ephemeral; we don't persist a known_hosts file)
cat > ~/.ssh/gitea_config << 'EOF'
Host git.neuralplatform.ai
HostName git.neuralplatform.ai
User git
IdentityFile ~/.ssh/gitea_key
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
EOF
chmod 600 ~/.ssh/gitea_config
# Point SSH at our per-job config (merge with any existing config if present)
export GIT_SSH_COMMAND="ssh -F ~/.ssh/gitea_config"
# Rewrite HTTPS Gitea URLs → SSH so `actions/checkout` and plain `git clone`
# both go through SSH without any HTTPS credential or CF Access token needed
git config --global \
url."git@git.neuralplatform.ai:".insteadOf \
"https://git.neuralplatform.ai/" 2>/dev/null || true
fi