goproxyio/goproxy
A global proxy for Go modules.
Stale — last commit 2y ago
weakest axislast commit was 2y ago; no CI workflows detected
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
last commit was 2y ago; no CI workflows detected
- ✓30+ active contributors
- ✓Distributed ownership (top contributor 47% of recent commits)
- ✓MIT licensed
Show all 6 evidence items →Show less
- ✓Tests present
- ⚠Stale — last commit 2y ago
- ⚠No CI workflows detected
What would change the summary?
- →Use as dependency Mixed → Healthy if: 1 commit in the last 365 days
- →Deploy as-is Mixed → Healthy if: 1 commit in the last 180 days
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Forkable" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/goproxyio/goproxy)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/goproxyio/goproxy on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: goproxyio/goproxy
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/goproxyio/goproxy shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
WAIT — Stale — last commit 2y ago
- 30+ active contributors
- Distributed ownership (top contributor 47% of recent commits)
- MIT licensed
- Tests present
- ⚠ Stale — last commit 2y ago
- ⚠ No CI workflows detected
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live goproxyio/goproxy
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/goproxyio/goproxy.
What it runs against: a local clone of goproxyio/goproxy — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in goproxyio/goproxy | Confirms the artifact applies here, not a fork |
| 2 | License is still MIT | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | Last commit ≤ 854 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of goproxyio/goproxy. If you don't
# have one yet, run these first:
#
# git clone https://github.com/goproxyio/goproxy.git
# cd goproxy
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of goproxyio/goproxy and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "goproxyio/goproxy(\\.git)?\\b" \\
&& ok "origin remote is goproxyio/goproxy" \\
|| miss "origin remote is not goproxyio/goproxy (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
&& ok "license is MIT" \\
|| miss "license drift — was MIT at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 854 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~824d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/goproxyio/goproxy"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
goproxy is a caching proxy server for Go modules that implements the Go Module Proxy Protocol (GOPROXY). It sits between go get clients and module repositories, storing module versions locally and serving them via HTTP, dramatically accelerating builds and reducing bandwidth. It supports both standalone proxy mode (caching all modules) and router mode (selectively proxying public modules while routing private ones directly). Monolithic service: main.go is the entry point, proxy/ contains the HTTP server (server.go, router.go) and Prometheus metrics (metrics.go), sumdb/ handles Go Sum Database integration, and utility packages (renameio/, robustio/) wrap platform-specific file operations. No clear separation into library vs. CLI—everything assumes server deployment.
👥Who it's for
Go developers and DevOps engineers who deploy Go services at scale and need faster, more reliable module resolution—especially those managing private modules alongside public dependencies, or running builds in air-gapped or bandwidth-constrained environments.
🌱Maturity & risk
Production-ready. The project has active CI/CD (CircleCI), public deployment at goproxy.io, Docker support, and implements the official Go proxy protocol. The dependency set is conservative (golang.org/x/mod, Prometheus metrics). However, the GitHub star count is not listed in provided data, so community adoption level is unclear from this snapshot.
Low risk for the core proxy mechanism, but operator-dependent. Key risks: (1) the service invokes the local go command, so Go SDK version mismatches between proxy and clients can cause silent failures; (2) cacheDir must be on a different GOPATH than the local machine to avoid deadlocks (documented but operationally fragile); (3) private module auth relies on git credential helpers—if misconfigured, private modules fail silently. Single-maintainer visibility is unclear from repo data.
Active areas of work
No recent commit history visible in provided data, so active development status is unclear. The repo includes CircleCI config and Docker Compose setup, suggesting infrastructure is maintained. Version is v2 (go.mod declares module github.com/goproxyio/goproxy/v2), indicating a major version bump occurred.
🚀Get running
git clone https://github.com/goproxyio/goproxy.git && cd goproxy && make
Then run: ./bin/goproxy -listen=0.0.0.0:80 -cacheDir=/tmp/test
Daily commands: make ./bin/goproxy -listen=0.0.0.0:80 -cacheDir=/tmp/test
For router mode: ./bin/goproxy -listen=0.0.0.0:80 -cacheDir=/tmp/test -proxy https://goproxy.io -exclude '*.corp.example.com,rsc.io/private'
Or Docker: docker-compose up
🗺️Map of the codebase
- main.go: Entry point that parses CLI flags (-listen, -cacheDir, -proxy, -exclude) and initializes the server
- proxy/server.go: HTTP request handler implementing the Go Module Proxy Protocol endpoints (/module/@v/list, /module/@v/version.mod, /module/@v/version.zip)
- proxy/router.go: Implements the -exclude glob pattern matching logic that decides whether to route to upstream proxy or direct repository
- proxy/metrics.go: Prometheus metrics collection for monitoring cache hits, module resolution latency, and error rates
- sumdb/handler.go: Implements Go Sum Database proxy protocol (go.sum verification) for module integrity checks
- robustio/robustio.go: Atomic file write wrapper preventing corruption on disk full or process crash
- Makefile: Build targets; examine for compilation flags, test commands, and Docker image building
🛠️How to make changes
Main entry point: main.go (command-line flags). Request routing: proxy/router.go (glob pattern matching for -exclude). HTTP handlers: proxy/server.go (module endpoint logic). Metrics: proxy/metrics.go (Prometheus instrumentation). Sum DB: sumdb/handler.go. File operations (atomic writes): renameio/renameio.go, robustio/robustio.go.
🪤Traps & gotchas
Critical: (1) GOPATH collision deadlock—if you run go get on the proxy machine itself, you MUST use a different GOPATH than the -cacheDir, or the go command will deadlock. (2) Git auth: private modules require git config --global url...insteadOf setup; without it, private repos fail silently. (3) The service spawns the local go command—Go SDK version mismatch between proxy and clients can cause unexpected behavior. (4) Sum Database handler (sumdb/) requires network access to sum.golang.org unless -sumdb is overridden. (5) Platform-specific code in robustio/robustio_windows.go and robustio_other.go—Windows and Unix behave differently for file locking.
💡Concepts to learn
- Go Module Proxy Protocol — goproxy's entire purpose is to implement this protocol; understanding the API contract (/@v/list, /@v/version.mod, /@v/version.zip endpoints) is essential to modifying server.go and router.go
- Atomic file writes with rename (POSIX rename idiom) — robustio/renameio/ packages implement crash-safe caching: they write to a temp file then atomic-rename it, preventing corruption if the process dies mid-write—critical for cache reliability
- Glob pattern matching (Go filepath/path.Match semantics) — The -exclude flag in router.go uses glob patterns to route modules; knowing Go's glob syntax (*, ?, [abc]) is essential to understand and extend the router logic
- Go Sum Database (sumdb protocol) — goproxy's sumdb/handler.go proxies checksums from sum.golang.org to prevent tampering; understanding this protocol is necessary to modify security-critical code paths
- Reverse proxy / router pattern — Router mode (proxy/router.go with -exclude) is a selective reverse proxy; common DevOps pattern for splitting traffic based on rules—useful for understanding hybrid public/private module architectures
- Prometheus metrics and Grafana dashboards — proxy/metrics.go exposes cache hit ratios and latency; understanding Prometheus labels and histogram buckets is necessary to add new observability or debug performance issues
- GOPATH and module cache layout — The cacheDir structure mirrors GOPATH/pkg/mod; understanding Go's module storage format is necessary to implement cache eviction, corruption recovery, or offline serving
🔗Related repos
golang/go— The official Go repository that defines the Module Proxy Protocol (RFC) that goproxy implementsgomods/athens— Alternative Go module proxy server with similar goals but written in Go, supports validation and cleanup policiesjfrog/artifactory— Enterprise module proxy/registry that supports Go modules alongside other package managers (Maven, npm, etc.)goproxyio/goproxy-docker— Official Docker image repository for deploying goproxy as a container (referenced in Dockerfile)prometheus/client_golang— The metrics library used by goproxy/proxy/metrics.go for Prometheus observability
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add integration tests for proxy/router.go and proxy/server.go
The repo has test/get_test.sh and test/testdata/get.txt for shell-based testing, but lacks Go unit tests for core routing and server logic. proxy/router.go and proxy/server.go handle request routing and HTTP server setup but have no corresponding _test.go files. This would improve code coverage and catch regressions early.
- [ ] Create proxy/router_test.go with tests for route matching and request handling
- [ ] Create proxy/server_test.go with tests for server initialization and HTTP response handling
- [ ] Add test cases that mock Go module requests (e.g., @v/list, @latest, @v/go.mod)
- [ ] Run tests locally with 'go test ./proxy/...' to verify coverage
Add Windows-specific tests for robustio/robustio_windows.go
The repo has platform-specific code with robustio_windows.go and robustio_other.go, but robustio_windows.go has no corresponding unit tests. The existing umask_test.go only covers non-Windows behavior. Windows file I/O behavior differs significantly (e.g., file locking, permissions), requiring dedicated tests.
- [ ] Create robustio/robustio_windows_test.go with Windows-specific test cases
- [ ] Add tests for file operations that verify Windows-specific behavior (e.g., handling locked files)
- [ ] Use build tags (//+build windows) to ensure tests only run on Windows
- [ ] Reference existing robustio_test.go patterns for consistency
Add GitHub Actions workflow to replace CircleCI for faster feedback
The repo uses CircleCI (see .circleci/config.yml), but lacks native GitHub Actions workflows in .github/workflows/. GitHub Actions integrates directly with GitHub, provides faster setup, and is free for public repos. This would provide faster PR feedback and reduce external CI dependency.
- [ ] Create .github/workflows/test.yml with Go test matrix (go 1.12 minimum, latest stable)
- [ ] Include 'go test ./...', 'go vet ./...', and 'go build' steps
- [ ] Add build matrix for linux and windows platforms given robustio platform-specific code
- [ ] Reference go.mod version (1.12) in workflow Go version setup
🌿Good first issues
- Add test coverage for proxy/router.go glob pattern matching: the -exclude flag is underfeatured (e.g., no negation patterns), and current test/testdata/get.txt only covers basic cases. Write tests in proxy/router_test.go to verify patterns like '!*.internal.com' or glob precedence.
- Implement health check endpoint /health or /ready: the server has no liveness probe for Kubernetes, forcing operators to guess from /metrics. Add a simple endpoint that returns 200 with cache stats JSON.
- Add missing benchmark in proxy/server_test.go for module zip download throughput under concurrent requests. The README shows docker-compose but no perf baselines exist.
⭐Top contributors
Click to expand
Top contributors
- @oiooj — 47 commits
- @hxzhao527 — 11 commits
- @ianwoolf — 5 commits
- @formych — 4 commits
- @jamesaorson — 2 commits
📝Recent commits
Click to expand
Recent commits
382eafb— Update README.md (oiooj)985d9fc— Add missing whitespace (jamesaorson)6f817c3— Improve documentation (jamesaorson)303c77b— Merge pull request #211 from wolfogre/bugfix/fix_type (hxzhao527)6b82d6c— chore: fix typo (wolfogre)4f3b008— add Sponsors in README (oiooj)450ca75— change sumdb proxy impl (hxzhao527)e03dc0f— feat: support to set cache expiration (Y4ssss)236ffb4— fix: rewrite content-length header when returning decompressed body (stanxing)258f7b0— fix: fix typos (httpcheck)
🔒Security observations
- High · Outdated Go Module Dependencies —
go.mod. The go.mod file specifies golang.org/x/mod v0.4.0 (released ~2021) which is significantly outdated. This version may contain known security vulnerabilities and lacks security patches. The prometheus/client_golang v1.9.0 is also from 2021 and should be updated. Fix: Update dependencies to their latest stable versions. Run 'go get -u ./...' and test thoroughly. Consider using 'go mod tidy' and implement automated dependency scanning in CI/CD. - High · Tini Binary Downloaded from External Source Without Verification —
Dockerfile (line: ADD https://github.com/krallin/tini/releases/download/...). The Dockerfile downloads tini from GitHub releases via HTTP without checksum verification. This creates a supply chain risk where a compromised or MITM attack could inject malicious code into the binary. Fix: Verify the downloaded binary using checksums. Use HTTPS explicitly, download the SHA256 checksums file, and validate before use. Example: ADD --checksum=sha256:... or verify after download. - High · Exposed Service Port Without Authentication —
docker-compose.yaml (port 8081) and Dockerfile (EXPOSE 8081). The application exposes port 8081 without any authentication or authorization mechanism. The docker-compose configuration binds to 0.0.0.0:8081, making it accessible to any network client. This could allow unauthorized users to use the proxy service. Fix: Implement authentication (API keys, mTLS, OAuth2) for the proxy service. Use a reverse proxy with authentication. Bind to specific IPs instead of 0.0.0.0. Implement rate limiting and access controls. - Medium · Missing Security Headers in HTTP Responses —
proxy/server.go. Based on the proxy/server.go file references, the HTTP server likely lacks security headers (X-Frame-Options, X-Content-Type-Options, Strict-Transport-Security, etc.). This increases vulnerability to clickjacking, MIME sniffing, and other HTTP-based attacks. Fix: Add security headers to all HTTP responses. Implement middleware that sets: X-Frame-Options: DENY, X-Content-Type-Options: nosniff, Strict-Transport-Security, Content-Security-Policy, and other appropriate headers. - Medium · Volume Mount with Default Permissions —
docker-compose.yaml (volumes section). The docker-compose.yaml mounts ./cacheDir:/ext without specifying volume ownership or permissions. This could lead to privilege escalation or unauthorized file access depending on host permissions. Fix: Specify explicit permissions and ownership for mounted volumes. Use read-only mounts where appropriate. Implement proper file permission models (user/group). Consider using named volumes instead of bind mounts. - Medium · Alpine Image Base Without Package Pinning —
Dockerfile (FROM golang:alpine). The Dockerfile uses 'golang:alpine' without specifying a specific version tag, and runs 'apk add --no-cache -U' which upgrades packages. This could introduce breaking changes or vulnerabilities from untested package versions. Fix: Pin specific Alpine and Go versions (e.g., 'golang:1.19-alpine3.17'). Remove the '-U' flag from apk add or use specific package versions. Use a software composition analysis tool to track dependencies. - Medium · No Input Validation or Sanitization Visible —
proxy/router.go, proxy/server.go. The proxy service accepts module paths and versions from untreated user input. Without visible input validation in proxy/router.go and proxy/server.go, there's risk of path traversal, command injection via the 'go' command invocation, or other injection attacks. Fix: Implement strict input validation for all user-supplied parameters (module names, versions, paths). Use allowlists for valid characters. Validate and escape all inputs before passing to external commands. Use subprocess APIs that don't invoke shell interpretation. - Medium · External Command Execution Risk —
main.go. The README states 'This service invokes the local go command to answer requests.' Executing external commands with user-controlled input is a common source of command injection vulnerabilities. Fix: undefined
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.