Go packages#
The BSR serves Go code for Protobuf messages and Connect/gRPC clients through the Go module proxy protocol. SDKs are generated on the fly when a go get request first asks for them, then cached for subsequent requests.
Any go get works against the BSR with no extra tooling.
$ go get buf.build/gen/go/connectrpc/eliza/connectrpc/go
go: downloading buf.build/gen/go/connectrpc/eliza/connectrpc/go v1.11.0-20230913231627-233fca715f49.1
go: added buf.build/gen/go/connectrpc/eliza/connectrpc/go v1.11.0-20230913231627-233fca715f49.1
For an end-to-end walkthrough of finding and installing an SDK from the BSR, see the generated SDKs quickstart.
Go import paths#
A BSR-generated Go module path follows this format:
BSR_INSTANCE/gen/go/ORGANIZATION/MODULE_NAME/PLUGIN_OWNER/PLUGIN_NAME
# Examples
buf.build/gen/go/connectrpc/eliza/connectrpc/go # public BSR
your-bsr-instance.buf.dev/gen/go/connectrpc/eliza/connectrpc/go # Pro plan
your-bsr-instance.example.com/gen/go/connectrpc/eliza/connectrpc/go # Enterprise plan
The placeholders:
BSR_INSTANCEis the BSR host (defaults tobuf.build).ORGANIZATIONis the BSR organization that owns the module.MODULE_NAMEis the module name.PLUGIN_OWNERis the owner of the plugin.PLUGIN_NAMEis the plugin name.
In the example above, the BSR generates code for the connectrpc/eliza module using the connectrpc/go plugin.
The connectrpc/go plugin transitively depends on code generated by protocolbuffers/go, so the SDK pulls in the corresponding buf.build/gen/go/connectrpc/eliza/protocolbuffers/go SDK automatically.
To browse the package tree of a publicly available SDK, open it on pkg.go.dev (for example, pkg.go.dev/buf.build/gen/go/connectrpc/eliza/connectrpc/go).
For private SDKs, construct the import path by appending the Protobuf package to the module path:
BSR_INSTANCE/gen/go/ORGANIZATION/MODULE_NAME/PLUGIN_OWNER/PLUGIN_NAME/PROTO_PACKAGE
# Example
buf.build/gen/go/connectrpc/eliza/connectrpc/go/connectrpc/eliza/v1
Plugins like Connect and gRPC place their generated code in subpackages alongside the message types (see Connect’s reasoning). Append the subpackage name to reach the importable handlers and clients:
BSR_INSTANCE/gen/go/ORGANIZATION/MODULE_NAME/PLUGIN_OWNER/PLUGIN_NAME/PROTO_PACKAGE/SUBPACKAGE
# Example
buf.build/gen/go/connectrpc/eliza/connectrpc/go/connectrpc/eliza/v1/elizav1connect
The duplication isn’t a typo: a well-named Protobuf package commonly shares elements with the module name.
Install an SDK#
go get accepts the BSR Go module path with any of the standard Go reference shorthands:
$ go get buf.build/gen/go/connectrpc/eliza/connectrpc/go@v1.11.0-20230727062025-d8fbf2620c60.1
The BSR supports commits on labels, so referencing a non-default label fetches the matching unreleased Protobuf changes without disturbing the default label.
Labels whose names contain / aren’t compatible with the Go SDK versioning scheme.
To pin a specific plugin version (rather than the latest plugin against a chosen module ref), use the buf registry sdk version CLI command.
Version string anatomy#
PLUGIN_VERSION-MODULE_TIMESTAMP-COMMIT_ID.PLUGIN_REVISION
# Example
v1.11.0-20230727062025-d8fbf2620c60.1
| Part | Example | Source |
|---|---|---|
| Version core | 1.11.0 |
Plugin version. |
| Pre-release: timestamp | 20230727062025 |
Module commit timestamp (YYYYMMDDHHMMSS). |
| Pre-release: commit | d8fbf2620c60 |
First 12 characters of the module commit ID. |
| Build metadata | 1 |
Plugin revision. |
Commits pushed to non-default labels carry 00000000000000 as the timestamp so they sort below released versions.
Proxy cache delay#
Warning
The public Go module proxy at https://proxy.golang.org caches BSR responses, which means a fresh buf push followed by go get ...@latest may not pick up the new commit for up to ~30 minutes (per the proxy.golang.org docs).
To bypass the public proxy and fetch directly from the BSR:
Private generated SDKs#
For SDKs generated from private BSR repositories, supply a personal API token (or a bot user token for CI) and tell the Go toolchain to skip the public proxy and checksum database for those imports.
Authenticate with buf registry login#
buf registry login writes credentials to ~/.netrc, and the Go toolchain reads .netrc when fetching private modules.
For setup, see Authentication.
Configure GOPRIVATE#
Private modules can’t be fetched through the public proxy or verified through the public checksum database, so set GOPRIVATE:
GOPRIVATE implicitly sets GONOPROXY and GONOSUMDB to the same value, so the toolchain uses the direct strategy and bypasses the public proxy and checksum database for the BSR host.
For more, see Go’s private modules documentation.
Continuous integration#
For CI use of private generated SDKs, the canonical setup uses buf registry login plus GOPRIVATE.
GitHub Actions example:
- Create a BSR token (or a bot user token for shared CI).
- Add a repository secret
BUF_TOKENset to the token. - Add a repository secret
BUF_USERset to the username the token belongs to. - Set
GOPRIVATE=buf.build/gen/goas a workflow environment variable, or as a repository secret. -
As a CI step, run:
For other CI systems, the moving parts are the same: secret-store the token, export GOPRIVATE, log in with buf registry login before any go command runs.
Docker#
The Dockerfile below uses buf registry login and cleans up after itself so the credentials don’t end up in any image layer:
# syntax=docker/dockerfile:1.15
FROM golang:1.24-bookworm
ARG BUF_REGISTRY
ENV GOPRIVATE=${BUF_REGISTRY}/gen/go
COPY --from=bufbuild/buf:latest /usr/local/bin/buf /usr/local/bin/buf
WORKDIR /go/build
COPY go.mod go.sum /go/build/
RUN test -n "${BUF_REGISTRY}" || (echo "BUF_REGISTRY not set" && exit 1)
RUN --mount=type=secret,id=buftoken \
buf registry login ${BUF_REGISTRY} --token-stdin < /run/secrets/buftoken \
&& go mod download || (buf registry logout; exit 1) \
&& buf registry logout
COPY . .
# Your build steps go here.
RUN go build
With BUF_TOKEN set in the build environment to the user’s (or bot user’s) API token, build the image with:
Direct GOPROXY credentials (discouraged)#
Embedding credentials in GOPROXY is supported but discouraged: the URL ends up in shell history and process logs.
Prefer buf registry login above.
export BUF_TOKEN="<your_token>"
export BUF_USER="<username_associated_with_token>"
# GOPROXY accepts a comma-separated list of proxies; embed credentials in the
# BSR proxy URL and keep your existing proxies as fallbacks.
export GOPROXY="https://${BUF_USER}:${BUF_TOKEN}@buf.build/gen/go,${GOPROXY}"
# Skip the public sum database for the BSR module path.
export GONOSUMDB="buf.build/gen/go,${GONOSUMDB}"
Direct GOPROXY credentials aren’t compatible with GOPRIVATE for the same host: only .netrc-based authentication via buf registry login works alongside GOPRIVATE.
Available plugins#
The full list of supported Go plugins lives on the BSR plugins page (filter for Go).
For how those plugins are packaged, see the bufbuild/plugins repository; to request a new plugin, file an issue.
Troubleshooting#
Why does go get buf.build/gen/go/.../googleapis/googleapis/... return 404?#
The BSR intentionally doesn’t generate Go code for googleapis/googleapis.
Every type in googleapis/googleapis carries a go_package option pointing at google.golang.org/genproto/googleapis; import the canonical package instead of regenerating the source.