Skip to content

Wire Server Telemetry response header, Fixes AB#3556246#3062

Merged
fadidurah merged 10 commits intodevfrom
fadi/server-telemetry
Apr 7, 2026
Merged

Wire Server Telemetry response header, Fixes AB#3556246#3062
fadidurah merged 10 commits intodevfrom
fadi/server-telemetry

Conversation

@fadidurah
Copy link
Copy Markdown
Contributor

@fadidurah fadidurah commented Mar 30, 2026

ESTS will begin sending telemetry data in a response, which we will be emitting in broker telemetry. Here's the spec: https://microsoft.sharepoint-df.com/:w:/s/AuthSTSDocs/IQDIrGUMsdxVSZE3GlsMkqaBAXVzDyEJg2wCZk1JN_DeSF0?e=teY6EN&wdExp=TEAMS-TREATMENT&web=1&isSPOFile=1&ovuser=72f988bf-86f1-41af-91ab-2d7cd011db47%2Cfadidurah%40microsoft.com&clickparams=eyJBcHBOYW1lIjoiVGVhbXMtRGVza3RvcCIsIkFwcFZlcnNpb24iOiI0OS8yNjAzMTIyMzAwNyIsIkhhc0ZlZGVyYXRlZFVzZXIiOmZhbHNlfQ%3D%3D

Changes:

  • Introduces ClientDataInfo to parse pipe-delimited x-ms-clientdata header (/token) and clientdata redirect query parameter (/authorize) values, and emit them as OpenTelemetry span attributes.
  • Wires clidata=1 into the authorization request and parses/emits telemetry on both authorize redirects and token responses.
  • All three call sites are gated behind a new ENABLE_SERVER_CLIENT_DATA_TELEMETRY flight (CommonFlight), which is enabled by default and can be turned off via ECS if issues arise in production.
  • Promotes "clientdata" to a shared constant (ClientDataInfo.CLIENTDATA_QUERY_PARAMETER) used at all reference sites.
  • Extends OpenTelemetry AttributeName with new server telemetry attributes (server_error, server_sub_error, server_cloud_instance, server_caller_data_boundary); reuses existing account_type.
  • Unit tests cover parsing, attribute emission, and flight-disabled behavior for all three call sites.

AB#3556246

Copilot AI and others added 2 commits March 26, 2026 18:35
…, Fixes AB#3557850 (#3056)

Android currently drops the `x-ms-clientdata` header on `/token`
responses and the `clientdata` redirect parameter on `/authorize` flows,
leaving on-call engineers without server-side error context in
`android_spans`. This PR captures and emits those fields as
OpenTelemetry span attributes.

## New: `ClientDataInfo` model
(`common4j/.../telemetry/ClientDataInfo.java`)
- `fromJson(urlEncodedJson)` — URL-decodes → JSON parse with keys
`Error`, `SubError`, `AccountType`, `cloud_instance`,
`caller_data_boundary`
- `fromPipeDelimited(urlEncodedValue)` — URL-decodes → splits on `|`;
positional format
`account_type|error|sub_error|caller_data_boundary|cloud_instance`,
minimum 3 segments
- `emitToSpan()` — sets non-null fields on the current OTel span; maps
`m`→`MSA` / `e`→`AAD` (unknown → `"UNKNOWN"`); truncates each value to
256 chars; reuses existing `AttributeName.account_type`
- Both parsers are fully wrapped in try/catch with WARN-level logging on
failure; return `null` on bad input

## Feature flag
`CommonFlight.ENABLE_SERVER_CLIENT_DATA_TELEMETRY`
(`"EnableServerClientDataTelemetry"`, default `false`) gates **all** new
behavior.

## Integration points
| Location | Change |
|---|---|
| `AbstractMicrosoftStsTokenResponseHandler` | Reads `x-ms-clientdata`
header via `response.getHeaderValue(X_MS_CLIENTDATA, 0)`, parses via
`fromJson`, calls `emitToSpan()` |
| `MicrosoftStsAuthorizationResultFactory` | Reads
`urlParameters.get("clientdata")`, parses via `fromPipeDelimited`, calls
`emitToSpan()` |
| `MicrosoftStsAuthorizationRequest` | Appends `clidata=1` to authorize
URL so eSTS/MSA includes `clientdata` in the redirect |

## Supporting additions
- `HttpConstants.HeaderField.X_MS_CLIENTDATA = "x-ms-clientdata"`
- `AttributeName`: `server_error`, `server_sub_error`,
`server_cloud_instance`, `server_caller_data_boundary` — these should
also be mirrored in the Broker repo's `AttributeName.java`

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `dl.google.com`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=1024m -XX:&#43;HeapDumpOnOutOfMemoryError -Xmx3072m
-Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant`
(dns block)
> - `identitydivision.pkgs.visualstudio.com`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=1024m -XX:&#43;HeapDumpOnOutOfMemoryError -Xmx3072m
-Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant`
(dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/AzureAD/microsoft-authentication-library-common-for-android/settings/copilot/coding_agent)
(admins only)
>
> </details>

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

Fixes
[AB#3557850](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3557850)

# Implement ClientDataInfo model, flight, and parsing for
x-ms-clientdata

Follow .github/copilot-instructions.md strictly.

## Objective

Implement parsing of the x-ms-clientdata server telemetry header (from
/token responses) and the clientdata query parameter (from /authorize
redirect URLs), emitting parsed fields as OpenTelemetry span attributes.
This gives on-call engineers server-side error context in android_spans.

## Target Repository

| Field | Value |
|-------|-------|
| Repo | AzureAD/microsoft-authentication-library-common-for-android |
| Base Branch | fadi/server-telemetry |
| Module | common4j |

## Context

The eSTS and MSA identity services return telemetry data in the
x-ms-clientdata HTTP response header (on /token calls) and in the
clientdata query parameter on /authorize redirect URLs. This data
includes server-side error codes, account type, cloud instance, and data
boundary info. Today Android does not capture this on-call engineers
lack server-side error context when investigating auth failures.

For /authorize, HTTP response headers cannot be read from WebView or
browser flows, so the server provides the data as a URL query parameter
(clientdata) when the client opts in by appending clidata=1 to the
authorize URL. The /token endpoint is a direct HTTP call where headers
are fully accessible.

## Feature Flag

Wrap all new behavior behind
CommonFlight.ENABLE_SERVER_CLIENT_DATA_TELEMETRY (key:
EnableServerClientDataTelemetry, default: false).

## Technical Requirements

1. **New file:
common4j/src/main/com/microsoft/identity/common/java/telemetry/ClientDataInfo.java**
- Create a model class with fields: mError, mSubError, mAccountType,
mCloudInstance, mCallerDataBoundary
   - Use Lombok @Getter / @Setter annotations
- Add fromJson(@nullable String urlEncodedJson) URL-decodes the value,
parses JSON with keys Error, SubError, AccountType, cloud_instance,
caller_data_boundary. Returns null on failure. Wrap in try-catch, log at
WARN level on parse failure.
- Add fromPipeDelimited(@nullable String urlEncodedValue) URL-decodes,
splits on |. Positional format:
account_type|error|sub_error|caller_data_boundary|cloud_instance.
Require at least 3 segments. Returns null on failure.
- Add emitToSpan() sets each non-null field as a span attribute via
SpanExtension.current().setAttribute(...). Map account_type: m -> MSA, e
-> AAD, then set on existing AttributeName.account_type. Use
AttributeName.server_error, server_sub_error, server_cloud_instance,
server_caller_data_boundary for the other fields.
- Truncate each field to 256 characters max before emitting
(defense-in-depth).
- **Follow the pattern of existing CliTelemInfo.java** in
common4j/src/main/com/microsoft/identity/common/java/telemetry/CliTelemInfo.java.

2. **Modify
common4j/src/main/com/microsoft/identity/common/java/net/HttpConstants.java**
- Add constant: public static final String X_MS_CLIENTDATA =
x-ms-clientdata; in the HeaderField class.

3. **Modify
common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java**
- Add:
ENABLE_SERVER_CLIENT_DATA_TELEMETRY(EnableServerClientDataTelemetry,
false),

4. **Modify
common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java**
- Add enum values: server_error, server_sub_error,
server_cloud_instance, server_caller_data_boundary with doc comments. Do
NOT add server_account_type reuse existing account_type.

5. **Modify
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/AbstractMicrosoftStsTokenResponseHandler.java**
- In handleTokenResponse(), after the existing x-ms-clitelem parsing
block, add: if flight ENABLE_SERVER_CLIENT_DATA_TELEMETRY is enabled,
extract
response.getHeaderValue(HttpConstants.HeaderField.X_MS_CLIENTDATA, 0),
parse via ClientDataInfo.fromJson(), and call emitToSpan().

6. **Modify
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationResultFactory.java**
- In parseRedirectUriAndCreateAuthorizationResult(), before existing
result creation logic, add: if flight is enabled, extract
urlParameters.get(clientdata), parse via
ClientDataInfo.fromPipeDelimited(), and call emitToSpan().

7. **Modify
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationRequest.java**
- In getAuthorizationRequestAsHttpRequest(), when flight
ENABLE_SERVER_CLIENT_DATA_TELEMETRY is enabled, append query parameter
clidata=1 via builder.addParameterIfAbsent(clidata, 1).

## Scope

**In scope:**
- ClientDataInfo model class with dual parsers
- Feature flag
- HTTP header constant
- OTel attribute names
- Integration into token response handler and authorization result
factory
- Appending clidata=1 to authorize request

**Out of scope:**
- IPC contract changes
- Broker-specific or MSAL-specific code
- MicrosoftStsAuthorizationResponse changes (deferred)
-...

</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: fadidurah <88730756+fadidurah@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…ints, Fixes AB#3557852 (#3059)

Adds comprehensive test coverage for the `ClientDataInfo` model and the
three integration points that parse/emit server-side telemetry — all
changes are strictly under `src/test/`.

## `ClientDataInfoTest.java` (new, 16 tests)

| Area | Cases |
|---|---|
| `fromJson()` | valid full JSON, partial fields, malformed, null, empty
|
| `fromPipeDelimited()` | 5-segment, 3-segment, <3 segments (→ null),
empty segments, null, empty |
| `emitToSpan()` | all fields emitted, null fields skipped, `"m"` →
`"MSA"`, `"e"` → `"AAD"` |
| Truncation | field > 256 chars is capped at 256 |

`emitToSpan()` tests use `MockedStatic<SpanExtension>` (Mockito 5.11.0)
to assert exact `setAttribute` calls on a mock `Span`:

```java
try (MockedStatic<SpanExtension> mocked = Mockito.mockStatic(SpanExtension.class)) {
    mocked.when(SpanExtension::current).thenReturn(mockSpan);
    info.emitToSpan();
    verify(mockSpan).setAttribute(AttributeName.server_error.name(), "AADSTS50058");
    verify(mockSpan).setAttribute(AttributeName.account_type.name(), "MSA");
}
```

## Integration tests (existing files, tests-only additions)

- **`MicrosoftStsAuthorizationRequestTests`** — `clidata=1` present in
authorize URL when `ENABLE_SERVER_CLIENT_DATA_TELEMETRY` is on; absent
when off.
- **`MicrosoftStsAuthorizationResultFactoryTest`** — redirect with
`clientdata` param emits span attributes when flight enabled; no crash
when param absent or flight disabled.
- **`MicrosoftStsTokenResponseHandlerTest`** — `x-ms-clientdata`
response header triggers `emitToSpan()` when flight enabled; graceful
no-op otherwise.

Each modified test class resets `CommonFlightsManager.INSTANCE` in
`@After` to prevent state leakage.

> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `dl.google.com`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=1024m -XX:&#43;HeapDumpOnOutOfMemoryError -Xmx3072m
-Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant`
(dns block)
> - `identitydivision.pkgs.visualstudio.com`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=1024m -XX:&#43;HeapDumpOnOutOfMemoryError -Xmx3072m
-Dfile.encoding=UTF-8 -Duser.country -Duser.language=en -Duser.variant`
(dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/AzureAD/microsoft-authentication-library-common-for-android/settings/copilot/coding_agent)
(admins only)
>
> </details>

<!-- START COPILOT CODING AGENT SUFFIX -->



<!-- START COPILOT ORIGINAL PROMPT -->



<details>

<summary>Original prompt</summary>

> # [Server Telemetry][Common] Add unit tests for ClientDataInfo and
integration points
> 
> Fixes
[AB#3557852](https://identitydivision.visualstudio.com/fac9d424-53d2-45c0-91b5-ef6ba7a6bf26/_workitems/edit/3557852)
> 
> Follow .github/copilot-instructions.md strictly.
> 
> ---
> 
> ## ===== CRITICAL CONSTRAINT  READ BEFORE DOING ANYTHING =====
> 
> **DO NOT MODIFY ANY FILES UNDER src/main/.**
> 
> Two previous PRs (#3057 and #3058) were CLOSED because the agent
re-implemented production code that already exists in the base branch
`fadi/server-telemetry`, causing merge conflicts.
> 
> ALL production code already exists in the base branch
`fadi/server-telemetry` (merged via PR #3056):
> - `ClientDataInfo.java` model class with `fromJson()`,
`fromPipeDelimited()`, `emitToSpan()`
> - `CommonFlight.ENABLE_SERVER_CLIENT_DATA_TELEMETRY`
> - `HttpConstants.HeaderField.X_MS_CLIENTDATA`
> - `AttributeName` entries: `server_error`, `server_sub_error`,
`server_cloud_instance`, `server_caller_data_boundary`
> - Integration in `AbstractMicrosoftStsTokenResponseHandler`
> - Integration in `MicrosoftStsAuthorizationResultFactory`
> - `clidata=1` param in `MicrosoftStsAuthorizationRequest`
> 
> ### MANDATORY RULES:
> 1. **ONLY create or modify files under `src/test/`** absolutely NO
changes to `src/main/` files
> 2. **DO NOT re-create** `ClientDataInfo.java`
> 3. **DO NOT modify** `CommonFlight.java`, `HttpConstants.java`,
`AttributeName.java`
> 4. **DO NOT modify** `AbstractMicrosoftStsTokenResponseHandler`,
`MicrosoftStsAuthorizationResultFactory`,
`MicrosoftStsAuthorizationRequest`
> 5. If your PR diff contains ANY file under `src/main/`, YOUR PR WILL
BE REJECTED this is the 3rd attempt
> 
> Before writing code, first READ the existing production code from the
base branch to understand the actual API/signatures:
> -
`common4j/src/main/java/com/microsoft/identity/common/java/telemetry/ClientDataInfo.java`
> -
`common4j/src/main/java/com/microsoft/identity/common/java/flighting/CommonFlight.java`
> -
`common4j/src/main/java/com/microsoft/identity/common/java/telemetry/AttributeName.java`
> 
> ## ===== END CRITICAL CONSTRAINT =====
> 
> ---
> 
> ## Objective
> 
> Add comprehensive unit tests for the `ClientDataInfo` model class and
the modified integration points.
> 
> ## Target
> 
> - **Repo**:
AzureAD/microsoft-authentication-library-common-for-android
> - **Base Branch**: fadi/server-telemetry
> - **Module**: common4j
> 
> ## Technical Requirements
> 
> 1. **New test file:
`common4j/src/test/com/microsoft/identity/common/java/telemetry/ClientDataInfoTest.java`**
>    - Test `fromJson()`: valid URL-encoded JSON -> all 5 fields parsed
> - Test `fromJson()`: partial JSON (only Error + AccountType) -> those
set, others null
>    - Test `fromJson()`: malformed JSON -> returns null, no exception
>    - Test `fromJson()`: null input -> returns null
>    - Test `fromJson()`: empty string -> returns null
> - Test `fromPipeDelimited()`: valid 5-segment value -> all fields
parsed
> - Test `fromPipeDelimited()`: 3-segment value -> account type, error,
sub-error only
>    - Test `fromPipeDelimited()`: < 3 segments -> returns null
>    - Test `fromPipeDelimited()`: empty segments -> fields become null
> - Test `emitToSpan()`: all fields set -> all attributes emitted (mock
SpanExtension)
>    - Test `emitToSpan()`: some fields null -> null fields not emitted
> - Test `emitToSpan()`: account type `m` -> maps to `MSA` on
`account_type` attribute
>    - Test `emitToSpan()`: account type `e` -> maps to `AAD`
>    - Test field truncation: field > 256 chars -> truncated to 256
> 
> 2. **Modify existing test files for integration points (all under
src/test/ ONLY):**
> - Test `MicrosoftStsAuthorizationRequest`: when flight enabled,
authorize URL contains `clidata=1`; when disabled, URL does not contain
`clidata`
> - Test `MicrosoftStsAuthorizationResultFactory`: redirect URL with
`clientdata` param + flight enabled -> attributes emitted; without
`clientdata` -> no crash
> - Test `AbstractMicrosoftStsTokenResponseHandler`: mock HttpResponse
with `x-ms-clientdata` header + flight enabled -> attributes emitted; no
header -> no crash; flight disabled -> no parsing
> 
> Follow existing test patterns in:
> - `common4j/src/test/com/microsoft/identity/common/java/telemetry/`
for telemetry tests
> -
`common4j/src/test/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/`
for provider tests
> 
> ## Feature Flag
> 
> Tests should verify behavior with flight
`ENABLE_SERVER_CLIENT_DATA_TELEMETRY` both enabled and disabled.
> 
> ## Acceptance Criteria
> 
> - 14+ unit tests for `ClientDataInfo` covering all parsing, edge case,
and emission scenarios
> - Integration tests verifying flight gating works correctly
> - All tests pass: `./gradlew :common4j:testDebugUnitTest`
> - No existing tests broken
> - Test coverage for `ClientDataInfo.java` >= 90%
> - **ZERO files modified under src/main/**  this is a hard requirement
> 


</details>



<!-- START COPILOT CODING AGENT TIPS -->
---

⚡ Quickly spin up Copilot coding agent tasks from anywhere on your macOS
or Windows machine with [Raycast](https://gh.io/cca-raycast-docs).

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: fadidurah <88730756+fadidurah@users.noreply.github.com>
@fadidurah fadidurah requested a review from a team as a code owner March 30, 2026 18:19
Copilot AI review requested due to automatic review settings March 30, 2026 18:19
Comment thread common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java Outdated
@github-actions
Copy link
Copy Markdown

❌ Work item link check failed. Description does not contain AB#{ID}.

Click here to Learn more.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds support for capturing server-provided telemetry from eSTS/MSA via the x-ms-clientdata /token response header and the clientdata /authorize redirect query parameter, emitting the parsed values as OpenTelemetry span attributes (gated by a new flight).

Changes:

  • Introduces ClientDataInfo to parse URL-encoded JSON (x-ms-clientdata) and decoded pipe-delimited (clientdata) formats and emit attributes to the current span.
  • Adds flight-gated wiring to request (clidata=1) and to parse/emit telemetry on both authorize redirects and token responses.
  • Extends OpenTelemetry attribute names and adds unit tests covering parsing and emission behavior.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
common4j/src/main/com/microsoft/identity/common/java/telemetry/ClientDataInfo.java New model/parser for server telemetry and span emission.
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/AbstractMicrosoftStsTokenResponseHandler.java Parses x-ms-clientdata header (flight-gated) and emits span attributes.
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationResultFactory.java Parses clientdata query param from redirect URI (flight-gated) and emits span attributes.
common4j/src/main/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationRequest.java Adds clidata=1 to authorize request when the flight is enabled.
common4j/src/main/com/microsoft/identity/common/java/opentelemetry/AttributeName.java Adds new attribute keys for server telemetry fields.
common4j/src/main/com/microsoft/identity/common/java/net/HttpConstants.java Adds x-ms-clientdata header constant.
common4j/src/main/com/microsoft/identity/common/java/flighting/CommonFlight.java Adds ENABLE_SERVER_CLIENT_DATA_TELEMETRY flight.
common4j/src/test/com/microsoft/identity/common/java/telemetry/ClientDataInfoTest.java New unit tests for parsing (JSON + pipe) and span emission (including truncation).
common4j/src/test/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsTokenResponseHandlerTest.java Tests token response handling with/without header and with flight enabled/disabled.
common4j/src/test/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationResultFactoryTest.java Tests redirect parsing/emission with flight enabled and validates no-crash behavior.
common4j/src/test/com/microsoft/identity/common/java/providers/microsoft/microsoftsts/MicrosoftStsAuthorizationRequestTests.java Tests that clidata is present/absent depending on the flight.

@fadidurah fadidurah added the No-Changelog This Pull-Request has no associated changelog entry. label Apr 2, 2026
@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

✅ Work item link check complete. Description contains link AB#3556246 to an Azure Boards work item.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Apr 2, 2026

❌ Work item link check failed. Description contains AB#3556246 but the Bot could not link it to an Azure Boards work item.

Click here to learn more.

@github-actions github-actions Bot changed the title Wire Server Telemetry response header Wire Server Telemetry response header, Fixes AB#3556246 Apr 2, 2026
Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 6, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • www.puppycrawl.com
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/tools/linux64/java/bin/java /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/tools/linux64/java/bin/java -jar /opt/hostedtoolcache/CodeQL/2.25.1/x64/codeql/xml/tools/xml-extractor.jar --fileList=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/working/files-to-index15840176630227446451.list --sourceArchiveDir=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/src --outputDir=/tmp/codeql-scratch-b2678d0398b00160/dbs/java/trap/java (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@fadidurah fadidurah merged commit 3b53d1a into dev Apr 7, 2026
27 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

No-Changelog This Pull-Request has no associated changelog entry.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants