Ships step 1 of the #1933 fleet-wide GH_TOKEN refresh fix.
The plugin's v0.0.0-20260416194734-2cd28737f845 predates the Mutator.Token()
method added in plugin-repo PR #1 (merged 2026-04-17). Monorepo's
workspace-server/pkg/provisionhook/mutator.go:218 has been emitting
`provisionhook: no Token method on "github-app-auth"` on every boot and
the reflection-fallback at mutator.go:216 is doing extra work every
time a workspace requests a fresh GH token.
This is the one-line pin bump:
v0.0.0-20260416194734-2cd28737f845 → v0.0.0-20260421064811-7d98ae51e31d
Effect: direct-interface path (not the reflection fallback) gets taken,
log noise goes away. Does NOT fix the actual 60-min GH_TOKEN death —
steps 2–5 of #1933 (credential helper install, git config wire-up,
runtime auth context, periodic refresh) are separate, larger PRs.
Verified: workspace-server/go build ./... passes with the new pin.
Ref: #1933
Closes the last CP-provisioned-workspace gap: Terminal tab now works
for workspaces running on separate EC2 instances. Follow-up to
#1531 which added instance_id persistence.
How it works:
- HandleConnect checks workspaces.instance_id
- Empty → existing local Docker path (unchanged)
- Set → spawn `aws ec2-instance-connect ssh --connection-type eice
--instance-id X --os-user ec2-user -- docker exec -it ws-Y
/bin/bash` under creack/pty, bridge pty ↔ canvas WebSocket
Why subprocess AWS CLI instead of native AWS SDK:
- EIC Endpoint tunnel needs a signed WebSocket with specific framing
- aws-cli v2 implements it correctly; reimplementing in Go is ~500
lines of crypto + WS protocol work for zero user-visible benefit
- Tenant image picks up 1MB of aws-cli + openssh-client via apk
Handler design:
- sshCommandFactory is a var so tests can stub it (no real aws calls)
- Context cancellation propagates both ways (WS close → kill ssh;
ssh exit → close WS)
- User-visible error points at docs/infra/workspace-terminal.md when
EIC wiring is incomplete (common bootstrap failure)
Tests:
- TestHandleConnect_RoutesToRemote — instance_id in DB → CP branch
- TestHandleConnect_RoutesToLocal — empty instance_id → local branch
- TestSshCommandFactory_BuildsEICCommand — argv shape regression guard
Dockerfile.tenant: + openssh-client + aws-cli (Alpine main repo)
Refs: #1528, #1531
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>