Skip to content

feat(xds): expose CertificateProvider for custom certificate sources#2743

Open
LYZJU2019 wants to merge 2 commits into
grpc:masterfrom
LYZJU2019:lyzju2019/xds-custom-cert-provider
Open

feat(xds): expose CertificateProvider for custom certificate sources#2743
LYZJU2019 wants to merge 2 commits into
grpc:masterfrom
LYZJU2019:lyzju2019/xds-custom-cert-provider

Conversation

@LYZJU2019

@LYZJU2019 LYZJU2019 commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Motivation

tonic-xds currently sources data-plane (upstream) TLS certificates only from the built-in file_watcher plugin, configured through the bootstrap certificate_providers map (gRFC A29). Applications that obtain certificates from a different system have no way to plug in.

This mirrors the pluggable certificate-provider registries in grpc-go / grpc-java: applications can register their own provider implementation and have CDS-referenced instances resolve to it.

Changes

  • Promote CertificateProvider, CertificateData, and Identity to public API and re-export them from the crate root (gated on a TLS feature).
  • Add XdsChannelBuilder::with_certificate_provider(instance_name, provider) to register custom provider instances.
  • Add a general CertProviderError::Other variant so out-of-crate providers can surface their own failures.
  • Allow rustls::* in the cargo-check-external-types allowlist: CertificateData surfaces CA roots as a parsed rustls::RootCertStore.

Testing

  • cargo test -p tonic-xds --features tls-ring — all
  • cargo clippy -p tonic-xds --features tls-ring and default (no-TLS feature).
  • cargo doc with -D rustdoc::broken_intra_doc_links.

@LYZJU2019
LYZJU2019 force-pushed the lyzju2019/xds-custom-cert-provider branch from 1a4c1e0 to 6072b5a Compare July 19, 2026 21:44
Make the gRFC A29 data-plane TLS certificate provider API public so
applications can supply their own certificate source instead of the
built-in `file_watcher` plugin.

- Promote `CertificateProvider`, `CertificateData`, and `Identity` to
  public API and re-export them from the crate root (TLS features only).
- Add `XdsChannelBuilder::with_certificate_provider(instance_name,
  provider)` to register custom provider instances. They resolve by the
  instance name referenced in CDS `UpstreamTlsContext` resources and
  fully shadow a bootstrap `file_watcher` instance of the same name.
- Add a general `CertProviderError::Other` variant so out-of-crate
  providers can report their own failures.
- Allow `rustls::*` in the public API: CA roots surface as a parsed
  `RootCertStore`.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@LYZJU2019
LYZJU2019 force-pushed the lyzju2019/xds-custom-cert-provider branch from 6072b5a to c5f1072 Compare July 19, 2026 21:58
Comment thread tonic-xds/src/xds/cert_provider/mod.rs
Comment thread tonic-xds/src/xds/cert_provider/mod.rs
Comment thread tonic-xds/src/xds/cert_provider/mod.rs Outdated
pub(crate) key: Vec<u8>,
pub struct Identity {
/// PEM-encoded certificate chain.
pub cert_chain: Vec<u8>,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's use getters/setters for this type

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 87437c2

Comment thread tonic-xds/src/xds/cert_provider/mod.rs
Comment thread tonic-xds/src/client/channel.rs Outdated
&bootstrap.certificate_providers,
)?);
let cert_provider_registry = Arc::new(if self.cert_providers.is_empty() {
CertProviderRegistry::from_bootstrap(&bootstrap.certificate_providers)?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since this delegates to HashMap::new() anyway, can collapse to just the 2nd branch

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 87437c2

- Redact the private key in `Identity`'s `Debug` (manual impl).
- Mark `CertProviderError` `#[non_exhaustive]` for future extensibility.
- Encapsulate `Identity` behind `new()` + `cert_chain()`/`key()` accessors.
- Carry CA roots as PEM bytes instead of `rustls::RootCertStore`, for
  symmetry with the identity bytes and to drop rustls from the public API.
  The verifier parses the bundle into a `RootCertStore` at handshake time.
- Collapse the registry build into a single `from_bootstrap` call that
  takes the injected providers directly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants