Skip to content

[QUERY] Is it safe to put a TokenCredential in com.azure.core.util.Context for a custom HttpPipelinePolicy? #48953

@ashutoshsuman99

Description

@ashutoshsuman99

Query/Question

We're using com.azure.core.util.Context to pass a per-request TokenCredential (an AzureTokenCredentials representing a customer's auxiliary tenant identity) into a custom HttpPipelinePolicy that stamps the
x-ms-authorization-auxiliary header on outgoing ARM requests. The pattern lets a single shared HttpPipeline serve many customers without binding any one customer's credential to the pipeline at construction time. We need a single shared HttpPipeline to scale our systems better.

Concretely:

// Caller side — per-request, per-customer:
Context ctx = new Context("x-aux-secondary-token", customerSecondaryCredential);                                                                                                                                                                  
vmUpdate.apply(ctx);  // Appliable<T>.apply(Context)                                                                                                                                                                                              
                                                                                                                                                                                                                                                  
// Policy side — stateless:                                                                                                                                                                                                                       
public class AuxiliaryAuthPolicy implements HttpPipelinePolicy {                                                                                                                                                                                  
  @Override     
  public Mono<HttpResponse> process(HttpPipelineCallContext context, HttpPipelineNextPolicy next) {                                                                                                                                               
    Optional<Object> tokenOpt = context.getData("x-aux-secondary-token");                                                                                                                                                                         
    if (tokenOpt.isPresent()) {                                                                                                                                                                                                                   
      AzureTokenCredentials cred = (AzureTokenCredentials) tokenOpt.get();                                                                                                                                                                        
      String bearer = cred.getToken(cred.environment().resourceManagerEndpoint());                                                                                                                                                                
      context.getHttpRequest().setHeader("x-ms-authorization-auxiliary", "Bearer " + bearer);                                                                                                                                                     
    }                                                                                                                                                                                                                                             
    return next.process();                                                                                                                                                                                                                        
  }                                                                                                                                                                                                                                               
}               

Questions, in order of priority:

  1. Does any data placed in com.azure.core.util.Context (or surfaced to a policy via HttpPipelineCallContext.getData(...)) cross the wire to Azure? Our reading of the SDK source and the JavaDoc is that Context is purely an in-memory JVM carrier — the only thing transmitted is what a policy explicitly writes onto HttpRequest. Can you confirm? A pointer to the authoritative doc/source line would help.

  2. Is putting a TokenCredential reference (not a resolved bearer string) in Context considered safe by the SDK team? We've reviewed Context lifecycle (per-request, immutable, GC'd after the reactive chain terminates) and AzureTokenCredentials.toString() (defaults to Object.toString, no secret leakage). Are there any SDK-level paths — diagnostic logging, retry policies, telemetry, error reporting — that might serialize, log, or persist Context contents in a way that would expose the credential reference?

  3. Is there a more idiomatic pattern for the underlying problem? Specifically: a single shared HttpPipeline (and AzureResourceManager) that needs to attach a different secondary auxiliary token per customer, without rebuilding the pipeline.

Why is this not a Bug or a feature Request?

This is a design/security review request, not a defect report or feature ask. We want guidance on whether
this is a safe and intended use of those APIs before shipping it, and whether the SDK team would steer us toward a different idiom.

Setup (please complete the following information if applicable):

  • OS: Linux (production), macOS (dev)
  • IDE: IntelliJ
  • Library/Libraries: com.azure:azure-core, com.azure.resourcemanager:azure-resourcemanager-compute, com.microsoft.azure:azure-client-authentication

Information Checklist

  • Query Added
  • Setup information Added

Metadata

Metadata

Assignees

No one assigned

    Labels

    customer-reportedIssues that are reported by GitHub users external to the Azure organization.needs-triageWorkflow: This is a new issue that needs to be triaged to the appropriate team.questionThe issue doesn't require a change to the product in order to be resolved. Most issues start as that

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions