From 25c74f10dce1cfdd5c29b48420e777516a2cc53d Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:29:52 +0000 Subject: [PATCH 1/2] Initial plan From a35833367413713a3f2cf220a19566833d16cbc4 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 27 Jul 2026 21:39:05 +0000 Subject: [PATCH 2/2] Add azure-deprecating to default allowed HTTP headers list Add `azure-deprecating` to the default unsanitized/allowed response header list in both `azure-core` (HttpLogOptions) and `clientcore/core` (HttpInstrumentationOptions), so the header is logged without redaction by default. Also add the corresponding `AZURE_DEPRECATING` constant to both `HttpHeaderName` classes and update tests and changelogs. Related: https://github.com/microsoft/api-guidelines/blob/vNext/azure/Guidelines.md#deprecating-behavior-notification Co-authored-by: heaths <1532486+heaths@users.noreply.github.com> --- sdk/clientcore/core/CHANGELOG.md | 2 ++ .../core/http/models/HttpHeaderName.java | 5 +++++ .../pipeline/HttpInstrumentationOptions.java | 2 +- .../HttpInstrumentationLoggingTests.java | 6 ++++++ sdk/core/azure-core/CHANGELOG.md | 1 + .../com/azure/core/http/HttpHeaderName.java | 5 +++++ .../azure/core/http/policy/HttpLogOptions.java | 18 +++++++++--------- .../core/http/policy/HttpLogOptionsTest.java | 7 +++++++ 8 files changed, 36 insertions(+), 10 deletions(-) diff --git a/sdk/clientcore/core/CHANGELOG.md b/sdk/clientcore/core/CHANGELOG.md index 74dfa25695ea..ac92e98dd8b9 100644 --- a/sdk/clientcore/core/CHANGELOG.md +++ b/sdk/clientcore/core/CHANGELOG.md @@ -4,6 +4,8 @@ ### Features Added +- Added `azure-deprecating` to the default allowed (unsanitized) HTTP response header list so it is logged without redaction. + ### Breaking Changes - Changed `HttpRetryOptions.delayFromHeaders` to `HttpRetryOptions.delayFromRetryCondition`. The `Function` is now a `Function` instead of `Function`. This allows richer inspection diff --git a/sdk/clientcore/core/src/main/java/io/clientcore/core/http/models/HttpHeaderName.java b/sdk/clientcore/core/src/main/java/io/clientcore/core/http/models/HttpHeaderName.java index ead89cf69c36..6bf9b346dba9 100644 --- a/sdk/clientcore/core/src/main/java/io/clientcore/core/http/models/HttpHeaderName.java +++ b/sdk/clientcore/core/src/main/java/io/clientcore/core/http/models/HttpHeaderName.java @@ -173,6 +173,11 @@ public boolean equals(Object obj) { */ public static final HttpHeaderName AUTHORIZATION = fromString("Authorization"); + /** + * {@code azure-deprecating} + */ + public static final HttpHeaderName AZURE_DEPRECATING = fromString("azure-deprecating"); + /** * {@code Cache-Control}/{@code cache-control} */ diff --git a/sdk/clientcore/core/src/main/java/io/clientcore/core/http/pipeline/HttpInstrumentationOptions.java b/sdk/clientcore/core/src/main/java/io/clientcore/core/http/pipeline/HttpInstrumentationOptions.java index 4f11ecff8edf..d6ee1dee752e 100644 --- a/sdk/clientcore/core/src/main/java/io/clientcore/core/http/pipeline/HttpInstrumentationOptions.java +++ b/sdk/clientcore/core/src/main/java/io/clientcore/core/http/pipeline/HttpInstrumentationOptions.java @@ -92,7 +92,7 @@ public final class HttpInstrumentationOptions extends InstrumentationOptions { HttpHeaderName.ETAG, HttpHeaderName.EXPIRES, HttpHeaderName.IF_MATCH, HttpHeaderName.IF_MODIFIED_SINCE, HttpHeaderName.IF_NONE_MATCH, HttpHeaderName.IF_UNMODIFIED_SINCE, HttpHeaderName.LAST_MODIFIED, HttpHeaderName.PRAGMA, HttpHeaderName.RETRY_AFTER, HttpHeaderName.SERVER, HttpHeaderName.TRANSFER_ENCODING, - HttpHeaderName.USER_AGENT, HttpHeaderName.WWW_AUTHENTICATE); + HttpHeaderName.USER_AGENT, HttpHeaderName.WWW_AUTHENTICATE, HttpHeaderName.AZURE_DEPRECATING); static final HttpLogLevel ENVIRONMENT_HTTP_LOG_LEVEL = HttpLogLevel.fromConfiguration(Configuration.getGlobalConfiguration()); diff --git a/sdk/clientcore/core/src/test/java/io/clientcore/core/http/pipeline/HttpInstrumentationLoggingTests.java b/sdk/clientcore/core/src/test/java/io/clientcore/core/http/pipeline/HttpInstrumentationLoggingTests.java index adb1e625f10b..9f7f09517f13 100644 --- a/sdk/clientcore/core/src/test/java/io/clientcore/core/http/pipeline/HttpInstrumentationLoggingTests.java +++ b/sdk/clientcore/core/src/test/java/io/clientcore/core/http/pipeline/HttpInstrumentationLoggingTests.java @@ -65,6 +65,12 @@ public HttpInstrumentationLoggingTests() { this.logCaptureStream = new AccessibleByteArrayOutputStream(); } + @Test + public void defaultAllowlistContainsAzureDeprecating() { + assertTrue(new HttpInstrumentationOptions().getAllowedHeaderNames().contains(HttpHeaderName.AZURE_DEPRECATING), + "azure-deprecating should be in the default headers allowlist"); + } + @ParameterizedTest @MethodSource("disabledHttpLoggingSource") public void testDisabledHttpLogging(LogLevel logLevel, HttpInstrumentationOptions.HttpLogLevel detailLevel) diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md index 41f07fe5cf61..530f8809a94a 100644 --- a/sdk/core/azure-core/CHANGELOG.md +++ b/sdk/core/azure-core/CHANGELOG.md @@ -4,6 +4,7 @@ ### Features Added +- Added `azure-deprecating` to the default allowed (unsanitized) HTTP response header list so it is logged without redaction. ([#XXXXX](https://github.com/Azure/azure-sdk-for-java/pull/XXXXX)) - Promoted `AccessTokenCache` to a public API in the `com.azure.core.credential` package. This class provides a thread-safe, proactively refreshing token cache that wraps a `TokenCredential`, supporting both synchronous and asynchronous token retrieval. ### Breaking Changes diff --git a/sdk/core/azure-core/src/main/java/com/azure/core/http/HttpHeaderName.java b/sdk/core/azure-core/src/main/java/com/azure/core/http/HttpHeaderName.java index 3b22f002a9b6..7fc3550fcc91 100644 --- a/sdk/core/azure-core/src/main/java/com/azure/core/http/HttpHeaderName.java +++ b/sdk/core/azure-core/src/main/java/com/azure/core/http/HttpHeaderName.java @@ -181,6 +181,11 @@ public boolean equals(Object obj) { */ public static final HttpHeaderName AZURE_ASYNCOPERATION = fromString("Azure-AsyncOperation"); + /** + * {@code azure-deprecating} + */ + public static final HttpHeaderName AZURE_DEPRECATING = fromString("azure-deprecating"); + /** * {@code Cache-Control}/{@code cache-control} */ diff --git a/sdk/core/azure-core/src/main/java/com/azure/core/http/policy/HttpLogOptions.java b/sdk/core/azure-core/src/main/java/com/azure/core/http/policy/HttpLogOptions.java index 09bf902fca7e..6c2b85430261 100644 --- a/sdk/core/azure-core/src/main/java/com/azure/core/http/policy/HttpLogOptions.java +++ b/sdk/core/azure-core/src/main/java/com/azure/core/http/policy/HttpLogOptions.java @@ -73,15 +73,15 @@ public class HttpLogOptions { private static final String INVALID_APPLICATION_ID_LENGTH = "'applicationId' length cannot be greater than " + MAX_APPLICATION_ID_LENGTH; private static final String INVALID_APPLICATION_ID_SPACE = "'applicationId' cannot contain spaces."; - static final Set DEFAULT_HEADERS_ALLOWLIST - = Collections.unmodifiableSet(new HashSet<>(Arrays.asList(HttpHeaderName.X_MS_REQUEST_ID, - HttpHeaderName.X_MS_CLIENT_REQUEST_ID, X_MS_RETURN_CLIENT_REQUEST_ID, HttpHeaderName.TRACEPARENT, MS_CV, - HttpHeaderName.ACCEPT, HttpHeaderName.CACHE_CONTROL, HttpHeaderName.CONNECTION, - HttpHeaderName.CONTENT_LENGTH, HttpHeaderName.DATE, HttpHeaderName.ETAG, HttpHeaderName.EXPIRES, - HttpHeaderName.IF_MATCH, HttpHeaderName.IF_MODIFIED_SINCE, HttpHeaderName.IF_NONE_MATCH, - HttpHeaderName.IF_UNMODIFIED_SINCE, HttpHeaderName.LAST_MODIFIED, HttpHeaderName.PRAGMA, REQUEST_ID, - HttpHeaderName.RETRY_AFTER, HttpHeaderName.RETRY_AFTER_MS, HttpHeaderName.SERVER, - HttpHeaderName.TRANSFER_ENCODING, HttpHeaderName.USER_AGENT, HttpHeaderName.WWW_AUTHENTICATE))); + static final Set DEFAULT_HEADERS_ALLOWLIST = Collections.unmodifiableSet( + new HashSet<>(Arrays.asList(HttpHeaderName.X_MS_REQUEST_ID, HttpHeaderName.X_MS_CLIENT_REQUEST_ID, + X_MS_RETURN_CLIENT_REQUEST_ID, HttpHeaderName.TRACEPARENT, MS_CV, HttpHeaderName.ACCEPT, + HttpHeaderName.CACHE_CONTROL, HttpHeaderName.CONNECTION, HttpHeaderName.CONTENT_LENGTH, HttpHeaderName.DATE, + HttpHeaderName.ETAG, HttpHeaderName.EXPIRES, HttpHeaderName.IF_MATCH, HttpHeaderName.IF_MODIFIED_SINCE, + HttpHeaderName.IF_NONE_MATCH, HttpHeaderName.IF_UNMODIFIED_SINCE, HttpHeaderName.LAST_MODIFIED, + HttpHeaderName.PRAGMA, REQUEST_ID, HttpHeaderName.RETRY_AFTER, HttpHeaderName.RETRY_AFTER_MS, + HttpHeaderName.SERVER, HttpHeaderName.TRANSFER_ENCODING, HttpHeaderName.USER_AGENT, + HttpHeaderName.WWW_AUTHENTICATE, HttpHeaderName.AZURE_DEPRECATING))); static final List DEFAULT_QUERY_PARAMS_ALLOWLIST = Collections.singletonList("api-version"); diff --git a/sdk/core/azure-core/src/test/java/com/azure/core/http/policy/HttpLogOptionsTest.java b/sdk/core/azure-core/src/test/java/com/azure/core/http/policy/HttpLogOptionsTest.java index 967372e3fa56..97104f4b9add 100644 --- a/sdk/core/azure-core/src/test/java/com/azure/core/http/policy/HttpLogOptionsTest.java +++ b/sdk/core/azure-core/src/test/java/com/azure/core/http/policy/HttpLogOptionsTest.java @@ -2,6 +2,7 @@ // Licensed under the MIT License. package com.azure.core.http.policy; +import com.azure.core.http.HttpHeaderName; import org.junit.jupiter.api.Test; import static org.junit.jupiter.api.Assertions.assertEquals; @@ -35,4 +36,10 @@ public void testSetApplicationId() { public void testSetPrettyPrintBody() { assertTrue(new HttpLogOptions().setPrettyPrintBody(true).isPrettyPrintBody()); } + + @Test + public void defaultAllowlistContainsAzureDeprecating() { + assertTrue(HttpLogOptions.DEFAULT_HEADERS_ALLOWLIST.contains(HttpHeaderName.AZURE_DEPRECATING), + "azure-deprecating should be in the default headers allowlist"); + } }