Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Sep 29, 2025

  • Initial plan
  • Implement Authorization header expansion with mTLS support
  • Simplify ArgumentNullException for all target frameworks
  • Rename MTlsCertificate to BindingCertificate for better clarity
  • Remove AdditionalHeaders property to simplify the design
  • Fix extra closing curly bracket in AuthorizationHeaderInformation.cs
  • Use ArgumentNullException.ThrowIfNull for NET8.0_OR_GREATER target frameworks
Original prompt

This section details on the original issue you should resolve

<issue_title>Design proposal: Expand Authorization header to support multiple values including mTLS certificate</issue_title>
<issue_description>## Summary

This proposal is to expand the current authorization header abstraction to support richer scenarios, such as providing a JWT token and an mTLS certificate (mTLS Pop), by introducing new types and a result structure.

Motivation and goals

  • Many modern APIs require more than just a simple Bearer token in the Authorization header (bearer or another protocol based on tokens). Some require additional values, such as mTLS certificates for mutual TLS authentication.
  • The current interface IAuthorizationHeaderProvider only supports a single string for the authorization header, making it hard to extend for these use cases. There is another interface though IAuthorizationHeaderProvider which would work.
  • By providing an extensible result type, we will enable downstream libraries and applications to support richer authentication scenarios.

In scope

  • New types for encapsulating authorization header information and errors.
  • A generic result class for success/error handling.
  • An implicit conversion that allows existing code expecting a string to continue working.

Out of scope

  • Implementation of the acquisition logic for certificates or tokens.
  • Changes to the HTTP pipeline integration with HttpClient (integration will be documented separately).

Risks / unknowns

  • Developers may misuse the implicit conversion to string and ignore richer information (such as certificate or additional headers). This is fine for simple scenarios (bearer tokens)
  • Security: Ensure sensitive material (such as certificates) is handled securely and not logged.

Examples

API Usage

public class MyAuthorizationHeaderProvider : IAuthorizationHeaderProvider<AuthorizationHeaderResult>
{
    public async Task<AuthorizationHeaderResult> CreateAuthorizationHeaderAsync(
        DownstreamApiOptions downstreamApiOptions,
        ClaimsPrincipal? claimsPrincipal = null,
        CancellationToken cancellationToken = default)
    {
        // Implementation here...
    }
}

Class Definitions

using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;

namespace Microsoft.Identity.Abstractions
{
    public class AuthorizationHeaderInformation
    {
        public string? AuthorizationHeaderValue { get; set; }
        public X509Certificate2? MTlsCertificate { get; set; }
        public IDictionary<string, string>? AdditionalHeaders { get; set; }
    }

    public class AuthorizationHeaderError
    {
        public string Code { get; set; } = string.Empty;
        public string Message { get; set; } = string.Empty;
        public Exception? Exception { get; set; }
    }

   // Operation Result already exists under src/Results

    public class AuthorizationHeaderResult : OperationResult<AuthorizationHeaderInformation, AuthorizationHeaderError>
    {
        public AuthorizationHeaderResult(
            AuthorizationHeaderInformation? info,
            AuthorizationHeaderError? error)
            : base(info, error) { }

        public static implicit operator string(AuthorizationHeaderResult result)
        {
            if (!result.Succeeded)
            {
                if (result.Error?.Exception != null)
                {
                    throw result.Error.Exception;
                }
                throw new InvalidOperationException($"Authorization header creation failed. Code: {result.Error?.Code}, Message: {result.Error?.Message}");
            }
            return result.Result?.AuthorizationHeaderValue ?? string.Empty;
        }
    }
}

</issue_description>

<agent_instructions>Please let's co-create together, iteratively. Let's make sure we have unit tests, and the XML documentation is updated.
</agent_instructions>

Comments on the Issue (you are @copilot in this section)

Fixes #208

💡 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 in the docs.

- Add AuthorizationHeaderInformation class with support for authorization header value, mTLS certificate, and additional headers
- Add AuthorizationHeaderError class extending OperationError for error handling
- Add AuthorizationHeaderResult class wrapping OperationResult with implicit string conversion for backward compatibility
- Add comprehensive unit tests covering all functionality and edge cases
- Update all PublicAPI.Unshipped.txt files for target frameworks
- All 79 tests passing including 18 new authorization header tests

Co-authored-by: jmprieur <[email protected]>
Copilot AI changed the title [WIP] Design proposal: Expand Authorization header to support multiple values including mTLS certificate Expand Authorization header to support multiple values including mTLS certificate Sep 29, 2025
Copilot AI requested a review from jmprieur September 29, 2025 16:18
Copilot finished work on behalf of jmprieur September 29, 2025 16:18
@MZOLN
Copy link

MZOLN commented Sep 29, 2025

Is a per-header size limit a concern? JWT size can vary, due to custom claims and by embedding the certificate into the same header we might be putting additional strain on the customizability. We might need to document additional mitigations per server platform in case we embed them together.

@jmprieur
Copy link
Contributor

Is a per-header size limit a concern? JWT size can vary, due to custom claims and by embedding the certificate into the same header we might be putting additional strain on the customizability. We might need to document additional mitigations per server platform in case we embed them together.

I don't understand. Which header are your talking about, @MZOLN ? the AuthorizationHeader? how is it different from today?.
Do you want to provide repro steps? We don't want to embed the certificate in any header circulating on the wire. this is the API that is going to be used by higher level APIs (Graph SDK adapter, Azure SDK adapter, DownstreamAPI, and MicrosoftIdentityDelegatingHandler)

Copy link
Contributor Author

Copilot AI commented Sep 30, 2025

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:

  • 0t3vsblobprodcus362.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
    • Triggering command: dotnet restore --no-cache (dns block)
  • 11vvsblobprodcus336.vsblob.vsassets.io
    • Triggering command: dotnet restore --no-cache (dns block)
  • 1oavsblobprodcus350.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • 1s1vsblobprodcus386.vsblob.vsassets.io
    • Triggering command: dotnet restore --no-cache (dns block)
  • 4vyvsblobprodcus361.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
    • Triggering command: dotnet restore --no-cache (dns block)
  • 4zjvsblobprodcus390.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • 51yvsblobprodcus36.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • 96bvsblobprodcus338.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • c50vsblobprodcus330.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • c78vsblobprodcus322.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • ckzvsblobprodcus347.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
    • Triggering command: dotnet restore --no-cache (dns block)
  • kmuvsblobprodcus389.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • l49vsblobprodcus358.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • lylvsblobprodcus31.vsblob.vsassets.io
    • Triggering command: dotnet restore --no-cache (dns block)
  • n3kvsblobprodcus335.vsblob.vsassets.io
    • Triggering command: dotnet restore --no-cache (dns block)
  • pdfvsblobprodcus380.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • s8mvsblobprodcus38.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • sqdvsblobprodcus333.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
  • vb4vsblobprodcus33.vsblob.vsassets.io
    • Triggering command: dotnet build src/Microsoft.Identity.Abstractions/Microsoft.Identity.Abstractions.csproj --configuration Release (dns block)
    • Triggering command: dotnet restore --no-cache (dns block)

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

Copilot AI requested a review from jmprieur September 30, 2025 01:15
Copilot finished work on behalf of jmprieur September 30, 2025 01:15
@jmprieur jmprieur marked this pull request as ready for review September 30, 2025 02:09
@jmprieur jmprieur requested a review from a team as a code owner September 30, 2025 02:09
Copilot finished work on behalf of jmprieur September 30, 2025 19:52
Copilot AI changed the title Expand Authorization header to support multiple values including mTLS certificate Expand Authorization header to support binding certificate for mTLS scenarios Sep 30, 2025
Copilot finished work on behalf of jmprieur September 30, 2025 19:58
Copy link
Contributor

@jmprieur jmprieur left a comment

Choose a reason for hiding this comment

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

LGTM
Thanks @copilot

Copilot AI requested a review from jmprieur September 30, 2025 21:56
Copilot finished work on behalf of jmprieur September 30, 2025 21:56
Copy link
Contributor

@jmprieur jmprieur left a comment

Choose a reason for hiding this comment

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

LGTM

Copilot AI requested a review from jmprieur September 30, 2025 22:09
Copilot finished work on behalf of jmprieur September 30, 2025 22:09
@jmprieur jmprieur merged commit c37a0a9 into main Oct 1, 2025
5 checks passed
@jmprieur jmprieur deleted the copilot/fix-21da73c6-fedd-4bf7-baac-d1cc6c47defb branch October 1, 2025 22:17
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.

Design proposal: Expand Authorization header to support multiple values including mTLS certificate

7 participants