Honor secure Functions host URIs in Java worker#872
Conversation
Agent-Logs-Url: https://github.com/larohra/azure-functions-java-worker/sessions/db76de91-28a8-4391-b3a2-d8796d6725e4 Co-authored-by: larohra <41490930+larohra@users.noreply.github.com>
Agent-Logs-Url: https://github.com/larohra/azure-functions-java-worker/sessions/db76de91-28a8-4391-b3a2-d8796d6725e4 Co-authored-by: larohra <41490930+larohra@users.noreply.github.com>
Agent-Logs-Url: https://github.com/larohra/azure-functions-java-worker/sessions/db76de91-28a8-4391-b3a2-d8796d6725e4 Co-authored-by: larohra <41490930+larohra@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR updates the Java worker to honor the scheme of the already-parsed --functions-uri when building the gRPC channel to the Functions host, enabling TLS when https is provided and preserving plaintext behavior for legacy host/port startup.
Changes:
- Add
IApplication#getFunctionsUri()(defaulting tonull) and expose the parsed Functions URI fromApplication. - Update
JavaWorkerClientto selectuseTransportSecurity()vsusePlaintext()based on the Functions URI scheme. - Add unit + functional tests for transport selection, including TLS test assets and a TLS-capable in-process test host.
Reviewed changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java | Selects TLS vs plaintext based on functions-uri scheme; adds scheme parsing/validation helper. |
| src/main/java/com/microsoft/azure/functions/worker/IApplication.java | Adds compatibility-safe default getFunctionsUri() accessor. |
| src/main/java/com/microsoft/azure/functions/worker/Application.java | Exposes parsed functions-uri via getFunctionsUri(); keeps getUri() delegating for compatibility. |
| src/test/java/com/microsoft/azure/functions/worker/JavaWorkerClientTest.java | Unit tests for scheme -> transport decision and invalid scheme handling. |
| src/test/java/com/microsoft/azure/functions/worker/ApplicationTest.java | Tests precedence of prefixed args vs legacy args and compatibility behavior. |
| src/test/java/com/microsoft/azure/functions/worker/functional/tests/GrpcTransportTest.java | Functional coverage for plaintext legacy, TLS success (trusted), and no plaintext downgrade on TLS failure. |
| src/test/java/com/microsoft/azure/functions/worker/test/utilities/FunctionsTestHost.java | Adds TLS-capable gRPC test server and URI-driven client transport selection for tests. |
| src/test/resources/grpc-tls/localhost-cert.pem | Adds test TLS certificate for localhost. |
| src/test/resources/grpc-tls/localhost-key.pem | Adds test TLS private key for localhost. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Agent-Logs-Url: https://github.com/larohra/azure-functions-java-worker/sessions/bc5fc454-8077-4ad5-b568-3befc6ceb14c Co-authored-by: larohra <41490930+larohra@users.noreply.github.com>
| } | ||
|
|
||
| String scheme = parseFunctionsUriScheme(functionsUri); | ||
| switch (scheme.toLowerCase(Locale.ROOT)) { |
There was a problem hiding this comment.
Consolidate URI parsing into Application.parseUri as the single source of truth. Validate the scheme there, default the port from the scheme, and decompose host/port. JavaWorkerClient.useTransportSecurity then collapses to a one-line scheme check. Today there are two parsers (URL in Application, URI in JavaWorkerClient) with different acceptance rules, and https://host/ without an explicit port is rejected by URL.getPort() == -1. Both go away with the consolidation. Small change, fits naturally with the rest of this PR.
| return this.uri; | ||
| } | ||
|
|
||
| public String getUri() { |
There was a problem hiding this comment.
This isn't being called, can it be removed?
ahmedmuhsin
left a comment
There was a problem hiding this comment.
What's the host-side timeline for emitting https:// URIs? The current host hardcodes http://127.0.0.1:port/ in AspNetCoreGrpcServer.cs, so this PR's TLS branch is dormant in production today. Is there a tracked host-side change to enable TLS that this PR is gating, or is this defense-in-depth ahead of any host plans? Either is fine, just helps reviewers calibrate.
Summary
JavaWorkerClientalways buildsManagedChannelBuilder.forAddress(...).usePlaintext(), so the Java worker ignores the already-parsed--functions-uriand can never join a secure host/worker gRPC channel.Findings
functions-uri, plus fallback to legacy args, butJavaWorkerClientwas not updated; this looks like an old assumption that became a gap once URI-based startup existed.functions-uriuseshttps, the worker should build a TLS gRPC channel and fail if handshake, certificate, or hostname validation fails. OnlyhttpURIs, or legacy startup that supplies just host+port, should continue to use plaintext.httpand legacy host+port launches keep their current behavior. The only observable behavior change is that a previously ignored or misconfiguredhttpsendpoint will stop connecting insecurely and instead fail closed.mvn testcurrently passes (63 tests, 0 failures/errors/skips). Repo CI also runs build plus emulated, docker, and end-to-end matrices, but there is no direct secure gRPC transport coverage.Plan
functions-urithroughIApplicationin a compatibility-safe way.JavaWorkerClientchoose transport from the URI scheme:https=> TLS with no plaintext downgrade,httpor legacy host+port => plaintext.mvn test.Issue describing the changes in this PR
resolves #issue_for_this_pr
Pull request checklist
release_notes.mdAdditional information
Additional PR information