Table of contents
Overview
When your service depends on private Go modules (e.g., shared libraries in a private GitHub org or GitLab group), Go needs two things:
-
GOPRIVATE — tells
goto skip the public module proxy and fetch directly from the source - Authentication — credentials to access private repositories
ColdBrew’s cookiecutter template pre-configures GOPRIVATE from the goprivate variable you set during project creation (defaults to source_path/*). You just need to set up authentication.
Local Development
Option 1: SSH key (recommended)
If you already have SSH access to your repos:
git config --global url."git@github.com:".insteadOf "https://github.com/"
# Or for GitLab:
git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"
Option 2: Personal access token via .netrc
# GitHub
echo "machine github.com login x-access-token password YOUR_PAT" >> ~/.netrc
# GitLab (needs read_repository scope)
echo "machine gitlab.com login your-username password YOUR_PAT" >> ~/.netrc
Option 3: GOAUTH
export GOAUTH=netrc
This tells Go to use .netrc for authentication during module resolution.
Docker Builds
The generated Dockerfile includes GOPRIVATE as a build arg. For authentication, uncomment one of the options in the Dockerfile:
Personal access token
docker build --build-arg GITHUB_TOKEN=your_pat .
The Dockerfile has a commented-out section that uses this arg to create a .netrc file in the build stage. Since ColdBrew uses a multi-stage build, credentials in the build stage are not included in the final image.
For even stronger isolation, use a BuildKit secret mount instead of a build arg:
docker build --secret id=netrc,src=$HOME/.netrc .
SSH agent forwarding
For SSH-based auth during Docker builds, use BuildKit:
DOCKER_BUILDKIT=1 docker build --ssh default .
Add to your Dockerfile build stage:
RUN --mount=type=ssh git config --global url."git@github.com:".insteadOf "https://github.com/"
GitHub Actions
The generated workflow includes GOPRIVATE in the env section. For authentication, uncomment the private modules step and add a GO_PRIVATE_TOKEN secret to your repo:
- Create a GitHub PAT with
reposcope - Add it as a repository secret named
GO_PRIVATE_TOKEN - Uncomment the “Configure private modules” step in
.github/workflows/go.yml
GitLab CI
The generated .gitlab-ci.yml includes GOPRIVATE in the variables. For authentication, uncomment the .netrc line in before_script:
before_script:
- mkdir -p .go/pkg/mod
- echo "machine gitlab.com login gitlab-ci-token password ${CI_JOB_TOKEN}" > ~/.netrc
CI_JOB_TOKEN is automatically available in GitLab CI — no manual token setup needed.
GitLab nested subgroups
GitLab projects nested more than one level deep (e.g., gitlab.com/org/group/subgroup/repo) require special handling because Go’s module discovery makes unauthenticated HTTP requests to determine the repository path.
Use GOAUTH with .netrc:
variables:
GOAUTH: "netrc"
Also set GONOSUMDB and GONOPROXY alongside GOPRIVATE to ensure Go doesn’t try the public checksum database or proxy for nested subgroup paths.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
410 Gone | Module proxy can’t access private repo | Ensure GOPRIVATE is set correctly |
404 Not Found | Git can’t authenticate | Check .netrc or SSH config |
remote: HTTP Basic: Access denied | Token expired or wrong scope | Regenerate PAT with repo (GitHub) or read_repository (GitLab) scope |
could not read Username | Git prompting for credentials in non-interactive mode | Add .netrc or SSH config — don’t rely on interactive auth in CI/Docker |