Skip to content

aviad-has/gitgate

Repository files navigation

GitGate

A self-hosted, policy-enforcing proxy for git clone.

Every time a developer runs git clone https://github.com/..., arbitrary code enters your network. Until recently that was an acceptable tradeoff. The agent era changed the math: GitHub now sees millions of new repositories per month, most of them AI-generated, most of them unreviewed. Your developers are one git clone away from running any of them.

GitGate sits between your developers and GitHub. Allowed repos clone normally. Everything else is blocked before a single byte of code crosses the boundary — with a reason logged.

$ git clone https://github.com/sketchy/brand-new-package
remote: GitGate: clone blocked
remote: Reason: repo_too_young (3 days old, minimum 30)
remote: Contact your security team to request an exception.
fatal: repository not found

Quick start

Prerequisites: Docker, Docker Compose.

git clone https://github.com/your-org/gitgate
cd gitgate
cp policy.yaml.example policy.yaml   # edit to taste
docker compose up -d

For team use: set GITGATE_GITHUB_TOKEN to a GitHub token with read access before starting. Without it GitGate is limited to 60 API calls/hour — a small team will exhaust that quickly and clones will start failing.

GITGATE_GITHUB_TOKEN=ghp_... docker compose up -d

The token is read at runtime from the environment and is never compiled into the binary.

No Docker? If you're an individual developer, the gitgate CLI works without any infrastructure:

cargo install --path .       # build once
gitgate clone owner/repo     # replaces `git clone`
gitgate check owner/repo     # dry-run without cloning

Policy file: drop a gitgate-policy.yaml in your project root, or set GITGATE_POLICY_FILE.


First run generates a private CA and server certificate in ./certs/.

Install the CA on developer machines (once per machine, run as admin):

# macOS
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain ./certs/ca.crt

# Linux (Debian/Ubuntu)
sudo cp ./certs/ca.crt /usr/local/share/ca-certificates/gitgate.crt
sudo update-ca-certificates

# Windows
certutil -addstore -f "ROOT" certs\ca.crt

Configure git on developer machines (replace proxy.yourdomain.com with your proxy's address):

git config --global \
  url."https://proxy.yourdomain.com:7443/".insteadOf "https://github.com/"

Done. Every git clone https://github.com/... now goes through GitGate. Developers notice nothing for allowed repos.


Policy

Edit policy.yaml to match your org's requirements:

# Only allow OSI-approved permissive licenses
license_allowlist:
  - MIT
  - Apache-2.0
  - BSD-2-Clause
  - BSD-3-Clause
  - ISC

# Block repos with no license at all
no_license_action: block

# Ignore repos younger than 30 days
min_repo_age_days: 30

# Always block these orgs/users
org_blocklist: []

# Specific repos that bypass all checks (your own internal mirrors, etc.)
exceptions:
  - my-org/approved-internal-tool

Full reference with all options: policy.yaml.example.


What developers see

Allowed:

$ git clone https://github.com/torvalds/linux
  GitGate: ALLOW — license: GPL-2.0
Cloning into 'linux'...
remote: Enumerating objects: ...

Blocked:

$ git clone https://github.com/sketchy/new-package
remote: GitGate: clone blocked
remote: Reason: no_license
remote:
remote: Contact your security team to request an exception.
fatal: repository 'https://github.com/sketchy/new-package/' not found

The blocking message appears verbatim in the developer's terminal. No guessing why — they know exactly which policy rule triggered and who to ask.


Already blocked GitHub?

If your security team blocked github.com at the firewall after an incident, GitGate is the path back.

Deploy GitGate inside your network. Update the firewall to allow outbound HTTPS from the GitGate host to github.com and api.github.com. Developers configure the git redirect above. GitHub access is restored — gated by your policy.


How it works

GitGate is a git smart-HTTP proxy. It speaks the same protocol GitHub does.

  1. Developer runs git clone https://github.com/owner/repo
  2. git contacts the proxy instead (via the url.insteadOf config)
  3. GitGate calls the GitHub API to fetch repo metadata (license, age, stars, owner)
  4. Policy engine evaluates the request → ALLOW or BLOCK
  5. ALLOW: GitGate forwards the request to GitHub and streams the pack data back
  6. BLOCK: GitGate returns HTTP 403 with the reason; git prints it as remote: ...
  7. Every decision is written to the audit log

The code for an allowed repo transfers directly from GitHub to the developer — GitGate is not in the data path beyond the initial handshake. Large repos and monorepos are not buffered.


Custom hostname and port

By default the proxy runs on port 7443 with localhost in the certificate SAN. For a production deployment, set the hostname before first run:

GITGATE_HOSTNAME=proxy.yourdomain.com docker compose up -d

Or generate certificates manually:

gitgate-cert generate --out-dir ./certs --hostname proxy.yourdomain.com

Configuration reference

Environment variable Default Description
GITGATE_HOSTNAME localhost Hostname in the generated TLS certificate
GITGATE_PORT 7443 Port the proxy listens on
GITGATE_GITHUB_TOKEN (none) GitHub token for higher API rate limits

Status

  • Policy engine — license, age, stars, org allowlist/blocklist, per-repo exceptions
  • HTTPS proxy with auto-generated self-signed CA
  • Audit log (JSON, one entry per decision)
  • Docker Compose install
  • Code scanning policy — block if GitHub code scanning reports critical alerts (block_if_critical), or require scanning to be enabled (require); defaults to ignore
  • Web UI for audit log and exception requests

Building from source

Requires Rust 1.75+.

cargo build --release

Produces three binaries in target/release/: gitgate-proxy, gitgate-cert, and gitgate.

For individual-developer usage without a proxy, see Quick start above.


Why self-hosted?

Your clone traffic contains the names of every repository your organization depends on. Routing that through a third-party service is a different kind of risk. GitGate is installed by your IT team, runs in your network, and the code is open for your security team to read.


License

MIT

About

Self-hosted, policy-enforcing proxy for git clone — block malicious/risky repos before code enters your network

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors