Skip to content

Support GAPIC unary operations and configurable TLS - #7

Merged
samuel-williams-shopify merged 20 commits into
mainfrom
fix-grpc-interoperability
Sep 24, 2026
Merged

samuel-williams-shopify merged 20 commits into
mainfrom
fix-grpc-interoperability

Conversation

@samuel-williams-shopify

@samuel-williams-shopify samuel-williams-shopify commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

GAPIC unary calls need deferred operations and authentication callbacks, while Google/proxy responses expose content-type, metadata, and HTTP-response handling failures. Add return_op: true operations with execution, deadlines, cancellation, status, and response metadata, plus ClientStub.for(Service) and an optional GapicServiceStub adapter for generated unary clients.

Support Compatible::ChannelCredentials.new(root_certificates, private_key, certificate_chain) with grpc-ruby's positional PEM arguments. The ChannelCredentials module provides a factory that returns IO::Endpoint::TLS::Configuration directly, so the stub needs no credential wrapper handling. Preserve custom trust roots and client certificate chains; omitted roots use the transport's default trust store, and gRPC-specific root overrides must be supplied explicitly. Peer and hostname verification are enabled by default, including localhost. Explicit target schemes must match the credentials. Native gRPC credential objects are rejected because their TLS material and composed callbacks cannot be recovered through Ruby's public API. Existing callers can use Compatible::ChannelCredentials.new with the original PEM inputs; no process-wide GRPC constants are replaced.

Authentication callbacks run on each execution with the service's :jwt_aud_uri, derived from the actual channel endpoint. Merge their returned authentication headers into request metadata and keep the authentication context out of HTTP headers. Support original Google credential objects through updater_proc, and reject callbacks on plaintext channels or shared clients whose endpoint is unknown. The adapter preserves original credentials at GAPIC's stub-construction boundary; documentation includes a KMS example and custom TLS configuration.

Requests use application/grpc, and binary metadata uses the shared protocol decoder. Map native Async::GRPC::ResponseError to grpc-ruby errors using the HTTP status, retaining the cause and its buffered response. Callers can inspect error.cause.response and read error.cause.response.read for diagnostics.

Unit tests cover TLS argument mapping, certificate bundle ordering, incomplete identities, operation state, cancellation cleanup, thread boundaries, and GAPIC channel ownership. HTTP/2 integration tests exercise GAPIC with real Google JWT credentials and verify the signature and audience. Local TLS tests cover custom roots, hostname verification, and mutual authentication, including a GAPIC call using mapped gRPC client credentials and rejection of untrusted servers and missing client certificates.

Fixes #2.
Fixes #3.
Fixes #4.
Fixes #6.

Transport-error translation in #5 remains separate work. Socket and TLS failures can still raise native Ruby exceptions. Supported RPC scope is unary; active cancellation runs in the same Async reactor. Native GAPIC channel pools, interceptors, and additional native operation controls remain unsupported.

Requires released async-grpc ~> 0.10, async-http ~> 0.100, and io-endpoint ~> 0.18. The existing optional sibling-checkout preference remains available for local development.

Validation: COVERAGE=PartialSummary bundle exec bake test (99 tests, 344 assertions; 275/275 lines executed), bundle exec rubocop (26 files), and bundle exec bake decode:index:coverage lib (28/28 public definitions). Tested on Ruby 4.0.7 against published async-grpc 0.10.0, protocol-grpc 0.16.0, async-http 0.105.0, and io-endpoint 0.18.0 in an isolated checkout. Tests generate local credentials and certificates; no live Google services or production credentials are used.

@samuel-williams-shopify
samuel-williams-shopify marked this pull request as ready for review September 24, 2026 04:09
@samuel-williams-shopify samuel-williams-shopify changed the title Support GAPIC unary operations and call credentials Support GAPIC unary operations and configurable TLS Sep 24, 2026
@samuel-williams-shopify
samuel-williams-shopify merged commit a057527 into main Sep 24, 2026
22 checks passed
@samuel-williams-shopify
samuel-williams-shopify deleted the fix-grpc-interoperability branch September 24, 2026 08:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment