Skip to content

[BUG] Corporate networks blocking port 22 cause SSH clone attempt to hang #652

@tillig

Description

@tillig

Describe the bug

apm install hangs indefinitely when restoring packages from an Azure DevOps repository on a network that silently drops SSH traffic (e.g., corporate firewalls, VPN/Zscaler). The clone fallback chain in _clone_with_fallback() tries SSH (Method 2) before plain HTTPS (Method 3), but Repo.clone_from() via GitPython has no connection timeout. When the firewall silently drops packets on port 22 instead of rejecting them, the SSH attempt blocks forever and the HTTPS fallback is never reached.

This affects users who rely on git credential helpers (e.g., Git Credential Manager, Azure CLI) rather than explicit ADO_APM_PAT tokens, since having no token means Method 1 (authenticated HTTPS) is skipped.

To Reproduce

  1. Be on a corporate/VPN network that silently drops outbound SSH traffic (port 22) like Zscaler.
  2. Have an apm.yml with an Azure DevOps dependency.
  3. Do not set ADO_APM_PAT (rely on git credential helpers instead).
  4. Run apm install.
  5. The command hangs indefinitely at the SSH clone attempt.

Expected behavior

The SSH clone attempt should fail within a reasonable timeout (e.g., 30 seconds) and fall back to plain HTTPS, where git credential helpers can provide authentication.

Alternatively, HTTPS could be attempted first, before SSH, to allow credential helpers to kick in.

Environment (please complete the following information):

  • OS: macOS (Apple Silicon), though the issue affects any platform behind a firewall that drops SSH
  • Python Version: 3.13
  • APM Version: 0.8.11
  • VSCode Version: N/A (CLI issue)

Logs

Running apm install -v gives me this output...

apm install -v output

Additional context

  • The _try_sparse_checkout() method already uses subprocess.run(timeout=120), so sparse-checkout operations are protected. Only the GitPython Repo.clone_from() path lacks a timeout.
  • The GIT_SSH_COMMAND environment variable is not set in the git environment, so there is no ConnectTimeout to bound the SSH connection attempt.
  • A workaround is to set url.<base>.insteadOf in gitconfig to rewrite SSH URLs to HTTPS, but this only works when APM uses the relaxed env (no token). When APM has a token and uses the locked-down env (GIT_CONFIG_GLOBAL=/dev/null), user gitconfig is suppressed.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingneeds-triageNew issue, not yet reviewed by maintainers

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions