Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,96 @@ operator's GH user; check `/etc/zeta/operator-ssh-keys.nix` for
populated pubkey array; check `git -C /etc/zeta remote -v` for the
clone URL + verify it pulls without credentials prompt.

### Bug 2a — git push prompts HTTPS basic-auth despite gh auth login (CRITICAL — blocks self-registration; empirical 2026-05-26)

Empirical anchor 2026-05-26 (2nd physical hardware-support test on
same hardware, post-Bug-1-fix re-flash):

```
[iter-5.4.0] Run gh auth login now? [Y/n]: Y
[iter-5.4.0] running 'gh auth login' (interactive)...
! First copy your one-time code: D30B-468F
Open this URL to continue in your web browser: https://github.com/login/device
■ Authentication complete.
! Authentication credentials saved in plain text
■ Logged in as AceHack
[iter-5.4.0] gh auth login: SUCCESS
...
[iter-5.4.1] ── self-registration commit+push (B-0812) ──
[iter-5.4.1] maintainer: AceHack
[iter-5.4.1] node-name: node-efe404
Switched to a new branch 'register-node-efe404-20260527T0005332'
Username for 'https://github.com': acehack
Password for 'https://acehack@github.com':
```

`gh auth login` SUCCEEDED as AceHack via device flow, but the
subsequent `git push -u origin <branch>` at iter-5.4.1 prompted for
HTTPS basic-auth. Root cause: `gh auth login` stores the token in
its own config but does NOT configure git's credential helper. Git
push goes through the default credential-store chain which doesn't
know about gh's token.

**Standard fix**: `gh auth setup-git` writes a `credential.helper`
config that delegates to `gh auth git-credential`. Once configured,
all git operations against github.com automatically use the gh token.

**Implementation**: insert `gh auth setup-git` immediately after a
successful `gh auth login` in `zeta-install.sh` Step 6.8. Failure of
setup-git is non-fatal (warning only); the prompt-for-password
behavior is the symptom indicating it didn't run.

**Acceptance**: 3rd physical test (Bug 2a fix re-flash) shows
iter-5.4.1 `git push` completes silently without basic-auth prompt;
self-registration PR URL is printed; PR is browseable on github.com.

### Bug 2b — gh ssh-key list returns empty / fails (degraded; substrate-honest WARN insufficient; empirical 2026-05-26)

Same empirical anchor 2026-05-26:

```
[iter-5.4.0] fetching operator's SSH pubkeys via 'gh ssh-key list'...
[iter-5.4.0] WARN: 'gh ssh-key list' failed; no keys written
[iter-5.4.0] (gh auth succeeded but the user has no SSH keys
[iter-5.4.0] registered with GitHub, OR the jq/tee pipe broke)
```

The WARN already covers both candidate causes but doesn't help the
operator recover. Two candidate root causes need discrimination:

1. **Auth scope missing** (most likely): `gh auth login` default
scopes are `repo, read:org, workflow, gist`. `gh ssh-key list`
requires `admin:public_key` OR `read:public_key`. Device-flow
without explicit `--scopes` will NOT request these.
2. **Operator has no SSH keys at GitHub**: returns empty list (no
error). Operator uses gh CLI auth + signed commits via gh, never
added SSH keys to their account.

**Fix path**: capture stderr from `gh ssh-key list`; discriminate
between scope-error and empty-list cases; for scope errors,
substrate-honest guidance:

```
WARN: 'gh ssh-key list' returned no keys — gh token lacks SSH-key scope
To enable SSH-from-Mac path, run on the installed system:
gh auth refresh -s admin:public_key
gh ssh-key list --json key | jq -r '.[].key' | sudo tee -a /etc/zeta/operator-authorized-keys
sudo nixos-rebuild switch # picks up operator-authorized-keys.nix
```

For empty-list (no keys at GH): substrate-honest WARN names
https://github.com/settings/keys as fix surface.

**Acceptance**: 3rd physical test shows substrate-honest WARN with
specific recovery commands; OR (if scope-mode pursued separately)
default install captures pubkeys without operator intervention.

**Scope-prompt deferred**: rather than ask for elevated
`admin:public_key` scope by default (security tradeoff), the install
shows substrate-honest fallback. Future B-NNNN candidate:
opt-in flag `--with-ssh-key-scope` for operators who want one-shot
auto-population.

### CORE REQUIREMENT (operator 2026-05-26 reframing)

> "also i should not have to log in for any of this to start that
Expand Down
56 changes: 50 additions & 6 deletions full-ai-cluster/usb-nixos-installer/zeta-install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,25 @@ if [[ "$GH_AUTH_REPLY" =~ ^[Yy]$ ]]; then
GH_AUTH_OK=1
echo
echo "[iter-5.4.0] gh auth login: SUCCESS"

# ── B-0835 Bug 2a fix: wire git to use gh token for HTTPS pushes ──
# `gh auth login` stores the token but does NOT configure git's
# credential helper. Without this step, subsequent `git push` to
# https://github.com/... prompts for HTTPS basic-auth (username +
# password) — empirically observed 2026-05-26 physical hardware-
# support test where iter-5.4.1 self-registration `git push -u
# origin <branch>` prompted operator for "Password for
# 'https://acehack@github.com':" despite gh auth login succeeding
# as AceHack moments earlier. `gh auth setup-git` writes a
# credential.helper entry that delegates to `gh auth git-credential`
# so git push picks up the gh token automatically.
echo "[iter-5.4.0] wiring git credential helper to use gh token..."
if gh auth setup-git 2>&1 | tail -3; then
echo "[iter-5.4.0] git credential helper: configured"
else
echo "[iter-5.4.0] WARN: 'gh auth setup-git' failed; subsequent git push may prompt for password"
fi

echo "[iter-5.4.0] fetching operator's SSH pubkeys via 'gh ssh-key list'..."
KEY_DST_DIR=/mnt/etc/zeta
sudo mkdir -p "$KEY_DST_DIR"
Expand All @@ -644,20 +663,45 @@ if [[ "$GH_AUTH_REPLY" =~ ^[Yy]$ ]]; then
# the `key` field which contains the standard authorized_keys line
# (algo + base64-pubkey; no comment). Each gets a comment appended
# so the operator can identify it later: "gh-key-<id>".
if gh ssh-key list --json id,key,title 2>/dev/null \
#
# B-0835 Bug 2b fix: substrate-honest discrimination of failure modes.
# Capture stderr so we can distinguish (a) auth-scope error from
# (b) empty key list from (c) jq/tee pipe break. Empirically 2026-05-26:
# device-flow `gh auth login` only requests default scopes
# (`repo, read:org, workflow, gist`); `gh ssh-key list` requires
# `admin:public_key` OR `read:public_key` which are NOT in defaults.
# If scope is the issue, the WARN tells operator how to refresh.
SSH_KEY_ERR_FILE=$(mktemp -t zeta-ghkey-err.XXXXXX)
if gh ssh-key list --json id,key,title 2>"$SSH_KEY_ERR_FILE" \
| jq -r '.[] | "\(.key) gh-key-\(.id)-\(.title // "")"' \
| sudo tee "$KEY_DST" >/dev/null; then
sudo chmod 0644 "$KEY_DST"
GH_KEY_COUNT="$(wc -l < "$KEY_DST" | tr -d ' ')"
echo "[iter-5.4.0] wrote $GH_KEY_COUNT key(s) to $KEY_DST"
echo "[iter-5.4.0] the operator-authorized-keys.nix module will pick"
echo "[iter-5.4.0] them up during nixos-install (next step)"
if [ "$GH_KEY_COUNT" -gt 0 ]; then
echo "[iter-5.4.0] wrote $GH_KEY_COUNT key(s) to $KEY_DST"
echo "[iter-5.4.0] the operator-authorized-keys.nix module will pick"
echo "[iter-5.4.0] them up during nixos-install (next step)"
else
# Empty key list — either no keys at GitHub OR scope missing.
# Check stderr for scope error to discriminate.
if grep -qE "(scope|insufficient|admin:public_key|read:public_key)" "$SSH_KEY_ERR_FILE" 2>/dev/null; then
echo "[iter-5.4.0] WARN: 'gh ssh-key list' returned no keys — gh token lacks SSH-key scope"
echo "[iter-5.4.0] To enable SSH-from-Mac path, run on the installed system:"
echo "[iter-5.4.0] gh auth refresh -s admin:public_key"
echo "[iter-5.4.0] gh ssh-key list --json key | jq -r '.[].key' | sudo tee -a /etc/zeta/operator-authorized-keys"
echo "[iter-5.4.0] sudo nixos-rebuild switch # picks up operator-authorized-keys.nix"
else
echo "[iter-5.4.0] WARN: 'gh ssh-key list' returned no keys — operator has no SSH keys registered at GitHub"
echo "[iter-5.4.0] SSH-from-Mac fallback: add keys at https://github.com/settings/keys"
echo "[iter-5.4.0] then on the installed system, re-run the gh ssh-key list step (see B-0835 Bug 2b)"
fi
fi
else
echo "[iter-5.4.0] WARN: 'gh ssh-key list' failed; no keys written"
echo "[iter-5.4.0] (gh auth succeeded but the user has no SSH keys"
echo "[iter-5.4.0] registered with GitHub, OR the jq/tee pipe broke)"
echo "[iter-5.4.0] stderr: $(head -3 "$SSH_KEY_ERR_FILE" 2>/dev/null | tr '\n' ' ')"
GH_KEY_COUNT=0
fi
rm -f "$SSH_KEY_ERR_FILE" 2>/dev/null || true
else
echo
echo "[iter-5.4.0] gh auth login FAILED or was cancelled; skipping"
Expand Down
Loading