Skip to content

fix: use SSH_AGENT_FORWARDING context option in generated ssh config - #899

Merged
skevetter merged 1 commit into
mainfrom
ssh-agent-forwarding
Aug 7, 2026
Merged

fix: use SSH_AGENT_FORWARDING context option in generated ssh config#899
skevetter merged 1 commit into
mainfrom
ssh-agent-forwarding

Conversation

@skevetter

@skevetter skevetter commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The ~/.ssh/config ForwardAgent line was hardcoded to yes, ignoring the SSH_AGENT_FORWARDING context option (already respected by devsy's own proxied SSH client).
  • addSSHOptions now writes ForwardAgent yes/no based on the context setting, threaded through SSHConfigParamsaddHostParams.

Fixes #898

Summary by CodeRabbit

  • New Features
    • Added configurable SSH agent forwarding for workspaces.
    • SSH connections now respect whether agent forwarding is enabled or disabled.
    • The setting is consistently applied during initial connections, tunnel-based connections, and SSH reconfiguration.
  • Bug Fixes
    • Prevented SSH agent forwarding from being enabled automatically when it is turned off in workspace settings.

The ~/.ssh/config entries Devsy writes hardcoded ForwardAgent yes,
ignoring the SSH_AGENT_FORWARDING context option. Disabling agent
forwarding in the context had no effect on the generated config,
breaking SSH access for anyone who turned the option off.
@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for devsydev canceled.

Name Link
🔨 Latest commit 542ce5b
🔍 Latest deploy log https://app.netlify.com/projects/devsydev/deploys/6a75e084b2de87000896c098

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

SSH agent-forwarding settings now flow from workspace context into SSH configuration generation. Generated proxy-command and tunnel configurations emit ForwardAgent yes or ForwardAgent no according to the setting. Tests cover both states.

Changes

SSH Agent Forwarding

Layer / File(s) Summary
SSH configuration generation
pkg/ssh/config.go
SSHConfigParams and host parameters carry agent forwarding. Proxy-command and tunnel configurations now emit the selected ForwardAgent value.
Workspace setting propagation
cmd/workspace/up/configure.go
Workspace setup and tunnel reconfiguration pass the context agent-forwarding setting into SSH configuration.
Agent-forwarding coverage
pkg/ssh/config_test.go, pkg/ssh/config_tunnel_test.go
Fixtures pass agent-forwarding values. Tests cover enabled forwarding and expect ForwardAgent no when disabled.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the fix: generated SSH configuration now uses the SSH_AGENT_FORWARDING context option.
Linked Issues check ✅ Passed The changes propagate SSH agent forwarding and generate ForwardAgent no when disabled, addressing issue #898 requirements.
Out of Scope Changes check ✅ Passed All changes support SSH agent-forwarding configuration and its tests; no unrelated code changes are identified.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@netlify

netlify Bot commented Aug 7, 2026

Copy link
Copy Markdown

Deploy Preview for images-devsy-sh canceled.

Name Link
🔨 Latest commit 542ce5b
🔍 Latest deploy log https://app.netlify.com/projects/images-devsy-sh/deploys/6a75e084b37d7e0008bf284b

@github-actions github-actions Bot added the size/l label Aug 7, 2026
@skevetter skevetter changed the title fix: honor SSH_AGENT_FORWARDING context option in generated ssh config fix: use SSH_AGENT_FORWARDING context option in generated ssh config Aug 7, 2026
@skevetter
skevetter marked this pull request as ready for review August 7, 2026 17:08
@skevetter
skevetter marked this pull request as draft August 7, 2026 17:28
@skevetter
skevetter marked this pull request as ready for review August 7, 2026 17:50

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
pkg/ssh/config_test.go (1)

304-326: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Cover regeneration with forwarding disabled.

The new disabled case starts with an empty configuration. It does not verify that regeneration replaces an existing generated block containing ForwardAgent yes. Add a case with an existing Devsy host for the same workspace, set agentForwarding to false, and assert that the regenerated block contains ForwardAgent no.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/ssh/config_test.go` around lines 304 - 326, Add a regeneration test
alongside the existing agent-forwarding cases in the test table, using an
existing Devsy-generated host block for the same workspace that contains
ForwardAgent yes, then set agentForwarding to false and assert the regenerated
block replaces it with ForwardAgent no.
pkg/ssh/config_tunnel_test.go (1)

172-180: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Add a disabled tunnel-mode test.

All tunnel fixtures set agentForwarding to true. The disabled case in pkg/ssh/config_test.go covers the proxy-command path only. Add a tunnel-mode case with agentForwarding: false and assert ForwardAgent no.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/ssh/config_tunnel_test.go` around lines 172 - 180, Add a disabled
tunnel-mode case to TestBuildTunnelConfigLines using agentForwarding: false, and
assert the generated configuration contains ForwardAgent no. Keep the existing
enabled tunnel fixture and assertions unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@pkg/ssh/config.go`:
- Around line 178-184: Update the SSH configuration insertion flow around
sshConfigBuilder.addSSHOptions and findInsertPosition so generated Devsy host
entries are placed before any earlier matching generic or override Host block,
ensuring their ForwardAgent value takes precedence. Add a fixture covering an
existing Host * ForwardAgent yes rule and verify the generated Devsy host block
is inserted ahead of it.

---

Nitpick comments:
In `@pkg/ssh/config_test.go`:
- Around line 304-326: Add a regeneration test alongside the existing
agent-forwarding cases in the test table, using an existing Devsy-generated host
block for the same workspace that contains ForwardAgent yes, then set
agentForwarding to false and assert the regenerated block replaces it with
ForwardAgent no.

In `@pkg/ssh/config_tunnel_test.go`:
- Around line 172-180: Add a disabled tunnel-mode case to
TestBuildTunnelConfigLines using agentForwarding: false, and assert the
generated configuration contains ForwardAgent no. Keep the existing enabled
tunnel fixture and assertions unchanged.
🪄 Autofix

✅ Autofix completed


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 579a33c6-2f6a-4a28-9347-75aea774a1ca

📥 Commits

Reviewing files that changed from the base of the PR and between 49e1812 and 542ce5b.

📒 Files selected for processing (4)
  • cmd/workspace/up/configure.go
  • pkg/ssh/config.go
  • pkg/ssh/config_test.go
  • pkg/ssh/config_tunnel_test.go

Comment thread pkg/ssh/config.go
Comment on lines +178 to +184
func (b *sshConfigBuilder) addSSHOptions(provider string, agentForwarding bool) *sshConfigBuilder {
forwardAgent := "no"
if agentForwarding {
forwardAgent = "yes"
}
b.lines = append(b.lines,
" ForwardAgent yes",
" ForwardAgent "+forwardAgent,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 20 'findInsertPosition|mergeSSHConfig|Host \*|ForwardAgent' --glob '*.go' .

tmp="$(mktemp)"
trap 'rm -f "$tmp"' EXIT
cat > "$tmp" <<'EOF'
Host *
  ForwardAgent yes
Host testhost
  ForwardAgent no
EOF

if command -v ssh >/dev/null 2>&1; then
  actual="$(ssh -G -F "$tmp" testhost 2>/dev/null | awk '$1 == "forwardagent" {print $2; exit}')"
  test "$actual" = no
fi

Repository: devsy-org/devsy

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== packages =="
find . -maxdepth 3 -type f -name 'go.mod' | xargs -r -n1 sh -c 'echo "--- $0"; sed -n "1,120p" "$0"'

echo
echo "== relevant config.go section =="
sed -n '258,321p' pkg/ssh/config.go

echo
echo "== call sites for addHostSection / mergeSSHConfig / findInsertPosition =="
rg -n -C 3 'addHostSection|mergeSSHConfig|findInsertPosition|addHostParams' --glob '*.go' .

echo
echo "== fixture-style SSH precedence probe with ssh -G =="
tmp="$(mktemp -d)"
trap 'rm -rf "$tmp"' EXIT

cat > "$tmp/hostfile" <<'EOF'
Host *
  ForwardAgent yes
Host testhost
  ForwardAgent no
EOF

if command -v ssh >/dev/null 2>&1; then
  echo "--- ssh -G hostfile prefix-only testhost ---"
  actual="$(ssh -G -F "$tmp/hostfile" testhost 2>/dev/null | awk '$1 == "forwardagent" {print tolower($2); exit}')"
  echo "forwardagent=$actual"
  if [ "$actual" != "no" ]; then
    echo "RESULT: ssh -G keeps ForwardAgent=yes for testhost when Host * precedes host-specific ForwardAgent no"
    exit 3
  else
    echo "RESULT: ssh -G applied host-specific ForwardAgent=no"
  fi
else
  echo "ssh command unavailable"
fi

Repository: devsy-org/devsy

Length of output: 17817


🌐 Web query:

OpenSSH ssh_config Host blocks first last more specific override ForwardAgent

💡 Result:

In OpenSSH configuration files, for each parameter, the first obtained value is used [1][2]. Because SSH parses the configuration file from top to bottom, this means that more specific Host or Match blocks should be placed at the beginning of the file, while more general or default configurations (such as those using Host *) should be placed at the end [3][1][4]. Regarding ForwardAgent and other configuration directives, if multiple Host or Match blocks match the target host, the first block encountered that defines a value for a specific parameter will take precedence [2][5]. Subsequent blocks that match the same host will not override that parameter [1][6][5]. To ensure a specific configuration (like ForwardAgent yes) applies to a specific host while having different settings for other hosts, you must structure your file so the specific host block appears before any broader blocks that might otherwise set a different value for the same parameter [2][4][5]. If you have a general block that sets a parameter you want to override for a specific host, you must either move the specific block above the general one or, if that is not possible, explicitly set the parameter in the specific block to the desired value (e.g., ForwardAgent yes) [2][5].

Citations:


Keep the generated Devsy host block before any earlier matching generic rule.

findInsertPosition inserts before the first existing Host line, so an existing Host * ForwardAgent yes block follows the generated Host testhost ForwardAgent no. Because SSH uses the first value for a matching option, ForwardAgent no is ignored and forwarding remains enabled. Add a fixture with an earlier generic Host * ForwardAgent yes, or prevent adding generic/override blocks before Devsy host entries.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/ssh/config.go` around lines 178 - 184, Update the SSH configuration
insertion flow around sshConfigBuilder.addSSHOptions and findInsertPosition so
generated Devsy host entries are placed before any earlier matching generic or
override Host block, ensuring their ForwardAgent value takes precedence. Add a
fixture covering an existing Host * ForwardAgent yes rule and verify the
generated Devsy host block is inserted ahead of it.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown

Fixes Applied Successfully

Fixed 1 file(s) based on 1 unresolved review comment.

A stacked PR containing fixes has been created.

  • Stacked PR: #901
  • Files modified:
  • pkg/ssh/config_test.go

Time taken: 6m 36s

@skevetter
skevetter merged commit bc4c5f4 into main Aug 7, 2026
67 checks passed
@skevetter
skevetter deleted the ssh-agent-forwarding branch August 7, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Disabling ssh agent forwarding still outputs forwardagent yes in ssh config

1 participant