transparency-dev / transparency-dev/tessera

Mitigate gRPC diamond dependency and version skew issues for downstream consumers (Debian)

Open
#931 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
Go
Stars
238
Forks
56
Avg merge
1d 2h
Merged PRs (30d)
35

Description

Background

The tessera repository currently depends on google.golang.org/grpc primarily through Google Cloud client libraries (for Spanner and GCS) and via OpenTelemetry OTLP gRPC exporters (used in the AWS conformance binaries).

While Go modules manage dependencies using Minimum Version Selection (MVS), gRPC does not strictly adhere to semantic versioning (semver) across minor/patch releases for its internal structures and generated Protobuf stubs. As a result, downstream consumers of tessera using Debian encounter "diamond dependency" conflicts and version skew when their application depends on a different version of gRPC or Protobuf stubs than the one pinned by tessera. See https://github.com/google/trillian/issues/3870#issuecomment-4175375093 for context in Trillian.

This problem is particularly acute in unvendored packaging ecosystems like Debian, where packages are resolved against a single system-wide installed version of a library (e.g., golang-google-grpc-dev).

If a user on Debian wants to build an application against the lightweight POSIX backend of tessera, the build chain is currently forced to resolve the entire gRPC, Protobuf, and GCP client library tree due to imports in the codebase. Incompatibilities between the system-wide gRPC package and tessera's required dependencies will break the compilation entirely, even for developers who have no intention of using Spanner, GCP, or the gRPC features.

Proposed Solutions

Option 1: Split Drivers into Independent Modules (Ideal but Heavy)

Break out individual storage implementations into separate, dedicated Go modules (e.g., github.com/transparency-dev/tessera/storage/gcp).
Pros:

  • Cleanest dependency graph for the core module.
  • Ensures that consumers of tessera-core never resolve gRPC, Spanner, or Google Cloud SDKs at all.
    Cons:
  • Higher overhead for development, maintenance, and releasing multiple synchronized Go modules.
Option 2: Pragmatic Isolation via Build Flags (Recommended)
  1. Migrate Exporters to HTTP
  2. Add Build Flags to GCP/gRPC Drivers

Switch the AWS conformance OTel exporter in cmd/conformance/aws/otel.go from otlptracegrpc/otlpmetricgrpc to their HTTP equivalents (otlp*http). Since AWS ADOT fully supports receiving over HTTP, this is functionally equivalent and drops the direct gRPC dependency at the application level.

Put the entire storage/gcp package (and any other gRPC-coupled storage components) behind explicit build flags (e.g., //go:build gcp).
Pros:

  • Lightweight to implement without refactoring repository structure.
  • Allows downstream packagers (like Debian maintainers) or developers to completely prune gRPC from the compile process by building without the -tags gcp flag.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with cmd/conformance/aws/otel.go and the storage/gcp package to map the current gRPC imports and build boundaries. Migrate the AWS OTLP exporter to its HTTP equivalent and isolate GCP/gRPC-coupled storage behind an explicit build tag; done means POSIX-focused builds can avoid resolving the gRPC and GCP dependency tree.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, grpc
Domain
backend, build-system
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.