2

I'm developing a console app that uploads a custom policy (that part is working) and the related policy key using the Graph API following this documentation https://learn.microsoft.com/en-us/graph/api/trustframework-post-keysets?view=graph-rest-beta&tabs=http#example-2-create-a-keyset-with-a-key

Request:

URL: https://graph.microsoft.com/beta/trustFramework/keySets
Headers: Content-Type = application/json, Authorization = Bearer eyJ0e...Mca9g
Payload: {
  "id":"Test3AADSecret",
  "keys":
  [
    {
      "use":"sig",
      "k":"A1B2C3D4E5F6G7H8I9J10K11L12M13N14O15P16Q17R18S19T20U21V22W23X24Y25Z26",
      "nbf":1644941414,
      "exp":4070908800
    }
  ]
}

The request works if I set the keys property to an empty array. However when I try to include a key in the keys property (as in the example above) I get 400 Bad Request status returned with this response payload

{
  "error":
  {
    "code":"AADB2C",
    "message":"The 'keySet' field is invalid in request. Please check the request body and parameters.",
    "innerError":
    {
      "correlationId":"ee3aa070-a5a7-4c52-96b7-f0a9471fba63",
      "date":"2022-02-15T16:27:36",
      "request-id":"ad5dba0f-595a-4f94-ade2-fec2357bcb55",
      "client-request-id":"ad5dba0f-595a-4f94-ade2-fec2357bcb55"
    }
  }
}

The only issues I can find on github relates to using the GraphServiceClient C# class (not the Graph API) to create a keyset with key and that issue has been closed (resolved) https://github.com/microsoftgraph/msgraph-beta-sdk-dotnet/issues/67

I've tried installing the latest version of Microsoft.Graph nuget package (4.18.0) but I can't follow the C# example from here https://learn.microsoft.com/en-us/graph/api/trustframework-post-keysets?view=graph-rest-beta&tabs=csharp#request because there's no TrustFrameworkKeySet class and the GraphServiceClient doesn't contain a definition for TrustFramework. I've tried searching nuget and google for other nuget packages to fill these gaps but I've found nothing.

Yes, I could just call the https://graph.microsoft.com/beta/trustFramework/keySets API with an empty keys array and then make a second call to https://graph.microsoft.com/beta/trustFramework/keySets/{id}/uploadSecret to add the key to the ketset. But when I do this I end up with two policy keys, one of which has a .bak extension to the name.

So I have many questions

  1. Am I doing something wrong when calling the Graph API with a key in the keys array
  2. Am I missing a nuget package for the GraphServiceClient C# class. If so, where can I find them?
  3. How can I prevent the second policy key from appearing (.bak file) when attempting to add the key in a separate API call after creating the empty keyset

Thanks in advance if you help me achieve at least one of these approaches.

Marlyn
  • 41
  • 3

1 Answers1

1

I made some experiments here. I'm using REST API through PowerShell.

One interesting behavior is the usage of keySets updating (PUT method). The object you try to update must somehow match the existing one.

Assume you have a signature with no valid before (nbf) and expiration, then the following payload works:

{
    "keys": [
        {
            "use": "sig",
            "k": "$key",
            "kty": "oct"
        }
    ]
}

However, if one adds the exp and nbf fields like so it fails:

{
    "keys": [
        {
            "use": "sig",
            "k": "$key",
            "kty": "oct",
            "nbf": $now,
            "exp": $exp
        }
    ]
}

If these fields exists, you must provide values. It fails with the common message

400 Bad Request {"error":{"code":"AADB2C","message":"The 'keySet' field is invalid in request. Please check the request body and parameters."

In general, the API works but is very restrictive. It's a very good idea to go to the portal and check the manifest files.

Identity Experience Framework | Policy Keys | {your policy} | {click on name}

{
    "metadata": {
        "updatedUtc": "8/1/2022 4:07:42 PM",
        "tenantID": "your-tenant.onmicrosoft.com",
        "storageKeyId": "B2C_1A_Keyname"
    },
    "keys": [
        {
            "kid": "Q1fDF-jMoHeyr7gciaaWgXe3eVkjYdx8BLZoG3J_f1E",
            "use": "sig",
            "key_ops": [
                "sign"
            ],
            "kty": "oct"
        }
    ]
}

Mostly the keys array shown is a valid body for the API call (while I found that you can strip the key_ops field). If you start just create few key variations by hand and try out to deal with these.

Joerg Krause
  • 1,759
  • 1
  • 16
  • 27