Repository navigation
[FEATURE] Opt-out for anonymous-first HTTPS on github.com behind TLS-inspecting proxies with no revocation info #2545
Description
Is your feature request related to a problem? Please describe.
AuthResolver.uses_public_github_anonymous_first() (introduced in #2406, 0.27.0; refined in #2422, 0.28.0) unconditionally tries HTTPS anonymously first for any exact-host github.com dependency, with no opt-out. The anonymous attempt runs in a from-scratch isolated Git environment (GIT_CONFIG_NOSYSTEM=1 + empty GIT_CONFIG_GLOBAL + disabled credential.helper), which ignores the user's real ~/.gitconfig (including http.sslBackend and any corporate TLS trust configuration).
On networks behind a TLS-inspecting proxy (e.g. Netskope) whose intercepting certificate chain carries no CRL Distribution Point and no Authority Information Access (OCSP) extensions at all (verified with openssl x509 -text on leaf, intermediate, and root — not just "unreachable", genuinely absent), the isolated environment's connection attempt fails with a network/TLS-classified error (schannel: CRYPT_E_NO_REVOCATION_CHECK, or a hang). is_public_github_auth_failure() correctly does not classify this as an auth failure, so APM neverresolves/tries a credential — and with --allow-protocol-fallback it jumps straight to SSH. If SSH is also blocked (common on corporate firewalls), install fails completely with "Could not connect to github.com (network error, not an auth failure)".
Critically, a plain git clone on the same machine/network succeeds instantly, because it uses the OS git credential helper and the use
r's real ~/.gitconfig (http.sslBackend=schannel, resolving against the Windows certificate store where the corporate root CA is installed) — the exact configuration the isolated environment discards.
This is a regression relative to 0.26.0, whose legacy --allow-protocol-fallback chain unconditionally tried a final "plain HTTPS" leg deferring to the OS git config/credential helper, which happened to succeed in this exact scenario.
Describe the solution you'd like
An opt-out (CLI flag and/or env var, e.g. --auth-first / APM_GITHUB_AUTH_FIRST=1) to restore auth-first / environment-inheriting behavior for exact-host github.com, for users who already have a working git config/credentials but are behind a network where the isolated anonymous-first environment cannot complete a TLS handshake at all.
Describe alternatives you've considered
-
Downgrading to apm <0.27.0 — works, but loses newer fixes/features.
-
Declaring dependencies with explicit
ssh://URLs to sidestep the HTTPS path — plausible, untested, and still depends on SSH connectivity (often blocked; workable viassh.github.com:443but non-obvious). -
Manually restoring TLS trust for the isolated environment via
GIT_SSL_CAINFO+ forcinghttp.sslbackend=openssl(these specific env vars surviveAuthResolver's isolation, unlike gitconfig-based settings) — works, but required deep reverse-engineering ofauth.pyto discover; not discoverable by a typical user hitting this. -
http.schannelCheckRevoke=false— does not reliably help when the CA chain has no revocation info at all (confirmed on 2.45.1.windows.1); matches several long-standing, unresolved community reports of the same git-for-windows/schannel limitation (SO 65636426, SO 45556189).
Additional context
-
apm-cli 0.28.0, Windows, git 2.45.1.windows.1.
-
Root cause chain: PR fix(auth): try public GitHub anonymously before resolving credentials #2406 introduced anonymous-first + isolated git env; PR fix(release): preserve Git isolation across auth fallback #2422 refined the isolation but didn't change this behavior.
-
Happy to share full repro details/logs if useful.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTodo
Activity
github-actions commentedon Aug 10, 2026
Thank you for the detailed report,
@rgarciapariente-- this is an excellent bug writeup with clear root-cause analysis and alternatives considered.Triage Panel Verdict
Summary
AuthResolver's anonymous-first isolated git environment (introduced in #2406, refined in #2422) stripsGIT_CONFIG_NOSYSTEM, clearsGIT_CONFIG_GLOBAL, and disablescredential.helper. On Windows behind a TLS-inspecting proxy whose intercepting CA chain carries no CRL/OCSP revocation info, this isolated environment cannot complete a TLS handshake -- whereas a plaingit cloneon the same machine succeeds because it uses the OS git credential helper and the user's real~/.gitconfig(http.sslBackend=schannel+ Windows certificate store). The result is a complete install failure, a regression from 0.26.0, and a severe discoverability gap (workarounds require reverse-engineeringauth.py).Decision: ACCEPT
This is a legitimate enterprise-blocking regression affecting users behind corporate TLS-inspecting proxies (Netskope and equivalents). The proposed opt-out (
--auth-first/APM_GITHUB_AUTH_FIRST=1) is the right shape: explicit user consent to trade the credential-isolation security property for environment-inheriting behavior.Panel notes by dimension
DevX UX Expert
--allow-protocol-fallback's "plain HTTPS leg" previously deferred to OS git config, accidentally making this work.--auth-firstis clear. Consider also surfacing a diagnostic hint in the existing "network error, not an auth failure" error path pointing users to the opt-out.GIT_SSL_CAINFO/http.sslbackend=opensslworkaround surviving isolation (because env vars bypass gitconfig stripping) is worth documenting as a power-user escape hatch in the error message.Supply Chain Security Expert
--auth-first/APM_GITHUB_AUTH_FIRST=1is active, emit a one-time[!] APM_GITHUB_AUTH_FIRST is set: git credentials will be forwarded on the first HTTPS attemptwarning so the security tradeoff is visible.AuthResolver-- implementation must passscripts/lint-auth-signals.sh.APM CEO
--allow-protocol-fallback) before coding to avoid a second round of auth-surface churn.Recommended labels
theme/securityarea/clipriority/highstatus/triagedExisting
type/featurelabel retained (human-applied; the regression aspect could also justifytype/bug, but this label is accurate and was set by a maintainer -- panel recommends addingtype/bugas a complementary label for the regression dimension, but defers to maintainer discretion).Suggested next action
--allow-protocol-fallback; whether to narrow isolation to TLS-config-only first.AuthResolver+ add regression test for the TLS-proxy scenario (mock or documented manual repro steps).rgarciapariente commentedon Sep 10, 2026
Design proposal: opt-out for anonymous-first isolation (#2545)
Answering the panel's three sub-questions.
1. API shape → both flag and env var, reusing the
--allow-protocol-fallbackpatternAPM already has a tested opt-out of this exact class:
--allow-protocol-fallback/APM_ALLOW_PROTOCOL_FALLBACK/apm config set allow-protocol-fallback(
config.py:337-458,commands/install.py:970-974,commands/config.py:25-70). Reuse it verbatim:--auth-first(is_flag=True, default=False), envAPM_GITHUB_AUTH_FIRST(tri-state parser,same as
_parse_allow_protocol_fallback_env), persisted keygithub_auth_first.get_apm_allow_protocol_fallback(): flag > env > config > False(add a sibling
get_apm_github_auth_first()).Both — flag for one-off/CI, env for wrapper scripts, config for "always behind this proxy".
2. Interaction with
--allow-protocol-fallback→ orthogonal, applied earlierThey compose, don't conflict:
--allow-protocol-fallbackgoverns what happens after the anonymous HTTPS attempt fails(whether to jump HTTPS → SSH).
--auth-firstacts before that: the opt-out must be threaded insideAuthResolver.uses_public_github_anonymous_first()so it returnsFalsefor exact-host github.com.That method is the single decision point consulted by ~13 call sites (validation, clone engine,
downloader, ref resolution) — its own docstring keeps the decision there "so ... [they] cannot drift
into separate host checks", so the opt-out belongs there, not at an individual
try_with_fallback(unauth_first=...)call site.tests/unit/test_transport_selection.py:12) over the 4 combinations of{auth-first} × {allow-protocol-fallback}.3. Narrow to TLS-config-only first → yes, ship it as the default; keep
--auth-firstas the broad escape hatchbuild_public_github_anonymous_git_env()(core/auth.py:1313-1343)zeroes the whole git config (
GIT_CONFIG_NOSYSTEM=1+ emptyGIT_CONFIG_GLOBAL), discarding TLStrust settings together with
credential.helper— two unrelated concerns in one mechanism. Wealready split them elsewhere:
noninteractive_env()takespreserve_config_isolationandsuppress_credential_helpersseparately (deps/git_auth_env.py:116-168). Inherit only the user'sreal
http.sslBackend+http.sslCAInfo(the settings that make a plaingit clonesucceedin this scenario — per the report
http.schannelCheckRevokedoes not help), while still forcingcredential.helper=/http.extraheader=empty.does relax the "hermetic TLS" property so the anonymous attempt honors the user's own CA trust —
same CAs a plain
git clonealready uses. Worth an explicit call-out for the supply-chain review.non-isolated config (
git config --get http.sslBackend, …) and re-inject viaGIT_CONFIG_COUNT/KEY_n/VALUE_n. We must not pointGIT_CONFIG_GLOBALat the real file(that would drag
credential.helperback in). Cross-platform care needed.--auth-first/APM_GITHUB_AUTH_FIRSTstays for cases the narrow fixdoesn't cover, with the one-time warning the panel suggested:
[!] APM_GITHUB_AUTH_FIRST is set: git credentials will be forwarded on the first HTTPS attempt.This fixes the common TLS-proxy case by default with no credential-leakage regression, and gives power
users an explicit, warned opt-out — as two independently reviewable/revertable
AuthResolverchanges.Implementation note
Both changes touch
AuthResolver→ must passscripts/lint-auth-signals.sh; the new env var is readonly in
config.py(no directos.getenv()in app code). Test both the flag matrix and thedefault TLS-inheritance path independently.
rgarciapariente commentedon Sep 16, 2026
I've added the following PR #2999 with an implementation proposal. Thank you very much!
feat(auth): auth-first opt-out and TLS config inheritance for github.…
feat(auth): auth-first opt-out and TLS config inheritance for github.…
feat(auth): auth-first opt-out and TLS config inheritance for github.…
feat(auth): auth-first opt-out and TLS config inheritance for github.…
feat(auth): auth-first opt-out and TLS config inheritance for github.…