fix: edge-control: deregister has no ownership check — any authorized SSH key can take over any project (#1091)
All checks were successful
ci/woodpecker/push/ci Pipeline was successful
ci/woodpecker/push/nomad-validate Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/edge-subpath Pipeline was successful
ci/woodpecker/pr/nomad-validate Pipeline was successful
ci/woodpecker/pr/smoke-init Pipeline was successful

- do_deregister now accepts <project> <pubkey> and verifies the caller's
  pubkey matches the stored pubkey before removing the registration
- Returns {"error":"pubkey mismatch"} on failure without revealing the
  stored pubkey
- dispatch in main() updated to parse pubkey from deregister command args
- bin/disinto deregister subcommand reads tunnel_key.pub and sends it
  as ownership proof over SSH

The user-facing CLI (disinto edge deregister <project>) is unchanged —
the pubkey is automatically sourced from secrets/tunnel_key.pub.
This commit is contained in:
Claude 2026-04-21 05:51:35 +00:00
parent 19ead14ede
commit d15ebf2bd1
2 changed files with 38 additions and 14 deletions

View file

@ -2885,12 +2885,23 @@ disinto_edge() {
edge_host="${EDGE_HOST:-edge.disinto.ai}"
fi
# Read tunnel pubkey for ownership proof
local secrets_dir="${FACTORY_ROOT}/secrets"
local tunnel_pubkey="${secrets_dir}/tunnel_key.pub"
if [ ! -f "$tunnel_pubkey" ]; then
echo "Error: tunnel keypair not found at ${tunnel_pubkey}" >&2
echo "Cannot prove ownership without the tunnel public key." >&2
exit 1
fi
local pubkey
pubkey=$(tr -d '\n' < "$tunnel_pubkey")
# SSH to edge host and deregister
echo "Deregistering tunnel for ${project} on ${edge_host}..."
local response
response=$(ssh -o StrictHostKeyChecking=accept-new -o BatchMode=yes \
"disinto-register@${edge_host}" \
"deregister ${project}" 2>&1) || {
"deregister ${project} ${pubkey}" 2>&1) || {
echo "Error: failed to deregister tunnel" >&2
echo "Response: ${response}" >&2
exit 1