Skip to content

Let workspaces use git over https when ssh-agent forwarding is off - #17

Merged
renatoathaydes merged 3 commits into
mainfrom
feat/git-ssh-to-https
Oct 19, 2026
Merged

renatoathaydes merged 3 commits into
mainfrom
feat/git-ssh-to-https

Conversation

@renatoathaydes

Copy link
Copy Markdown
Collaborator

Why

Agents running unattended in a workspace lose git access as soon as the user's laptop sleeps. Both ways DevPod provides git credentials depend on the laptop:

  • ssh remotes use the ssh-agent forwarded over the devpod ssh connection;
  • https remotes use a credential helper that calls back to the laptop.

SSH can't fix this without putting private keys in the workspace. This PR makes git use https instead, with credentials that the dev container provides. DevPod doesn't handle tokens itself, so it stays agnostic of GitHub, Bitbucket and other hosts.

What

  • New context option GIT_SSH_TO_HTTPS (auto | true | false, default auto). auto turns it on when SSH_AGENT_FORWARDING=false.

    • It's resolved on devpod up and passed to the container in CLIOptions (two new fields; older agents ignore them).
  • What container setup does when it's on. This runs before any lifecycle hook:

    • It collects the workspace source URL and the remote.*.url / submodule.*.url entries of the repository in the workspace folder. It reads the config files directly, so it isn't affected by safe.directory checks, and it follows worktree .git files.
    • It writes url."https://<host>/".insteadOf rules for the URL's own ssh prefix, git@<host>: and ssh://git@<host>/.
    • The rules go into /var/devpod/ssh-to-https.gitconfig, which is included from the system git config.
    • The repository's .git/config is not touched. That matters for local-folder workspaces, where it is the user's own checkout.
    • When the option is off, the next up removes the file and the include.
  • New context option GIT_SSH_TO_HTTPS_HOSTS: extra hosts, or explicit from=to rewrites for servers whose ssh and https paths differ (e.g. Bitbucket Data Center's :7999/ vs /scm/).

  • Fix: removeCredentialHelper used to delete the whole [credential] section of the global gitconfig at the end of a session, including helpers the user or dev container added. It now removes only DevPod's own helper line.

  • Docs: a new page, Run Workspaces Unattended, explaining:

    • what depends on the laptop;
    • exactly what DevPod changes;
    • the options to set;
    • token choices for GitHub and Bitbucket;
    • an env-var credential helper script (tested with git credential fill) and a gh alternative;
    • the inactivity timeout;
    • how to verify the setup.

    The credentials page links to it. CHANGELOG updated.

Testing

  • New unit tests:
    • URL prefix parsing;
    • rewrite generation, including explicit overrides;
    • config formatting;
    • a test that runs real git remote get-url --push against the generated config, covering ssh, ssh://…:7999 with an explicit rewrite, and https remotes;
    • remote discovery in a repo and in a worktree;
    • the credential-helper removal;
    • the auto resolution.
  • go test ./pkg/... ./cmd/..., go vet and golangci-lint v1.60.1 pass locally. The docs build passes with no new broken links or anchors.
  • Not done: an end-to-end devpod up against Docker. Docker wasn't available locally.

🤖 Generated with Claude Code

renatoathaydes and others added 3 commits October 19, 2026 10:47
A forwarded ssh-agent and DevPod's git credential helper both need the
user's computer, so agents running unattended in a workspace lose git
access when the laptop sleeps.

The new GIT_SSH_TO_HTTPS context option (auto by default, which enables
it when SSH_AGENT_FORWARDING is false) writes url.<base>.insteadOf rules
during container setup that rewrite the ssh urls of the workspace's
hosts to https. The rules live in /var/devpod/ssh-to-https.gitconfig,
included from the system git config, so the repository's .git/config is
left alone. GIT_SSH_TO_HTTPS_HOSTS adds hosts and explicit from=to
rewrites for servers with different ssh and https paths. Credentials are
left to the dev container, so DevPod stays agnostic of git hosts.

Removing DevPod's credential helper at the end of a session no longer
deletes other helpers in the [credential] section of the global git
config, such as one the dev container configured.

Documents how to set up a workspace that keeps working unattended.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Starts a workspace from a git repo with an ssh remote and an ssh submodule
url while SSH_AGENT_FORWARDING is off, checks that git in the container
uses https for both and that the repo on the host is untouched, then sets
GIT_SSH_TO_HTTPS=false and checks that the rewrites are removed. The test
runs in its own context so its options don't leak into other tests. It is
labelled up-docker, so CI runs it with the other docker tests, and
git-ssh-to-https to run it on its own.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Send GIT_SSH_TO_HTTPS as "true"/"false" and leave the rewrites alone when
  it is empty, so a container started by an older CLI keeps them. devpod ssh
  now also sends the context's options, so a stopped container that it
  starts again is set up as devpod up would.
- Honour SSH_AGENT_FORWARDING=false for the container: the setup tunnel no
  longer forwards the ssh-agent into lifecycle commands, and the ssh config
  entry gets ForwardAgent no. The agent on the machine still gets it to
  clone the source.
- Read the remotes of a local folder source on the host, so worktrees and
  submodule checkouts, whose git dir isn't mounted, get rewrites too.
- Reject GIT_SSH_TO_HTTPS_HOSTS entries that are neither a host nor a
  from=https://... rewrite, and handle scp-like IPv6 urls and
  git@host:/path remotes.
- Add the workspace folder to the system safe.directory, so git works with
  folders that aren't chowned (Docker Desktop on macOS and Windows).
- Don't save CLI options in the agent's workspace config, as intended.
- Extend the e2e test with a container restart, agent forwarding checks,
  no safe.directory workaround, and a worktree source.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@renatoathaydes
renatoathaydes merged commit 576a044 into main Oct 19, 2026
19 checks passed
@renatoathaydes
renatoathaydes deleted the feat/git-ssh-to-https branch October 19, 2026 09:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant