Extend the storage-owned remote model from HTTPS-only URLs to a typed HTTPS-or-SSH contract without weakening rejection of local, helper, or executable transports.
Scope
Replace the assumption that every configured remote is a url::Url with a typed remote endpoint owned by crates/storage.
Accept both Git SSH spellings:
ssh://[user@]host[:port]/path
[user@]host:path, including the requested git@host:path form
Preserve Git path semantics: an ssh:// path beginning with / is absolute, an scp-like path without / is relative to the remote account, and the documented ~user form remains distinguishable.
Parse IPv4, DNS names, bracketed IPv6 where Git permits it, explicit ports for ssh://, usernames, and non-empty repository paths into validated fields. Never recover transport state from display text.
Reject missing or ambiguous hosts/paths, control bytes, embedded secrets, query/fragment data, URL rewrites, separate push URLs, ext::, git://, file://, local paths, and every helper transport before connection work.
Preserve existing credential-free HTTPS configuration and behavior. Make transport-specific configuration fields explicit so HTTPS server/application credential references are not confused with SSH identity/trust references.
Add an optional ssh feature in crates/storage containing only the Rust SSH/runtime dependencies. The endpoint model must remain available without that feature so an unavailable build returns a typed unsupported-transport error instead of misparsing the config.
Keep russh and its async runtime behind the optional feature. Select a current patched Apache-2.0-compatible release and one deliberate crypto backend; do not enable legacy/insecure algorithms accidentally.
Update the architecture and configuration documentation from HTTPS-only to HTTPS plus feature-gated SSH while retaining the no-subprocess rule.
Tests and verification
Add table-driven parser/round-trip tests for both spellings, absolute/relative/tilde paths, ports, IPv6, Unicode policy, and malicious command/path inputs.
Prove existing HTTPS TOML and repository remotes load unchanged.
Prove a build without ssh contains no russh dependency and reports SSH as unsupported before DNS, socket, credential, or repository mutation work.
Run all repository-required Rust gates.
Acceptance criteria
The two requested SSH spellings map to one typed endpoint contract with correct Git path semantics.
Invalid/helper/local transports remain fail-closed and cannot reach a transport implementation.
HTTPS behavior and existing configurations do not regress.
SSH code and dependencies are absent when the feature is disabled.
crates/storage remains the only owner of remote parsing and transport selection.
## Goal
Extend the storage-owned remote model from HTTPS-only URLs to a typed HTTPS-or-SSH contract without weakening rejection of local, helper, or executable transports.
## Scope
- Replace the assumption that every configured remote is a `url::Url` with a typed remote endpoint owned by `crates/storage`.
- Accept both Git SSH spellings:
- `ssh://[user@]host[:port]/path`
- `[user@]host:path`, including the requested `git@host:path` form
- Preserve Git path semantics: an `ssh://` path beginning with `/` is absolute, an scp-like path without `/` is relative to the remote account, and the documented `~user` form remains distinguishable.
- Parse IPv4, DNS names, bracketed IPv6 where Git permits it, explicit ports for `ssh://`, usernames, and non-empty repository paths into validated fields. Never recover transport state from display text.
- Reject missing or ambiguous hosts/paths, control bytes, embedded secrets, query/fragment data, URL rewrites, separate push URLs, `ext::`, `git://`, `file://`, local paths, and every helper transport before connection work.
- Preserve existing credential-free HTTPS configuration and behavior. Make transport-specific configuration fields explicit so HTTPS server/application credential references are not confused with SSH identity/trust references.
- Add an optional `ssh` feature in `crates/storage` containing only the Rust SSH/runtime dependencies. The endpoint model must remain available without that feature so an unavailable build returns a typed unsupported-transport error instead of misparsing the config.
- Keep `russh` and its async runtime behind the optional feature. Select a current patched Apache-2.0-compatible release and one deliberate crypto backend; do not enable legacy/insecure algorithms accidentally.
- Update the architecture and configuration documentation from HTTPS-only to HTTPS plus feature-gated SSH while retaining the no-subprocess rule.
## Tests and verification
- Add table-driven parser/round-trip tests for both spellings, absolute/relative/tilde paths, ports, IPv6, Unicode policy, and malicious command/path inputs.
- Prove existing HTTPS TOML and repository remotes load unchanged.
- Prove a build without `ssh` contains no `russh` dependency and reports SSH as unsupported before DNS, socket, credential, or repository mutation work.
- Run all repository-required Rust gates.
## Acceptance criteria
- The two requested SSH spellings map to one typed endpoint contract with correct Git path semantics.
- Invalid/helper/local transports remain fail-closed and cannot reach a transport implementation.
- HTTPS behavior and existing configurations do not regress.
- SSH code and dependencies are absent when the feature is disabled.
- `crates/storage` remains the only owner of remote parsing and transport selection.
References: https://git-scm.com/docs/git-clone#_git_urls and https://docs.rs/russh/latest/russh/
hugo
added this to the 07 - Pure-Rust Git-over-SSH remotes milestone 2026-08-24 20:17:05 +00:00
Added storage-owned RemoteEndpoint, SshEndpoint, SshRepositoryPath, and RemoteTransport types for ssh:// and scp-like SSH remotes, including absolute, relative, and tilde path semantics, ports, IPv4, bracketed IPv6, IDNA hosts, usernames, and strict fail-closed validation.
Kept HTTPS credential references transport-specific and preserved existing HTTPS configuration and operations. Helper, local, executable, rewrite, push-URL, embedded-secret, query, fragment, ambiguous, and control-byte inputs remain rejected.
Added the optional storage ssh feature with Russh 0.63.1 and Tokio behind it. Default and Apple graphs contain no Russh; the enabled graph selects Ring only. Feature-disabled SSH returns a typed unsupported-transport error before repository, credential, DNS, socket, or transport work.
Updated affected Rust callers, architecture/configuration/synchronization documentation, and parser/config/repository regression tests.
Verification: cargo fmt --all -- --check; warnings-as-errors workspace check; Clippy with warnings denied; full workspace tests; feature-enabled storage check and focused tests; feature-tree inspection; and release desktop bundle build all passed. Computer Use on the exact target/release/IronStorage.app opened Git Status successfully and confirmed the existing HTTPS origin remained clean at 0 ahead / 0 behind. No Apple source changed, so iPhone Simulator/device validation was not applicable.
Installed cargo-audit 0.22.2 and audited the final lockfile. The audit found and this commit fixes h2 RUSTSEC-2026-0258 by updating 0.4.15 to 0.4.16. The only remaining vulnerability is pre-existing rsa 0.9.10 RUSTSEC-2023-0071 through pgp/apple-codesign; RustSec currently lists no fixed release. The new SSH feature does not enable Russh RSA.
Implemented in commit f636f3b.
- Added storage-owned RemoteEndpoint, SshEndpoint, SshRepositoryPath, and RemoteTransport types for ssh:// and scp-like SSH remotes, including absolute, relative, and tilde path semantics, ports, IPv4, bracketed IPv6, IDNA hosts, usernames, and strict fail-closed validation.
- Kept HTTPS credential references transport-specific and preserved existing HTTPS configuration and operations. Helper, local, executable, rewrite, push-URL, embedded-secret, query, fragment, ambiguous, and control-byte inputs remain rejected.
- Added the optional storage ssh feature with Russh 0.63.1 and Tokio behind it. Default and Apple graphs contain no Russh; the enabled graph selects Ring only. Feature-disabled SSH returns a typed unsupported-transport error before repository, credential, DNS, socket, or transport work.
- Updated affected Rust callers, architecture/configuration/synchronization documentation, and parser/config/repository regression tests.
Verification: cargo fmt --all -- --check; warnings-as-errors workspace check; Clippy with warnings denied; full workspace tests; feature-enabled storage check and focused tests; feature-tree inspection; and release desktop bundle build all passed. Computer Use on the exact target/release/IronStorage.app opened Git Status successfully and confirmed the existing HTTPS origin remained clean at 0 ahead / 0 behind. No Apple source changed, so iPhone Simulator/device validation was not applicable.
Installed cargo-audit 0.22.2 and audited the final lockfile. The audit found and this commit fixes h2 RUSTSEC-2026-0258 by updating 0.4.15 to 0.4.16. The only remaining vulnerability is pre-existing rsa 0.9.10 RUSTSEC-2023-0071 through pgp/apple-codesign; RustSec currently lists no fixed release. The new SSH feature does not enable Russh RSA.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Goal
Extend the storage-owned remote model from HTTPS-only URLs to a typed HTTPS-or-SSH contract without weakening rejection of local, helper, or executable transports.
Scope
url::Urlwith a typed remote endpoint owned bycrates/storage.ssh://[user@]host[:port]/path[user@]host:path, including the requestedgit@host:pathformssh://path beginning with/is absolute, an scp-like path without/is relative to the remote account, and the documented~userform remains distinguishable.ssh://, usernames, and non-empty repository paths into validated fields. Never recover transport state from display text.ext::,git://,file://, local paths, and every helper transport before connection work.sshfeature incrates/storagecontaining only the Rust SSH/runtime dependencies. The endpoint model must remain available without that feature so an unavailable build returns a typed unsupported-transport error instead of misparsing the config.russhand its async runtime behind the optional feature. Select a current patched Apache-2.0-compatible release and one deliberate crypto backend; do not enable legacy/insecure algorithms accidentally.Tests and verification
sshcontains norusshdependency and reports SSH as unsupported before DNS, socket, credential, or repository mutation work.Acceptance criteria
crates/storageremains the only owner of remote parsing and transport selection.References: https://git-scm.com/docs/git-clone#_git_urls and https://docs.rs/russh/latest/russh/
Implemented in commit
f636f3b.Verification: cargo fmt --all -- --check; warnings-as-errors workspace check; Clippy with warnings denied; full workspace tests; feature-enabled storage check and focused tests; feature-tree inspection; and release desktop bundle build all passed. Computer Use on the exact target/release/IronStorage.app opened Git Status successfully and confirmed the existing HTTPS origin remained clean at 0 ahead / 0 behind. No Apple source changed, so iPhone Simulator/device validation was not applicable.
Installed cargo-audit 0.22.2 and audited the final lockfile. The audit found and this commit fixes h2 RUSTSEC-2026-0258 by updating 0.4.15 to 0.4.16. The only remaining vulnerability is pre-existing rsa 0.9.10 RUSTSEC-2023-0071 through pgp/apple-codesign; RustSec currently lists no fixed release. The new SSH feature does not enable Russh RSA.