We have a legacy system which presents a REST API that has Basic Authentication / this API has so far only been accessible from within our private network.
We've been asked to make this API available publicly. However, our InfoSec team have a rule that Basic Auth is not sufficient (essentially for the reasons given here; though we're using >=TLS1.2 and it's a system-to-system API so there's no browser in the equation).
We use the Azure Application Gateway WAF when exposing any HTTP endpoints publicly; with this acting as both WAF and handling TLS offloading.
Normally we'd implement IP Whitelisting to improve the security; but in this case the requests are coming from HubSpot; so there's no published list of IPs, and even if there were, they could be hosting a significant number of other parties' code.
It's also possible to implement mTLS on the App Gateway, but so far as I can tell HubSpot doesn't support this.
HubSpot does seem to support its own approach - creating a hash from a client secret & various parts of the request; but the App Gateway can only compare static strings / doesn't have the ability to programmatically caclulate the hash to be compared.
We could
- implement that the HubSpot Hash logic on the legacy app; but that then impacts all using that API.
- implement the HubSpot Hash logic on the legacy app where the headers exist (so it only impacts HubSpot requests), and use the AppGateway to block any requests which don't have those headers (so anything public has to have the headers & thus gets authenticated this way, anything internal doesn't need the headers so gets authenticated via basic auth).
- Implement hubspot specific endpoints on the backend API and only present those HubSpot specific paths externally (with the HubSpot Hash logic applied on those endpoints).
- Implement an Azure Function which sits between the App Gateway and the legacy app's API, to handle the HubSpot Hash piece and only forward on authenticated requests.
There's probably many more options out there...
Has anyone else encountered something like this before / found a solution to handle it?
(Apologies if this is too opinion based; it felt like it's in the gray area where there may be a good standard solution that I've missed; but equally it may be one of those things with many possible options / no single best fit; please vote to close if you believe it's the latter).