Skip to content

fix(credentials): preserve non-default SSH ports in remote URLs#5945

Merged
kodiakhq[bot] merged 3 commits into
flipt-io:v2from
immanuwell:fix/ssh-remote-nondefault-port
Jun 8, 2026
Merged

fix(credentials): preserve non-default SSH ports in remote URLs#5945
kodiakhq[bot] merged 3 commits into
flipt-io:v2from
immanuwell:fix/ssh-remote-nondefault-port

Conversation

@immanuwell

@immanuwell immanuwell commented May 30, 2026

Copy link
Copy Markdown
Contributor

Small follow-up to #5130.

When Flipt normalizes ssh://git@host:2222/group/repo.git, it rewrites it to git@host:2222:group/repo.git.
That changes the meaning of the remote, so Git no longer uses port 2222 and sync can fail

Fix is pretty small:

  • keep SCP style for the default SSH port
  • keep ssh:// form for non-default ports

Repro

  1. Configure a Git environment with SSH creds and remote: ssh://[email protected]:2222/group/repo.git
  2. Start Flipt or trigger a remote sync
  3. Before this patch, the remote gets normalized to [email protected]:2222:group/repo.git
  4. Git treats that as SCP style, not an SSH URL with port 2222, so the sync goes to the wrong port and blows up

Tests: go test ./...

closes #5946

@immanuwell
immanuwell requested a review from a team as a code owner May 30, 2026 09:02
@dosubot dosubot Bot added the size:S This PR changes 10-29 lines, ignoring generated files. label May 30, 2026
@dosubot

dosubot Bot commented May 30, 2026

Copy link
Copy Markdown

Documentation Updates

1 document(s) were updated by changes in this PR:

Flipt SCM Providers and Git Integration
View Changes
@@ -47,7 +47,7 @@
 
 **SSH Remote URL Normalization and Port Handling:**
 
-When using SSH credentials, Flipt automatically normalizes the configured remote URL to the correct SCP-style format (`git@host:path`). Flipt supports SSH URLs with non-standard ports, such as `git@host:2222:owner/repo.git` or `ssh://git@host:2222/owner/repo.git`. The port is preserved in the normalized SCP-style URL for all SSH operations.
+When using SSH credentials, Flipt automatically normalizes the configured remote URL to the correct format for SSH operations. For the default SSH port (22), Flipt converts URLs to SCP-style format (`git@host:path`). For non-default SSH ports, Flipt preserves the `ssh://` protocol format (`ssh://git@host:port/path`) to ensure Git correctly uses the specified port during sync operations.
 
 You may specify the remote as HTTPS, HTTP, `ssh://`, SCP-style, or host/path format. Flipt will convert it as needed for Git operations. If the SSH user in your credentials differs from the user in the remote URL, Flipt will raise an error to prevent misconfiguration.
 
@@ -220,7 +220,7 @@
 - SCP-style with port: `[email protected]:2222:org/repo.git`
 - Host/path: `github.com/org/repo.git`
 
-Flipt will automatically normalize the URL to the correct SCP-style format required for SSH operations, preserving any non-standard port. The SSH user is taken from your credentials configuration (defaults to `git` if not specified). If the remote URL already contains a user (e.g., `[email protected]:org/repo.git`), it must match the user in your credentials, otherwise Flipt will fail to start with an error indicating the conflict.
+Flipt will automatically normalize the URL to the correct format for SSH operations. For the default SSH port (22), URLs are converted to SCP-style format (`git@host:path`). For non-default ports, the `ssh://` protocol format is preserved (`ssh://git@host:port/path`) to ensure Git correctly uses the specified port. The SSH user is taken from your credentials configuration (defaults to `git` if not specified). If the remote URL already contains a user (e.g., `[email protected]:org/repo.git`), it must match the user in your credentials, otherwise Flipt will fail to start with an error indicating the conflict.
 
 **Examples:**
 
@@ -228,14 +228,14 @@
 |------------------------------------------------|------------------------|-------------------------------------------|
 | `https://github.com/org/repo.git`              | `git`                  | `[email protected]:org/repo.git`             |
 | `ssh://[email protected]/group/repo.git`       | `deploy`               | `[email protected]:group/repo.git`        |
-| `ssh://git@localhost:6022/root/demo.git`       | `git`                  | `git@localhost:6022:root/demo.git`        |
+| `ssh://git@localhost:6022/root/demo.git`       | `git`                  | `ssh://git@localhost:6022/root/demo.git`  |
 | `[email protected]:org/repo.git`                  | `git`                  | `[email protected]:org/repo.git`             |
-| `git@localhost:2222:owner/repo.git`            | `git`                  | `git@localhost:2222:owner/repo.git`       |
+| `git@localhost:2222:owner/repo.git`            | `git`                  | `ssh://git@localhost:2222/owner/repo.git` |
 | `github.com/org/repo.git`                      | *(empty)*              | `[email protected]:org/repo.git`             |
 
 If you see an error about conflicting SSH users, ensure that the user in your credentials matches the user in the remote URL, or remove the user from the URL and let Flipt insert it automatically.
 
-This normalization is handled automatically by Flipt; you do not need to manually convert URLs for SSH usage. Non-standard ports are preserved in all SSH operations.
+This normalization is handled automatically by Flipt; you do not need to manually convert URLs for SSH usage. For non-default ports, Flipt preserves the `ssh://` protocol format to ensure Git uses the specified port correctly.
 
 ### 3. Configure Environments
 Reference your storage backend in the environments section and specify a directory for each environment.

How did I do? Any feedback?  Join Discord

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: approve

Clean, focused fix for a real bug. The change correctly preserves ssh:// format for non-default SSH ports instead of incorrectly converting them to SCP-style (git@host:port:path), which Git misinterprets. Tests cover both the with-user and without-user cases for non-default ports, and existing port-22 behavior is unchanged.

🤖 Automated review by the Flipt PR review agent.

@codecov

codecov Bot commented May 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.41%. Comparing base (b8a9cc8) to head (0dae180).
⚠️ Report is 1 commits behind head on v2.

Additional details and impacted files
@@           Coverage Diff           @@
##               v2    #5945   +/-   ##
=======================================
  Coverage   61.41%   61.41%           
=======================================
  Files         142      142           
  Lines       14265    14265           
=======================================
  Hits         8761     8761           
  Misses       4770     4770           
  Partials      734      734           
Flag Coverage Δ
integrationtests 34.51% <0.00%> (ø)
unittests 52.48% <100.00%> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@erka

erka commented May 30, 2026

Copy link
Copy Markdown
Contributor

related to #5298.

@erka

erka commented May 30, 2026

Copy link
Copy Markdown
Contributor

I've tried to investigate your issue with my setup, but I couldn't replicate it using Flipt v2.9.0 and GitLab 19.0. This is the log entries I captured:

DEBUG	pushing to remote	{"server": "grpc", "git_storage_type": "memory", "remoteName": "origin", "remoteURLs": ["[email protected]:6022:root/flipt-features.git"], "refSpec": "refs/heads/main:refs/heads/main"}
DEBUG	setting remote tracking reference	{"server": "grpc", "git_storage_type": "memory", "reference": "refs/remotes/origin/main", "hash": "5675e05a47d3ea629940b83af263ff48f326cf98"}
DEBUG	update and push completed successfully	{"server": "grpc", "git_storage_type": "memory", "branch": "main", "hash": "5675e05a47d3ea629940b83af263ff48f326cf98"}

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: approve

Focused, correct fix for SSH remote URL normalization with non-default ports. The change correctly preserves ssh:// form when a custom port is present (since SCP-style URLs cannot encode a port without misinterpreting it as part of the path), and existing port-22 behavior is unchanged. Tests cover both with-user and without-user cases for non-default ports.

🤖 Automated review by the Flipt PR review agent.

@immanuwell

Copy link
Copy Markdown
Contributor Author

@erka the log actually shows the old broken url ([email protected]:6022:root/flipt-features.git)
go-git's ssh transport happens to tolerate that format and still extracts the port correctly

but the standard git cli doesn't; it treats everything after the first : as the path, so it'd try to clone 6022:root/... over port 22

You can reproduce without a real server - just intercept the SSH invocation:

GIT_SSH_COMMAND="sh -c 'echo \"\$@\"; exit 1' --" GIT_SSH_VARIANT=ssh \
  git ls-remote [email protected]:6022:root/flipt-features.git
# [email protected] git-upload-pack '6022:root/flipt-features.git'
#                                ^^^^ treated as path, not port — connects on 22
GIT_SSH_COMMAND="sh -c 'echo \"\$@\"; exit 1' --" GIT_SSH_VARIANT=ssh \
  git ls-remote ssh://[email protected]:6022/root/flipt-features.git
# -p 6022 [email protected] git-upload-pack '/root/flipt-features.git'
#    ^^^^ correct port

go-git's internal ssh transport parses it differently, which is why it worked for you. But the standard git CLI doesn't

@immanuwell
immanuwell force-pushed the fix/ssh-remote-nondefault-port branch from 0c35292 to cc4ffa4 Compare June 7, 2026 17:38

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: approve

Clean, focused fix for SSH remote normalization with non-default ports. The change correctly preserves ssh:// URLs when a custom port is present, avoiding the SCP-style ambiguity where the port would be misinterpreted as part of the path. Tests cover both with-user and without-user cases for non-default ports and existing port-22 behavior remains unchanged.

🤖 Automated review by the Flipt PR review agent.

@erka erka left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I don't see any difference at the end - both ways work.

@erka erka added the v2 Flipt v2 label Jun 8, 2026
@erka erka added the automerge Used by Kodiak bot to automerge PRs label Jun 8, 2026

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Verdict: approve

Clean, focused bugfix. The change correctly preserves ssh:// URLs with non-default ports instead of incorrectly converting them to SCP-style, which Git misinterprets. Tests and documentation are updated appropriately.

🤖 Automated review by the Flipt PR review agent.

@erka erka added automerge Used by Kodiak bot to automerge PRs and removed automerge Used by Kodiak bot to automerge PRs labels Jun 8, 2026
@kodiakhq
kodiakhq Bot merged commit 9ebef94 into flipt-io:v2 Jun 8, 2026
47 of 48 checks passed
@github-project-automation github-project-automation Bot moved this to Done in Flipt V2 Jun 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automerge Used by Kodiak bot to automerge PRs size:S This PR changes 10-29 lines, ignoring generated files. v2 Flipt v2

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

Trouble connecting to Gitlab instance

2 participants