Skip to content

Generate gRPC test TLS material at runtime instead of committing it#878

Open
ahmedmuhsin wants to merge 2 commits into
Azure:devfrom
ahmedmuhsin:fix/remove-grpc-tls-test-certs
Open

Generate gRPC test TLS material at runtime instead of committing it#878
ahmedmuhsin wants to merge 2 commits into
Azure:devfrom
ahmedmuhsin:fix/remove-grpc-tls-test-certs

Conversation

@ahmedmuhsin

Copy link
Copy Markdown
Contributor

Summary

The gRPC transport tests shipped a self-signed localhost certificate, its private key, and a PKCS12 truststore under src/test/resources/grpc-tls/. Committing a PEM private key + PKCS12 bundle trips secret scanning and hard-blocks the internal ADO mirror push:

VS403654:NonbypassableBlock
  SEC101/013 : PemPrivateKey                     -> localhost-key.pem
  SEC101/055 : Pkcs12CertificatePrivateKeyBundle -> localhost-truststore.p12

This replaces the committed key material with runtime generation, so no private keys live in the repo.

What changed

  • New TestTlsMaterial — generates an ephemeral CN=localhost keypair, certificate, and matching PKCS12 truststore at test runtime using the JDK's keytool. keytool ships with every JDK (8–25), so this stays portable across the CI Java matrix without adding a certificate-generation dependency (e.g. Bouncy Castle) and without --add-exports for sun.security internals. Material is written to a temp dir deleted on JVM exit, generated once per JVM.
  • FunctionsTestHost — builds the server SslContext from the generated PKCS12 keystore (PrivateKey + X509Certificate[]) instead of PEM resource files.
  • GrpcTransportTest — points the client truststore at the generated PKCS12 truststore instead of the committed resource.
  • Deleted src/test/resources/grpc-tls/{localhost-cert.pem,localhost-key.pem,localhost-truststore.p12}.
  • .gitignore guards (src/test/resources/grpc-tls/, *.p12, *.pfx, *-key.pem) so keys/keystores can't be re-committed. Verified no currently-tracked files match these patterns.

Testing

mvn test -Dtest=GrpcTransportTest
-> Tests run: 3, Failures: 0, Errors: 0, Skipped: 0

Covers all three existing cases against the runtime-generated cert:

  • legacy plaintext transport
  • trusted HTTPS/TLS handshake
  • HTTPS does not downgrade to plaintext when TLS fails

Important caveat

This removes the files from the branch tip and prevents recurrence, but it does not on its own unblock the mirror. The hard-block is reported at the commit that introduced the key (079a4d40), which still exists in the history the mirror replays. Fully clearing the mirror still requires either:

  1. a history rewrite to purge those blobs from every mirrored ref (dev, release/*, etc.) + force-push, or
  2. a 1ES secret-scanning exception for those fingerprints/path.

This PR is the clean forward-fix that makes the eventual history purge final and stops new keys from landing.

The gRPC transport tests shipped a self-signed localhost certificate, its
private key, and a PKCS12 truststore under src/test/resources/grpc-tls/.
Committing a PEM private key + PKCS12 bundle trips secret scanning (SEC101/013
PemPrivateKey, SEC101/055 Pkcs12CertificatePrivateKeyBundle) and hard-blocks
the internal ADO mirror push (VS403654 NonbypassableBlock).

Replace the committed files with TestTlsMaterial, which generates an ephemeral
CN=localhost keypair, certificate, and matching truststore at test runtime
using the JDK's keytool. keytool ships with every JDK (8-25), so this stays
portable across the CI Java matrix without adding a certificate-generation
dependency (e.g. Bouncy Castle) and without needing --add-exports for
sun.security internals.

- TestTlsMaterial: keytool-driven generator, lazily initialized once per JVM,
  writing to a temp dir that is deleted on exit.
- FunctionsTestHost: builds the server SslContext from the generated PKCS12
  keystore (PrivateKey + X509Certificate) rather than PEM resource files.
- GrpcTransportTest: points the client truststore at the generated PKCS12
  truststore instead of the committed resource.
- Delete src/test/resources/grpc-tls/* and add .gitignore guards so keys and
  keystores cannot be re-committed.

Note: this removes the files from the branch tip only. Purging them from the
history that the mirror replays (commit 079a4d4) still requires a separate
history rewrite or a 1ES exception.

Verified: mvn test -Dtest=GrpcTransportTest -> 3 passed (plaintext, trusted
HTTPS/TLS, and HTTPS-no-plaintext-downgrade).
@ahmedmuhsin ahmedmuhsin marked this pull request as ready for review June 17, 2026 00:00
- Replace wildcard imports introduced by this PR with explicit imports
  (FunctionsTestHost, GrpcTransportTest); drop a now-unused java.net import.
- Make buildServerSslContext an instance method.
- Narrow initializeServer/buildServerSslContext throws to
  GeneralSecurityException and IOException instead of Exception.
- Reduce the generated cert validity from 7300 days to 2; it only needs to
  outlive a single test run.
- Throw IOException (not IllegalStateException) on keytool timeout/non-zero
  exit so the constructor's catch wraps all failures in one message.
- Validate keytool is present and executable before invoking it.
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