In the last article Module - Future of package management in Golang, we discussed about dependency management in Golang and its adoption in the developer community. Unlike Maven in Java, module allows us to host local copies of public/private libraries to avoid any malicious code without knowledge.

In this article, We will discuss about the GOPROXY and its benefits in the setting-up local copies of public/private libraries. So that we can target following:
  • Ensure version consistency
  • Let public repositories get bugs out
  • Let public repositories secure from unauthorized alterations

Why GOPROXY?

It controls the source of Go module downloads and help us to assure that builds are deterministic and secure every-time. Dependency management in golang were using direct source such GitHub, Bitbucket, GitLab to download repositories before Golang came-up with the Go Module in 2018.
Issues With Direct Source
Third party dependencies are typically downloaded from the public server, where as all private dependencies needs VCS credentials. This approach has two potential problems with respect to fundamental requirements of a deterministic and secure build and development process immutability & availability.
What if a module owner removes or updates a version, While these scenarios are considered to be bad practice, they do occur frequently.

Centralized Package Repository

Setting a GOPROXY for our Golang development or CI environment allows us to achieve centralized package repository. As it redirects all download requests to a cache repository instead of direct repository. In this way, we can always guarantee what a specific version of a module contains, so our builds are always repeatable. This also helps ensure the module is always available, even if the original in the VCS repo is destroyed or removed.
Public Centralized Repository

A public centralized repository available to Golang developers across the globe. It hosts open-source Go modules that have been made available from third parties in publicly accessible VCS project repositories. Most, like proxy.golang.org are provided to the Golang developer community for free.

Typically, Golang projects make use of both open-source and private module dependencies. We can use the GOPRIVATE environment variable to specify a list of paths that must bypass GOPROXY and GOSUMDB and download private modules directly from those private VCS repositories.

We should set GOPROXY and GOPRIVATE environment variable to proxy.golang.org and central.corp.com respectively in-order to make use of public centralized and private repository.

$ export GOPROXY=https://proxy.golang.org,direct
$ export GOSUMDB="https://sum.golang.org/lookup/"
$ export GOPRIVATE=https://example.corp.com
Private Centralized Repository

A private centralized repository is one we install in the organization boundaries to store both public and private Go modules.

Public modules are cached locally in the binary repository manager like JFrog Artifactory, Athens, Go Proxy, and private modules are also cached in the centralized private repository from their VCS. In this way, immutability and availability can be guaranteed for both public and private Go modules.

We should set GOPROXY, and GOSUMDB environment variable to our virtual repository:

$ export GOPROXY="https://central.corp.com/package/go"
$ export GOSUMDB="https://central.corp.com/package/lookup"

Make sure module info, mod, and zip is present in the https://central.corp.com/package/go.

Module Structure

Module structure in the package repository contains list, list.lock, info, lock, mod, zip, and ziphash files.

List
This file contains list of all available module version in the package repository. URL allows us to retrieve list of modules version available for gorilla mux in the proxy.golang.org.
Info
This file contains version information long with the timestamp for a specific module version in the package repository. URL allows us to retrieve information of modules available for gorilla mux version 1.8.0 in the proxy.golang.org.
{"Version":"v1.8.0","Time":"2020-07-11T20:05:21Z"}
Mod
This is a module file having list of all the dependencies for a specific module. URL allows us to retrieve dependencies of modules available for gorilla mux version 1.8.0 in the proxy.golang.org.
ZIP
This is a actual code zip file having source code for a specific module. URL allows us to download modules for gorilla mux version 1.8.0 from proxy.golang.org.
ZIP Hash
This contains a checksum value for a source code zip file of specific module and version. URL allows us to download modules for gorilla mux version 1.8.0 from sum.golang.org.

Final Thought

My personal recommendation is to use private centralized repository as it provides the most certainty, reliability, and security across public and private modules. It’s a great feature that works seamlessly with the go command. Giving the fact that it has so many advantages (secure, fast, storage efficient) it would be wise to embrace it quickly in the projects. Also The Go team tested it and found a 3x speedup on fast networks and 6x on slow networks!
GOPROXY A central and important part of modules to achieve secure and deterministic builds.