Skip to content

Comments

🤖 feat: add SSH agent forwarding support#2560

Closed
coadler wants to merge 9 commits intocoder:mainfrom
coadler:ssh-forward-agent
Closed

🤖 feat: add SSH agent forwarding support#2560
coadler wants to merge 9 commits intocoder:mainfrom
coadler:ssh-forward-agent

Conversation

@coadler
Copy link
Contributor

@coadler coadler commented Feb 23, 2026

Summary

Add SSH agent forwarding support to SSH workspace provider, allowing git operations, nested SSH connections, and other tools that rely on SSH_AUTH_SOCK to work on remote hosts.

Background

SSH workspaces currently don't forward the user's SSH agent to the remote host. SSH_AUTH_SOCK is read locally only for authenticating Mux's own connection — it's never forwarded to remote sessions. Docker and Devcontainer runtimes already have a "Share credentials" checkbox; SSH workspaces needed an equivalent "Forward SSH agent" toggle.

Implementation

Adds a forwardAgent boolean field threaded through the full stack:

  • Schema & TypesforwardAgent: z.boolean().optional() on the SSH runtime schema, forwardAgent?: boolean on ParsedRuntime SSH variant
  • BackendforwardAgent on SSHConnectionConfig, threaded through runtimeFactory
  • OpenSSH Transport-A flag added to buildSSHArgs() when enabled
  • SSH2 TransportagentForward: true passed at connection level in SSH2ConnectionPool.connect() (correct placement for the ssh2 library — it's a ConnectConfig option, not per-exec/shell)
  • Frontend HookforwardAgent added to SshRuntimeConfig/SshRuntimeState, persisted via readRuntimeConfigFrom/setLastRuntimeConfig
  • UI — "Forward SSH agent" checkbox rendered for SSH mode (hidden when Coder is selected), following the existing CredentialSharingCheckbox pattern

9 files changed, +50/-4 lines.

Additionally, all SSH runtime update call sites in CreationControls.tsx preserve forwardAgent across mode switches and host edits, and both makeConnectionKey implementations (SSH2 and OpenSSH pools) include forwardAgent in the connection identity to prevent pooled connection reuse with mismatched forwarding state.


Generated with mux • Model: anthropic:claude-opus-4-6 • Thinking: high • Cost: $3.74

Add forwardAgent toggle to SSH workspace runtime so users can forward
their local SSH agent to the remote host (enables git clone/push over
SSH on remote machines).

Changes:
- Schema: add forwardAgent boolean to SSH runtime schema
- Types: add forwardAgent to ParsedRuntime SSH variant and buildRuntimeConfig
- SSHConnectionConfig: add forwardAgent field
- runtimeFactory: pass forwardAgent through to SSH transports
- OpenSSHTransport: add -A flag to ssh args when forwardAgent is set
- SSH2ConnectionPool: pass agentForward:true in connect options
- useDraftWorkspaceSettings: persist/restore forwardAgent in SSH config
- CreationControls: add 'Forward SSH agent' checkbox for SSH mode
# Conflicts:
#	src/node/runtime/SSH2ConnectionPool.ts
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b9e70580d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b9e70580d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

… keys

Fix two bugs found by Codex review:

1. In CreationControls.tsx, three call sites that construct SSH runtime
   objects were missing the forwardAgent field, causing it to be
   silently reset to false when the runtime was persisted:
   - Auto-switch to SSH mode (disabled runtime guard)
   - SSH tab click handler
   - Host text field onChange handler

2. In both SSH2ConnectionPool.ts and sshConnectionPool.ts, the
   makeConnectionKey function did not include forwardAgent in the
   connection pool key. This meant connections with different
   agent-forwarding settings could incorrectly share a pooled
   connection.
@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

1 similar comment
@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d3599eeca5

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

- writeSshRuntimeConfig: skip persisting forwardAgent when undefined,
  so mode switches and Coder selection don't overwrite the stored value
- CreationControls: pass undefined (not false) for forwardAgent when
  the current mode isn't SSH, preventing destructive overwrites
@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0f0ea99b8e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

When switching from a non-SSH runtime to SSH, forwardAgent was set to
undefined in the in-memory state. While writeSshRuntimeConfig correctly
skips writing undefined values (preserving persisted state), the
in-memory runtime object used for workspace creation lacked forwardAgent,
silently disabling agent forwarding.

Follow the same fallback pattern used for sshHost: expose
sshForwardAgentFallback from useDraftWorkspaceSettings (sourced from
lastSshState.forwardAgent), thread it through useCreationWorkspace, and
use it in CreationControls when switching to SSH from another mode.
@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 03df9af259

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4949250edb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3bf5a05dc3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@coadler
Copy link
Contributor Author

coadler commented Feb 23, 2026

@codex review

@coadler coadler closed this Feb 23, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13ffeff458

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +675 to +677
const isNonCoderSsh =
selectedRuntime.mode === RUNTIME_MODE.SSH &&
selectedRuntime.host !== CODER_RUNTIME_PLACEHOLDER
? selectedRuntime.host
: props.sshHostFallback;
selectedRuntime.host !== CODER_RUNTIME_PLACEHOLDER;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Require coder absence in non-Coder SSH detection

The isNonCoderSsh predicate only checks whether the host is not coder://, so Coder runtimes that use a concrete host (for example existing workspaces like name.coder) are treated as plain SSH. In that case this branch pulls sshForwardAgent from selectedRuntime.forwardAgent (typically undefined for Coder flows) instead of sshForwardAgentFallback, so switching from Coder back to SSH can silently clear the user’s forwarding setting and break agent-dependent Git/SSH commands until manually re-enabled.

Useful? React with 👍 / 👎.

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