Problem/Motivation

drupal.org runs a single GitLab instance, but exposes it under two different hostnames depending on protocol:

  • HTTPS / web UIgit.drupalcode.org (Fastly-fronted)
  • SSHgit.drupal.org (direct, not behind Fastly — SSH cannot traverse the CDN)

The two hostnames resolve to different IPs but reach the same GitLab. drupal.org's project pages reflect this in their clone widget: Clone with SSH hands you git@git.drupal.org:project/foo.git, while Clone with HTTPS hands you https://git.drupalcode.org/project/foo.git. Both work for git itself, so the split is invisible to anyone who only ever runs git clone, git push, and git pull.

It is not invisible to higher-level tooling that expects a single canonical hostname. The most prominent example is the official GitLab CLI, glab, which performs a string comparison between the GITLAB_HOST environment variable and the host segment of the project's origin remote. When a user follows the natural path —

git clone git@git.drupal.org:project/foo.git    # from "Clone with SSH"
export GITLAB_HOST=git.drupalcode.org           # to talk to the GitLab API
export GITLAB_TOKEN=<PAT>
glab mr create

glab refuses with:

ERROR: None of the git remotes configured for this repository correspond
to the GITLAB_HOST environment variable.

GITLAB_HOST is currently set to git.drupalcode.org
Configured remotes: git.drupal.org.

The same friction extends to AI coding assistants (Claude Code, Cursor, ChatGPT/Codex, etc.) that drive glab on the user's behalf, and to any third-party tool that does a similar host check. Every new contributor following drupal.org's own clone-URL guidance encounters this the first time they reach for a GitLab CLI — and the error message points at the user's environment, not at the underlying drupal.org infrastructure detail, so the diagnostic path is non-obvious.

The cost is a one-time but recurring friction: every contributor who reaches beyond plain git hits it, has to debug the dual-host setup themselves, and has to choose a workaround. Multiplied across an initiative like the new AI Initiative, where AI-driven contribution workflows are a stated goal, this is worth normalizing.

Steps to reproduce

  1. On any drupal.org project page (e.g. project/drupal), click Clone and copy the Clone with SSH URL.
  2. Clone the project: git clone git@git.drupal.org:project/foo.git.
  3. Install glab (install instructions) and configure it for drupalcode.org via environment variables:
    export GITLAB_HOST=git.drupalcode.org
    export GITLAB_TOKEN=<personal access token from git.drupalcode.org>
  4. cd into the clone and run a write command, e.g. glab mr create --fill or glab issue create.
  5. Observe the error: "None of the git remotes configured for this repository correspond to the GITLAB_HOST environment variable."

The dual-host nature is also visible at the DNS level:

$ getent hosts git.drupal.org git.drupalcode.org
44.230.112.158   gitlab1-aws.drupalsystems.org git.drupal.org git-origin.drupalcode.org
146.75.122.217   osff2.map.fastly.net git.drupalcode.org

Security considerations

These are security-adjacent considerations stemming from the dual-hostname setup, not a vulnerability disclosure. Filing through the public queue is appropriate; flagging here so the infra team can weigh them when deciding the standardization approach.

  1. Phishing surface. Teaching users that two legitimate hostnames serve one service weakens the contrast they rely on to spot impostor domains. drupal.org vs drupalcode.org is already close enough to require a pause; normalizing "both are correct" lowers the bar for a future typosquat (e.g. git.drupalcode-mirror.org, gitlab.drupalcode.org) to be missed. Mild, but real.

  2. SSH host-key fingerprint trust. A security-conscious new contributor verifying the SSH host key on first connect must verify against git.drupal.org — the actual SSH host — but every visible cue (clone widget, web URL, brand) points at git.drupalcode.org. If drupal.org's published fingerprint documentation cites only one hostname, users following the visible-host advice may skip verification or look up the fingerprint somewhere less authoritative. The fix overlaps with this issue's standardization: a single hostname removes the ambiguity.

  3. CDN-origin exposure (worth verifying internally). The DNS reverse mapping shows the origin name is publicly resolvable:

    44.230.112.158   gitlab1-aws.drupalsystems.org git.drupal.org git-origin.drupalcode.org

    The name git-origin.drupalcode.org identifies an unproxied origin endpoint behind the git.drupalcode.org Fastly fronting. That is a common operational pattern (origin needs to be reachable for some workflows), but it means HTTPS traffic aimed at the AWS IP can skip Fastly entirely — bypassing whatever rate-limiting, WAF, and DDoS protection the CDN tier provides for the public hostname. Whether this is exploitable depends on the origin's firewall: if it accepts HTTPS only from Fastly's IP ranges, the exposure is just a name; if not, the public hostname's CDN protections can be circumvented by clients that resolve the origin name directly.

    This has not been probed — doing so without authorization would be inappropriate. Flagging only so the infra team can confirm the firewall posture as part of any standardization work, and so it is documented if the dual-hostname setup is kept in place.

None of the above is being asserted as exploitable today. They are reasons to prefer standardization on a single hostname over keeping the current dual-host arrangement long-term.

Proposed resolution

Standardize on git.drupalcode.org as the canonical hostname for both HTTPS and SSH clone URLs, since it already matches the public-facing web UI and is the hostname every user already sees. Three options, in increasing order of ambition:

Option A — minimal: change the clone-URL widget only. Update the Clone with SSH button on drupal.org / drupalcode.org project pages to emit git@git.drupalcode.org:project/foo.git instead of git@git.drupal.org:project/foo.git. Existing clones keep working (DNS for git.drupal.org stays in place); new clones use the canonical hostname and stop tripping glab's host check.

Option B — preferred: confirm SSH on git.drupalcode.org, then change the widget. Verify that the SSH listener on git.drupalcode.org works (it likely does, since the IP is just Fastly fronting the same backend that git.drupal.org reaches directly — but worth confirming). Once verified, do Option A.

Option C — long-term: deprecate git.drupal.org as a Git endpoint. Keep DNS for backwards compatibility for some announced period, but remove it from all official documentation and clone widgets, and eventually retire it.

Option A is sufficient to solve the immediate glab friction; Option B is the right end state.

Remaining tasks

  • Confirm SSH listener on git.drupalcode.org is functional (or set it up if not).
  • Update the project-page Clone with SSH widget on drupal.org / drupalcode.org to emit git.drupalcode.org.
  • Update drupal.org's "Using GitLab to contribute to Drupal" docs to use the canonical hostname in all examples.
  • Optionally: announce the change in a drupal.org blog / changelog post so contributors know the new canonical hostname and can update remotes if they want (git remote set-url origin git@git.drupalcode.org:...).

User interface changes

The clone-URL widget on every drupalcode.org project page would show git@git.drupalcode.org:project/foo.git in its Clone with SSH field instead of git@git.drupal.org:project/foo.git. The Clone with HTTPS field is unchanged.

API changes

None. The GitLab REST and GraphQL APIs are unaffected; both are reached at https://git.drupalcode.org/api/... today and would continue to be. Existing SSH remotes using git@git.drupal.org:... would continue to work as long as git.drupal.org DNS is maintained.

Data model changes

None.


Drafted with the assistance of AI (Claude Code / Opus 4.7).

Comments

jjchinquist created an issue. See original summary.

jjchinquist’s picture

Issue summary: View changes
drumm’s picture

Status: Active » Closed (won't fix)

git.drupalcode.org is fronted by a CDN. The CDN only handles HTTP requests, and does not offer services for any other ports. We can’t have the same domain handle port 22 and CDN requests without some major restructuring.

Now that this issue is closed, review the contribution record.

As a contributor, attribute any organization that helped you, or if you volunteered your own time.

Maintainers, credit people who helped resolve this issue.