grpc access log: add negotiated TLS group ID to TLSProperties
- Dominant language
- C++
- Stars
- 28.9k
- Forks
- 5.6k
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 430
Description
*Title*: Add the negotiated TLS group ID to typed gRPC access logs
*Description*:
Envoy exposes the negotiated TLS group through `Ssl::ConnectionInfo::tlsGroupId()` and
`tlsGroupString()`. It also supports `%DOWNSTREAM_TLS_GROUP%` and
`%UPSTREAM_TLS_GROUP%` substitution-format operators, added in #44347.
The typed gRPC Access Log Service model does not currently carry the same handshake fact.
`envoy.data.accesslog.v3.TLSProperties` includes the negotiated TLS version and cipher suite,
SNI, certificate properties, session ID, and JA3 fingerprint, but it has no field for the
negotiated TLS `NamedGroup`.
This means a gRPC ALS consumer cannot distinguish a connection that negotiated a configured
hybrid group such as `X25519MLKEM768` from a compatibility fallback such as `X25519` without
adding a separate formatter-based log pipeline. Aggregate `ssl.curves.` counters show that
fallback occurred, but not which downstream clients, workloads, routes, or tenants produced it.
This is useful beyond PQC migration: the negotiated group helps with interoperability debugging,
weak-group retirement, compliance evidence, and staged TLS policy enforcement.
## Proposed API
Add field 8 to `TLSProperties`:
```proto
// TLS Supported Groups registry ID negotiated for key agreement during the handshake.
// This is the numeric NamedGroup value observed by the TLS implementation.
// The field is unset when no group was negotiated or the value is unavailable.
google.protobuf.UInt32Value tls_group_id = 8;
```
The wrapper preserves the distinction between an unavailable value and a numeric value. Although
the current connection accessor returns `uint16_t`, `UInt32Value` follows the representation used
by `tls_cipher_suite` and provides a stable protobuf presence signal.
I propose starting with the numeric ID only:
- numeric IDs are the protocol-level value and are stable across TLS backends;
- canonical strings can vary by backend and version;
- consumers can map registered IDs to display names while retaining unknown/private-use values;
- the field describes the group actually selected by a completed handshake, never the configured
preference list or groups offered by the client;
- the field does not imply that the complete connection is quantum-safe.
## Implementation boundary
- add `tls_group_id = 8` and update `[#next-free-field]` in
`api/envoy/data/accesslog/v3/accesslog.proto`;
- populate it from `downstream_ssl_connection->tlsGroupId()` in
`source/extensions/access_loggers/grpc/grpc_access_log_utils.cc` only when the accessor returns a
non-zero value;
- add unit coverage for a negotiated classical group, a hybrid group ID, and unavailable/zero
group data;
- regenerate API documentation and add a release-note fragment;
- keep upstream TLS properties, string naming, OTLP semantic-convention mapping, default log
formats, and policy classification outside this first change.
The change is additive on the wire and existing ALS consumers will ignore the unknown field.
## Design questions
1. Is a present `UInt32Value tls_group_id` the preferred API, matching `tls_cipher_suite`, or is a
scalar field acceptable here?
2. Should the API documentation refer directly to the IANA TLS Supported Groups registry while
preserving values unknown to the linked TLS backend?
3. Is downstream population in `CommonProperties` the correct first scope, with upstream TLS
telemetry considered separately?
Related context:
- #44347 added downstream/upstream TLS group substitution formatters.
- open-telemetry/semantic-conventions#4015 proposes vendor-neutral negotiated-group attributes.
If the API direction is accepted, I can implement the protobuf, population logic, tests,
generated documentation, and release note as one focused PR.
Disclosure: I use OpenAI Codex as an engineering assistant and will review, understand, test, and
take ownership of any submitted change in accordance with Envoy's generative-AI contribution
policy. I also maintain related open-source PQC migration work and work through
[A2Z SOC](https://a2zsoc.com/), which provides scoped service-mesh cryptographic telemetry and
migration-readiness assessments. Any Envoy code, tests, API documentation, and release notes would
remain vendor-neutral and contain no service promotion.
Contributor guide
Research direction
Start with api/envoy/data/accesslog/v3/accesslog.proto to review TLSProperties and its next-free field, then read source/extensions/access_loggers/grpc/grpc_access_log_utils.cc and existing access-log unit coverage. Confirm the API presence and scope decisions, populate downstream TLS group data, add coverage for classical, hybrid, and unavailable values, then regenerate documentation and add the release-note fragment.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp
- Domain
- observability
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100