git clone proxy
Git Clone Proxy
The portal proxies the git smart HTTP protocol so that anonymous users can git clone
from icarus.eurekaendeavors.com while GitLab repositories remain private. This
resolves three concerns simultaneously: source code access (O1), clone metrics (O2), and
GitLab web UI lockdown (O3).
How Git Smart HTTP Works
When you run git clone https://example.com/repo.git, git makes exactly two types of
requests:
1. Discovery
GET /repo.git/info/refs?service=git-upload-pack
Client asks: "What branches, tags, and commits does this repo have?" Server responds with a list of refs.
2. Pack transfer
POST /repo.git/git-upload-pack
Client says: "I have X, send me everything since then." Server streams back a binary packfile containing all the objects the client needs.
That's the entire protocol. Both request/response bodies must be streamed — pack transfers can be large and must not be buffered in memory.
How the Portal Proxies It
The portal exposes two routes per configured project:
GET /:slug.git/info/refs?service=git-upload-pack
POST /:slug.git/git-upload-pack
On receiving a request:
- Map
slug→ GitLab namespace/repo path (e.g.pets→icarus/pets) - Forward the request to
https://git.eurekaendeavors.com/icarus/pets.git/... - Authenticate with the PAT in the
Authorizationheader — server-side only - Stream the GitLab response back to the client
The git client has no visibility into GitLab or the PAT. It sees a valid, responsive
git HTTP server at icarus.eurekaendeavors.com.
Clone Metrics (resolves O2)
Every info/refs request represents the start of a git clone or git fetch. The
portal logs each one to SQLite:
| Field | Value |
|---|---|
project |
slug (e.g. icarus-pets) |
timestamp |
UTC datetime |
ip |
client IP address |
user_agent |
client User-Agent string |
event |
clone or fetch (distinguished by whether client has existing refs) |
No additional instrumentation needed — the proxy position gives us this for free.
URL Migration (resolves O1)
Existing users clone from the old public GitLab URL. Once repos go private, the new clone URL is on the portal domain:
| Before | After |
|---|---|
git clone https://git.eurekaendeavors.com/root/icarus-pets |
git clone https://icarus.eurekaendeavors.com/pets.git |
Zero-disruption migration via 301 redirect
Git clients follow HTTP redirects. Caddy on git.eurekaendeavors.com issues a
permanent redirect for git smart HTTP requests on old paths to the new portal URL:
git.eurekaendeavors.com/root/icarus-pets.git → 301 → icarus.eurekaendeavors.com/pets.git
git cloneon the old URL follows the redirect transparentlygit pullon existing local repos follows the redirect transparently- No action required from existing users
GitLab Web UI Lockdown (resolves O3)
Caddy on git.eurekaendeavors.com applies a path/header allowlist:
Allowed:
- Git smart HTTP: paths matching *.git/info/refs and *.git/git-upload-pack
- SSH: port 22 (for admin access)
Blocked: - All other HTTP traffic (web UI, API browser, container registry UI, etc.)
GitLab repositories are set to private. Even if a web UI request reaches GitLab, it returns 404/403 for unauthenticated users. The Caddy allowlist is a belt-and- suspenders layer to prevent accidental exposure.
Caddy Config Sketch
git.eurekaendeavors.com {
# Allow git smart HTTP protocol only
@git_smart_http {
path_regexp \.git/info/refs$
path_regexp \.git/git-upload-pack$
}
# Redirect old paths to portal
handle @git_smart_http {
redir https://icarus.eurekaendeavors.com{uri} 301
}
# Block everything else
respond 403
}
Note: This is a sketch. The exact Caddy config will be refined when the portal goes live and repos are made private.