Customer API / Authentication

Use Microsoft Entra and Azure Key Vault

Let an Azure-hosted service authenticate to Key Vault, sign a Wavac client assertion, and exchange it for a Customer API access token.

In this article

Understand the trust boundary

Microsoft Entra ID can participate in a Customer API integration in two ways. Microsoft Entra token federation is available by request and requires Wavac to configure the integration for the approved issuer and token contract. The Key Vault pattern on this page is different: it uses Entra to authenticate an Azure workload to Key Vault while retaining the normal Wavac client-assertion flow.

The Key Vault pattern does not require federation to be enabled. Key Vault protects the RSA private key and signs the Wavac client assertion without exporting that key.

The credentials that cross these trust boundaries have separate purposes:

Credential Issuer and audience Purpose
Microsoft Entra access token Microsoft Entra, for Azure Key Vault Allows the Azure workload to ask Key Vault to sign.
Wavac client assertion Your integration, for the Wavac token endpoint Proves possession of the enrolled signing key.
Wavac access token Wavac authorization server, for the Customer API Authorizes Customer API requests.

Do not send the Entra access token used for Key Vault to the Customer API. Its audience is Key Vault, not Wavac. Likewise, an assertion created for a Microsoft identity platform token endpoint cannot be reused unchanged at the Wavac token endpoint. If federation has been enabled for your integration, follow the issuer, audience, claims, and endpoint requirements supplied during federation enrollment instead of the Key Vault procedure on this page.

Prepare the Azure workload

Enable a system-assigned or user-assigned managed identity for the Azure workload. Grant that identity only the Key Vault permissions needed to read the public key and request signatures. Microsoft Entra authenticates the workload to Key Vault, so the application does not need to store an Azure client secret.

Create an RSA key of at least 2048 bits in Key Vault and permit the RS256 signing operation. Keep the private key non-exportable. The service will send the JWT signing input to Key Vault and receive only the resulting signature.

Enroll the Key Vault public key

Read the RSA public modulus and exponent from Key Vault and construct the Wavac public JWK with kty set to RSA, use set to sig, and alg set to RS256. Calculate the RFC 7638 SHA-256 thumbprint from the public JWK and use that value for both the JWK kid and publicKeyThumbprint during enrollment.

Azure Key Vault identifies a key version with a Key Vault URL. Do not use that URL as the Wavac kid; Wavac requires the RFC 7638 thumbprint. Keep the Key Vault key URL in your application's private configuration so it can select the correct key version when signing.

Sign and exchange an assertion

Create the header and claims described in request an access token. Base64url-encode the header and claims, join them with a period, and ask Key Vault to sign that ASCII signing input using RS256. For example, Azure SDK SignData operations hash the input with SHA-256 before signing. If a lower-level signing operation expects a digest, calculate the SHA-256 digest once and submit the digest instead. Append the base64url-encoded signature to produce the compact client assertion.

Exchange that assertion at the Wavac token endpoint. Send the returned Wavac access token as the Bearer token on Customer API requests. The managed identity and its Entra token remain inside the Azure-to-Key Vault portion of the flow.

Verify the setup by calling discovery and confirming a 200 OK response. A signature failure usually means the assertion was signed with a different Key Vault key version than the public key enrolled with Wavac, or that kid is not the enrolled RFC 7638 thumbprint.

For the Azure side of this pattern, see Microsoft Learn guidance for managed identities and workload identities, Key Vault authentication, and Key Vault keys. The Azure SDK documentation for CryptographyClient.SignDataAsync shows the data-signing form of the operation.