Skip to content

Commit 803b695

Browse files
committed
feat: add Rekor v2 mode with verified entries and persistent deduplication
1 parent c4e2e2f commit 803b695

22 files changed

Lines changed: 1800 additions & 111 deletions

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,21 @@ jobs:
5050
test:
5151
name: Test
5252
runs-on: ubuntu-latest
53+
services:
54+
postgres:
55+
image: postgres:17
56+
env:
57+
POSTGRES_PASSWORD: test
58+
POSTGRES_DB: siglog_test
59+
ports:
60+
- 5432:5432
61+
options: >-
62+
--health-cmd pg_isready
63+
--health-interval 5s
64+
--health-timeout 5s
65+
--health-retries 10
66+
env:
67+
SIGLOG_TEST_POSTGRES_URL: postgres://postgres:test@localhost:5432/siglog_test
5368
steps:
5469
- uses: actions/checkout@v4
5570
- uses: dtolnay/rust-toolchain@master
@@ -58,3 +73,12 @@ jobs:
5873
- uses: Swatinem/rust-cache@v2
5974
- name: Run tests
6075
run: cargo test --all
76+
- uses: actions/setup-go@v5
77+
with:
78+
go-version-file: rekor-conformance/go.mod
79+
cache-dependency-path: rekor-conformance/go.sum
80+
- name: Rekor v2 interoperability
81+
run: |
82+
cargo build --bin siglog
83+
cd rekor-conformance
84+
go test -v -count=1

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ sigstore-crypto = "0.6.0"
4949
clap = { version = "4", features = ["derive", "env"] }
5050

5151
# Cryptography
52-
ed25519-dalek = { version = "2", features = ["rand_core"] }
52+
# Already used by sigstore-crypto; direct access for prehashed verification and strict DER parsing.
53+
aws-lc-rs = "1.15"
54+
x509-cert = "0.2"
55+
ed25519-dalek = { version = "2", features = ["rand_core", "digest"] }
5356
rand = "0.8"
5457
sha2 = "0.10"
5558

README.md

Lines changed: 94 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# siglog
44

5-
A Rust implementation of a [Tessera](https://github.com/transparency-dev/tessera)-compatible transparency log server for package distribution systems.
5+
A Rust transparency log server for package distribution systems, with [Tessera](https://github.com/transparency-dev/tessera) and [Rekor v2](https://github.com/sigstore/rekor-tiles) HTTP API modes.
66

77
This implementation follows the [C2SP tlog-tiles](https://c2sp.org/tlog-tiles) specification and provides an append-only Merkle tree with cryptographic guarantees that all users see the same data.
88

@@ -71,6 +71,7 @@ cargo build --release
7171

7272
| Variable | Description | Default |
7373
|----------|-------------|---------|
74+
| `LOG_MODE` | API mode: `tessera` or `rekor` (`--mode`) | `tessera` |
7475
| `LISTEN_ADDR` | Server listen address | `0.0.0.0:8080` |
7576
| `DATABASE_URL` | Database connection string | `sqlite:./siglog.db?mode=rwc` |
7677
| `LOG_ORIGIN` | Log origin identifier | Required |
@@ -82,8 +83,8 @@ cargo build --release
8283
| `S3_SECRET_KEY` | S3 secret key | - |
8384
| `S3_ENDPOINT` | S3 endpoint URL | - |
8485
| `S3_REGION` | S3 region | `auto` |
85-
| `API_KEY` | Bearer token required for `/add` writes | Required unless `ALLOW_PUBLIC_WRITES=true` |
86-
| `ALLOW_PUBLIC_WRITES` | Allow unauthenticated `/add` writes for local development | `false` |
86+
| `API_KEY` | Bearer token required for write requests in either mode | Required unless `ALLOW_PUBLIC_WRITES=true` |
87+
| `ALLOW_PUBLIC_WRITES` | Allow unauthenticated writes for local development | `false` |
8788
| `CHECKPOINT_INTERVAL` | Checkpoint frequency (seconds) | `1` |
8889
| `BATCH_MAX_SIZE` | Max entries per batch | `256` |
8990
| `BATCH_MAX_AGE_MS` | Max batch age (ms) | `1000` |
@@ -219,7 +220,80 @@ Response (on success): The witness's cosignature line.
219220

220221
## API Reference
221222

222-
### Log Server Endpoints
223+
### Choosing an API mode
224+
225+
```bash
226+
# Existing raw-entry API (default)
227+
./target/release/siglog --mode tessera
228+
229+
# Rekor v2 HTTP/JSON API; use a NEW database and tile storage directory
230+
./target/release/siglog --mode rekor \
231+
--database-url 'sqlite:./rekor.db?mode=rwc' --fs-root ./rekor-tiles
232+
```
233+
234+
Both commands also require the signing key, origin, and write-authentication configuration described above.
235+
The selected mode is persisted in the database; startup rejects a different mode.
236+
Existing non-empty, unmarked databases are treated as Tessera logs. Use separate
237+
storage, databases, and log identities for separate logs—do not mix their writers.
238+
239+
Rekor mode exposes:
240+
241+
| Endpoint | Method | Description |
242+
|----------|--------|-------------|
243+
| `/api/v2/log/entries` | POST | Verify and integrate a hashedrekord v0.0.2 entry |
244+
| `/api/v2/checkpoint` | GET | Latest signed checkpoint |
245+
| `/api/v2/tile/{level}/{index}` | GET | Hash tile, including partial tiles |
246+
| `/api/v2/tile/entries/{index}` | GET | Entry bundle, including partial bundles |
247+
| `/health`, `/ready` | GET | Health and readiness |
248+
249+
`/add` is **not exposed** in Rekor mode. Existing explorer/package-monitor clients
250+
that use the unprefixed API should continue using Tessera mode. Generic tile readers
251+
can use `/api/v2/` as their read base URL in Rekor mode.
252+
253+
The submission schema follows [Rekor v2](https://github.com/sigstore/rekor-tiles/blob/v2.3.0/api/proto/rekor/v2/entry.proto):
254+
255+
```json
256+
{
257+
"hashedRekordRequestV002": {
258+
"digest": "BASE64_ARTIFACT_SHA256",
259+
"signature": {
260+
"content": "BASE64_DER_ECDSA_SIGNATURE",
261+
"verifier": {
262+
"publicKey": {"rawBytes": "BASE64_DER_SPKI_PUBLIC_KEY"},
263+
"keyDetails": "PKIX_ECDSA_P256_SHA_256"
264+
}
265+
}
266+
}
267+
}
268+
```
269+
270+
Use `Content-Type: application/json` and `Authorization: Bearer <API_KEY>`.
271+
Exactly one `publicKey` or `x509Certificate` (DER, base64-encoded `rawBytes`) is required.
272+
Supported signature algorithms are Ed25519ph/SHA-512 (`PKIX_ED25519_PH`, empty
273+
context), ECDSA P-256/SHA-256, P-384/SHA-384, P-521/SHA-512 and RSA PKCS#1 v1.5
274+
SHA-256 with 2048/3072/4096-bit keys. Ed25519ph takes the artifact's SHA-512 digest;
275+
pure Ed25519 signatures over that digest are not interchangeable.
276+
Artifact signatures and key/algorithm agreement are verified before sequencing.
277+
Certificate trust/identity policy remains the client's responsibility, as in Rekor.
278+
RSA-PSS, deprecated DSSE submissions, and gRPC transport are not implemented.
279+
280+
A successful write returns HTTP **201** and a Sigstore `TransparencyLogEntry`:
281+
canonicalized body, log ID, kind/version, and inclusion proof against a **published,
282+
signed checkpoint**. Protobuf JSON integer fields are strings and byte fields are
283+
base64. No v1 signed-entry timestamp/inclusion promise is issued.
284+
The log ID is the full SHA-256 note-key hash, matching rekor-tiles v2.3.0.
285+
286+
Requests wait up to 30 seconds for sequencing, integration, and checkpoint publication
287+
(including configured witnesses). A 504 does **not** undo a queued entry.
288+
Exact canonical entries are deduplicated permanently and atomically in the database,
289+
including concurrent retries, pending entries, and retries after restarts. A duplicate
290+
returns HTTP **409**, gRPC JSON code **6**, and an `x-log-index` header with the original
291+
index. This is not an inclusion promise: that entry may still await integration.
292+
Different signatures or verification material produce different entries even for the
293+
same artifact. Tessera mode still appends every submission.
294+
Request bodies and canonical entries are each limited to 65,535 bytes.
295+
296+
### Tessera Log Server Endpoints
223297

224298
| Endpoint | Method | Description |
225299
|----------|--------|-------------|
@@ -387,6 +461,22 @@ Clients can verify entries against the transparency log:
387461
4. For a specific entry, fetch the inclusion proof
388462
5. Verify the proof against the checkpoint root hash
389463
464+
### Rekor interoperability checks
465+
466+
```bash
467+
cargo test --workspace
468+
cargo build --bin siglog
469+
(cd rekor-conformance && go test -v)
470+
```
471+
472+
The Go test requires Go 1.25.8+ (or automatic Go toolchain downloads). It launches an
473+
isolated local server and uses the upstream rekor-tiles v2.3.0 writer and verifier
474+
to check all supported signing algorithms, public keys and certificates, canonical
475+
entry reconstruction, Ed25519ph signatures, duplicate responses, and inclusion proofs
476+
across a full tile boundary. CI also checks concurrent deduplication and rollback on
477+
SQLite and PostgreSQL; locally, set `SIGLOG_TEST_POSTGRES_URL` to a dedicated empty
478+
PostgreSQL database to run that check.
479+
390480
## License
391481

392482
BSD-3-Clause. See [LICENSE](LICENSE) for details.

rekor-conformance/go.mod

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
module siglog-rekor-conformance
2+
3+
go 1.25.8
4+
5+
require (
6+
github.com/sigstore/protobuf-specs v0.5.1
7+
github.com/sigstore/rekor-tiles/v2 v2.3.0
8+
github.com/transparency-dev/merkle v0.0.2
9+
golang.org/x/mod v0.36.0
10+
)
11+
12+
require (
13+
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 // indirect
14+
github.com/google/go-containerregistry v0.20.7 // indirect
15+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 // indirect
16+
github.com/opencontainers/go-digest v1.0.0 // indirect
17+
github.com/secure-systems-lab/go-securesystemslib v0.11.0 // indirect
18+
github.com/sigstore/sigstore v1.10.8 // indirect
19+
github.com/transparency-dev/formats v0.1.0 // indirect
20+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect
21+
golang.org/x/crypto v0.51.0 // indirect
22+
golang.org/x/net v0.55.0 // indirect
23+
golang.org/x/sys v0.45.0 // indirect
24+
golang.org/x/term v0.43.0 // indirect
25+
golang.org/x/text v0.37.0 // indirect
26+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 // indirect
27+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68 // indirect
28+
google.golang.org/grpc v1.81.1 // indirect
29+
google.golang.org/protobuf v1.36.11 // indirect
30+
)

rekor-conformance/go.sum

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
2+
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
3+
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467 h1:uX1JmpONuD549D73r6cgnxyUu18Zb7yHAy5AYU0Pm4Q=
4+
github.com/cyberphone/json-canonicalization v0.0.0-20241213102144-19d51d7fe467/go.mod h1:uzvlm1mxhHkdfqitSA92i7Se+S9ksOn3a3qmv/kyOCw=
5+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
6+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
7+
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
8+
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
9+
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
10+
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
11+
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
12+
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
13+
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
14+
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
15+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
16+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
17+
github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I=
18+
github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM=
19+
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
20+
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
21+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0 h1:5VipnvEpbqr2gA2VbM+nYVbkIF28c5ZQfqCBQ5g2xfk=
22+
github.com/grpc-ecosystem/grpc-gateway/v2 v2.29.0/go.mod h1:Hyl3n6Twe1hvtd9XUXDec4pTvgMSEixRuQKPTMH2bNs=
23+
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
24+
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
25+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
26+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
27+
github.com/secure-systems-lab/go-securesystemslib v0.11.0 h1:iuCR9kcMFD4QurdKrGvPLoKZLv9YvwPYVr0473BdtFs=
28+
github.com/secure-systems-lab/go-securesystemslib v0.11.0/go.mod h1:+PMOTjUGwHj2vcZ+TFKlb1tXRbrdWE1LYDT5i9JC80Q=
29+
github.com/sigstore/protobuf-specs v0.5.1 h1:/5OPaNuolRJmQfeZLayJGFXMpsRJEdgC6ah1/+7Px7U=
30+
github.com/sigstore/protobuf-specs v0.5.1/go.mod h1:DRBzpFuE+LnvQMN10/dU6nBeKwVLGEQ6o2FovN2Rats=
31+
github.com/sigstore/rekor-tiles/v2 v2.3.0 h1:HhMgH61UP0t899V8Fjt7pz1YdgOBptbaQdnCF+79cdc=
32+
github.com/sigstore/rekor-tiles/v2 v2.3.0/go.mod h1:DEFiKSyQ4nF75QRVNdOPaIH3cmvMkO2B6xDZjNYngPc=
33+
github.com/sigstore/sigstore v1.10.8 h1:1Mgkxvkw4AXMfIP1DOjc6kw0GkUgA8pGVpveN/EfOq4=
34+
github.com/sigstore/sigstore v1.10.8/go.mod h1:f9+B/4iaYimvUkySyb2mvc73n3RLqNn24grHZM/ET8M=
35+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
36+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
37+
github.com/transparency-dev/formats v0.1.0 h1:oL0zUFuYUjg8AbtjPMnIRDmjbaHo5jCjEWU5yaNuz0g=
38+
github.com/transparency-dev/formats v0.1.0/go.mod h1:d2FibUOHfCMdCe/+/rbKt1IPLBbPTDfwj46kt541/mU=
39+
github.com/transparency-dev/merkle v0.0.2 h1:Q9nBoQcZcgPamMkGn7ghV8XiTZ/kRxn1yCG81+twTK4=
40+
github.com/transparency-dev/merkle v0.0.2/go.mod h1:pqSy+OXefQ1EDUVmAJ8MUhHB9TXGuzVAT58PqBoHz1A=
41+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM=
42+
github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI=
43+
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
44+
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
45+
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
46+
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
47+
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
48+
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
49+
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
50+
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
51+
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
52+
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
53+
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
54+
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
55+
golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI=
56+
golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8=
57+
golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4=
58+
golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ=
59+
golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
60+
golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
61+
golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
62+
golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
63+
golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
64+
golang.org/x/term v0.43.0/go.mod h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
65+
golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
66+
golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
67+
gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4=
68+
gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E=
69+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478 h1:yQugLulqltosq0B/f8l4w9VryjV+N/5gcW0jQ3N8Qec=
70+
google.golang.org/genproto/googleapis/api v0.0.0-20260414002931-afd174a4e478/go.mod h1:C6ADNqOxbgdUUeRTU+LCHDPB9ttAMCTff6auwCVa4uc=
71+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68 h1:PvEgGJf9C/1u5CHkInMg7UFYYUoiaQmW2LbtH0pjB78=
72+
google.golang.org/genproto/googleapis/rpc v0.0.0-20260523011958-0a33c5d7ca68/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
73+
google.golang.org/grpc v1.81.1 h1:VnnIIZ88UzOOKLukQi+ImGz8O1Wdp8nAGGnvOfEIWQQ=
74+
google.golang.org/grpc v1.81.1/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I=
75+
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
76+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
77+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
78+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

0 commit comments

Comments
 (0)