Unable to create a TrustFrameworkKeySet and TrustFrameworkKey at the same time
Describe the bug
I am trying to create a TrustFrameworkKeySet and TrustFrameworkKey at the same time using Microsoft.Identity.Web.GraphServiceClientBeta version 3.0.1 which is using Microsoft.Graph.Beta 5.78.0-preview. I get the following error:
The 'keySet' field is invalid in request. Please check the request body and parameters.
Expected behavior
To create a TrustFrameworkKey while creating a TrustFrameworkKeySet using the follow guide trustframework-post-keysets.
How to reproduce
Where: secret - the key to add name - name of the key to create graphServiceClient - Microsoft.Graph.Beta.GraphServiceClient
TrustFrameworkKeySetCollectionResponse? keySets = await graphServiceClient.TrustFramework.KeySets.GetAsync(cancellationToken: cancellationToken);
TrustFrameworkKeySet? trustFrameworkKeySet = keySets?.Value?.FirstOrDefault(x => x.Id == name);
if (trustFrameworkKeySet == null)
{
trustFrameworkKeySet = new()
{
Id = name,
Keys =
[
new TrustFrameworkKey()
{
Use = "sig",
K = secret,
Kty = "oct"
}
]
};
trustFrameworkKeySet = await graphServiceClient.TrustFramework.KeySets.PostAsync(trustFrameworkKeySet, cancellationToken: cancellationToken);
}
SDK Version
5.78.0-preview
Latest version known to work for scenario above?
No response
Known Workarounds
I am able to create the TrustFrameworkKeySet then Upload a secret separately but it always creates a .bak key.
Debug output
Click to expand log
```</details>
### Configuration
_No response_
### Other information
_No response_
Hello, did you even find a resolution for your problem? We are recently experiencing the same issue on both 5.86.0-preview and 5.103.0-preview.
Thanks.
The behavior between adding a TrustFrameworkKey within the TrustFrameworkKeySet and adding a key separately in the UploadSecretPostRequestBody. If you want to add a policy key within the creation of the key set, you need to Base64 encode your secret. Apparently the Graph SDK does this for you in the UploadSecretPostRequestBody request. I just tested this.
So if you want to create a keyset with a key, you should Base64UrlEncode your secret. Something like:
var encodedKey = Base64UrlEncode(secret);
var policyRequest = new Microsoft.Graph.Beta.Models.TrustFrameworkKeySet
{
Id = policyKeySetName,
Keys =
[
new Microsoft.Graph.Beta.Models.TrustFrameworkKey
{
K = encodedKey,
Use = useType.Value,
Exp = expiresOn.ToUnixTimeSeconds(),
Kty = "oct"
},
],
};
var result = await betaGraphServiceClient.TrustFramework.KeySets.PostAsync(policyRequest);
The url encode method:
private static string Base64UrlEncode(string input)
{
var bytes = Encoding.UTF8.GetBytes(input);
var base64 = Convert.ToBase64String(bytes);
return base64.Replace("+", "-").Replace("/", "_").TrimEnd('=');
}
When adding a key separately, no encoding is needed:
var requestBody = new UploadSecretPostRequestBody
{
Use = useType.Value,
K = secret,
Exp = expiresOn.ToUnixTimeSeconds()
};
var result = await betaGraphServiceClient.TrustFramework.KeySets[policyKeySetName].UploadSecret
.PostAsync(requestBody);
A bug in the SDK if you ask me. Too bad this stuff is still in Beta.
Hi @jeroenbeuz , thank you for your reply. Yes that seems to be the case indeed, I also eventually figured that out through this ticket I had created. We had already switched to using UploadSecretPostRequestBody by that time.
Too bad this stuff is still in Beta.
I don't think it will ever leave beta, since Microsoft has recently announced it would be deprecating Azure B2C altogether in 2030...