Person API: Token Verification in Webhooks

To increase the security of Person API webhook consumers, we will begin testing token verification in webhook event publishing on Monday, October 2, 2023.

As you may already know, when you create webhooks (documentation for which can be found here), a token is included in the response. This token must be saved, as all events for that webhook will be published with this token as a header, X-Person-Api-Token (learn more about this here), which can be used to verify the legitimacy of received webhook events.

What will this entail?

In the past, we have not attempted to verify that webhook consumers verify this token, but this will soon be changing. The changes (also documented here) will be as follows: 

  • Each webhook event will have a 0.1% chance of being selected for token verification.
  • When a webhook event is selected for verification, one of three things will occur:
    • The X-Person-Api-Token header will be set to a randomly-generated token, whose format is not guaranteed to match that of currently issued tokens.
    • The X-Person-Api-Token header will be left blank (an empty string).
    • The X-Person-Api-Token header will be deleted.
  • Upon being sent, the response code will be checked:
    • If the event was not rejected (e.g. we received an HTTP 200 response), this will be logged and flagged, and we will notify you via email. The event will not be re-sent, as your application has indicated that it has already acted on it.
    • If the event was rejected (e.g. we received an HTTP 401 response), we will log that your application acted properly, and will immediately re-send the event with the correct token.

What does this mean for my application?

If your application does not use Person API webhooks, you have nothing to worry about.

If your application correctly implements token verification, you may notice webhook events being sent with incorrect tokens from time to time, but since we re-send events upon successful rejection, you do not have to worry about missing or losing data.

Even if you know your application checks the token header, now would be a good time to ensure it rejects invalid payloads before it has a chance to act on them, as it does not do much good to emit a 401 or other HTTP error codes if you have already processed and acted on the event, especially since our re-sending upon receiving a rejection could trigger undefined behavior if your application attempts to repeat what it has already done (e.g. deleting a record which has already been deleted).

If your application does not correctly implement token verification, you will need to start doing so. We recommend returning HTTP 401 Unauthorized when the X-Person-Api-Token header is invalid or not present.

Note that you do not need to scramble to update your applications to implement token verification: although we will begin tracking and notifying developers whose applications are not properly verifying tokens, we do not yet have a cut-off date or any criteria by which we will start revoking access for non-compliant applications. We recommend that you implement this sooner rather than later, but we will give appropriate notice before taking any such actions.

Why does token verification matter?

When you pull data from the Person API, you are contacting us, meaning that unless someone is spoofing DNS and has forged or stolen TLS certificates, you can rest assured that the data has not been tampered with.

With webhooks, on the other hand, you are waiting for other servers (namely us) to contact you. Depending on what network your application resides in, this may only be a few dozen hosts, or potentially billions of hosts who can all send data to your application, and it is up to your application to verify the legitimacy of the data it receives. With today’s threat landscape, it is no longer a matter of if your application is targeted, but when.

And with expansion to the greater UW System on the horizon, we are taking steps to increase security now rather than wait until we have many more Person API webhook consumers and a greatly increased attack surface.

The X-Person-Api-Token header allows your application to easily verify the legitimacy of received data, even for applications exposed directly to the internet, because it is a secret value.

How strict is verification for applications using multiple webhooks?

Because each webhook is given a unique token, we retrieve the correct token for that webhook when preparing each event. You will be expected to verify that the token received matches that of the specific webhook it originated from.

If you merely check that a token matches one which has been issued for any of your webhooks (i.e. if you have 10 webhooks, making sure the received token is in that list of 10 tokens), you may validate the token against the wrong webhook, which would be flagged as having not been verified at all on our end. The chances of such a collision are extremely low, but we mention it because it is theoretically possible.

I never saved the tokens; how do I retrieve them?

Since we do not have the ability to easily retrieve arbitrary tokens outside the Person API, you are better off deleting (documentation for which can be found here) and re-creating your webhooks, taking care to properly store the tokens this time.

I have other questions or concerns, who do I contact?

Feel free to contact us at api@doit.wisc.edu.

Luna Lucadou – API Software Engineer

Division of Information Technology