Something that I've seen a bunch of times in Key Vault support cases is that the customer tries to use a token previously obtained to perform operations on Azure Services such as VMs, Websites, and even Key Vault to also access keys, secrets or certificates inside the Key Vault. They get understandably confused because the requests made about the Key Vault work fine. It's just that the requests made for Key Vault values fail with 401.
Azure's OAUTH client credentials grant protocol requires that the resource of the Web API being used is passed to the authentication server. The documentation states this:
||Enter the App ID URI of the receiving web service. To find the App ID URI, in the Azure portal, click Azure Active Directory, click App registrations, click the service application, and then click Settings and Properties.
This is the POST sample in the same documentation:
POST /contoso.com/oauth2/token HTTP/1.1
The highlighted area above is what I am referring to for this issue. There are multiple resources in Azure; here are a few that I am aware of:
|Azure Resource Manager (ARM)
||For performing operations on the various services hosted in the Azure portal.
||For obtaining information about objects inside the Azure Active Directory
|Azure Key Vault
||For performing data plane operations inside the Azure Key Vault
Here is an actual OAUTH request I made using the Key Vault resource URI (with some values removed):
POST https://login.microsoftonline.com/<tenant removed>/oauth2/token HTTP/1.1
HTTP/1.1 200 OK
Cache-Control: no-cache, no-store
Content-Type: application/json; charset=utf-8
Strict-Transport-Security: max-age=31536000; includeSubDomains
P3P: CP="DSP CUR OTPi IND OTRi ONL FIN"
Set-Cookie: fpc=AXuxcQCE2KRImJ4RCkjegB_EqXEQAQDjhy1f3lbWCA; expires=Sun, 30-Dec-2018 16:10:39 GMT; path=/; secure; HttpOnly
Set-Cookie: x-ms-gateway-slice=013; path=/; secure; HttpOnly
Set-Cookie: stsservicecookie=ests; path=/; secure; HttpOnly
Date: Fri, 30 Nov 2018 16:10:39 GMT
You can also see this value in the access token when it's decoded:
It's important to note that the resource value does not have a trailing slash! There are other resource URIs that work fine either with or without the trailing slash, but the Key Vault resource URI does not work with it.
Why are there two Resource URIs for Key Vault?
It's because Key Vault has two different sets of resources which it uses: the Management Plane and the Data Plane.
The Management plane is the set of operations which are performed on the Key Vault itself, such as:
- Creating/changing access policies
- Creating a new Key Vault
- Adding IP restrictions/VNet
- Setting Tags
- Access Control
Access to ARM APIs for Key Vault are set by RBAC.
The Data plane is the set of operations which allows others to retrieve/set the values of objects contained inside the Key Vault:
- Storage Objects
These objects are governed by the Access Policies, and therefore require a different set of APIs than the Management APIs.
I hope this clears up any confusion about making calls to the Key Vault using REST.
I hope this helps you out when using the Azure Key Vault! Please follow us on Twitter and tweet about it!