Skip to content

feat(acq): acq restore re-derives the msb --vsock route (SSH signing survives reboot) #501

Open

Description

@mogul

Part of #493.

Summary

Have acq restore re-derive the msb --vsock route from the current host SSH-agent socket, so SSH commit signing survives a reboot / recreate without acq rm. This closes the gap ADR-0021 explicitly left as future work.

Background (ADR-0021)

On msb, host SSH-agent forwarding is a --vsock $SSH_AUTH_SOCK:3552/stream route plus an in-guest socat bridge. The socat bridge is already re-plumbed on acq start/re-attach, but the --vsock route itself is create-time only and is never re-derived. After a host reboot the host agent gets a new socket path, the persisted route's host endpoint is dead, the bridge connects to a dead endpoint, and the only remedy today is acq rm + recreate. ADR-0021: "Refreshing the route automatically on resume is left as future work pending an msb capability to update a --vsock route in place."

The capability now exists

msb restore takes --vsock PATH:PORT[/stream|/dgram] and re-binds the host endpoint at restore time. So a snapshot-backed recreate can supply the current $SSH_AUTH_SOCK, producing a fresh, live route.

Scope

  • In the msb acq_backend_restore path, derive the --vsock route from the current host $SSH_AUTH_SOCK (reusing the existing route-construction helper) rather than any value captured in the snapshot.
  • Restart the in-guest socat bridge from the marker as the existing start path already does.
  • Warn (don't silently proceed) when no host agent socket is available at restore, consistent with the existing unreachable-agent warning.

Backend applicability

msb-only. sbx is unsupported for snapshot/restore (see parent), so this does not apply there.

Acceptance

  • After acq snapshot → host reboot → acq restore, git SSH signing works with no acq rm.

Activity

  1. basiliskus commented on Oct 7, 2026

    @basiliskus
    Contributor

    A way to survive reboots without waiting on restore: give msb a stable host path that acq owns instead of the raw $SSH_AUTH_SOCK. At create, acq would pass --vsock ~/.acq/ssh-agent/<sandbox>.sock:3552/stream, where that path is a symlink, and on every acq start/restart/run re-point the symlink at the current $SSH_AUTH_SOCK before starting the bridge. The route then never goes stale.

    Tested on macOS with msb 0.7.7: msb create --vsock <symlink>:3552/stream stores the symlink path as host_socket, and msb dials it per guest connection and follows the symlink. With the guest bridge up, ssh-add -l listed the host keys; after re-pointing the symlink on the host to a second, empty agent it printed "The agent has no identities"; re-pointing back listed the keys again — no sandbox restart in between.

    One catch in acq today: acq_host_socket_forwards runs canonicalize_path on $SSH_AUTH_SOCK (and on ACQ_FORWARD_HOST_SOCKETS entries), so a symlink is resolved to its target before msb create and the stable path is lost. The managed symlink would have to skip that step.

    Context: on this host, two sandboxes created before a reboot carry dead /private/var/run/com.apple.launchd.*/Listeners routes (vsock::muxer: custom vsock service rejected port 3552: No such file or directory), while one created after the reboot works. _acq_msb_warn_if_agent_unreachable fires correctly; recreate is the only fix today.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions