Azure APIM in Data Engine
Azure API Management service is used in Data Engine to expose 2 kinds of APIs:
- APIs exposed towards EnCo:
- API Nb-IoT Inbound
- inbound Nb-IoT data
- API Enco
- Nb-Iot resource info
- billing information
- API Nb-IoT Inbound
- APIs exposed towards Customers:
- API Resources
- get product containers
- get last reading of the device
- full message
- particular field of the message
- API Resources

Each API is defined in a separate Swagger file, the APIs exposed from Backend service have autogenerated on every build Swagger file - ensuring it's always up to date. In Backend service itself there are 2 Controllers consisting of Enco Controller and Resources Controller.
Each of those files is being copied to Pulumi directory during Pulumi pipeline execution, if there was any change, it will be populated on the Pulumi deployment.
API Nb-IoT Inbound swagger is a file that can be found in the same Pulumi directory data/apim/.
OAuth2.0 flow

For each environment there's a separate Application registered in EntraID, which credentials are used to obtain the access token, the Applications are named: pxs-iotde-enco-oauth-<sbx|dev|uat|prd>
Implementation on Backend side
Backend Service has JWT Strategy and Decorators implemented.
To secure full Controller or single Endpoint, you just need to put the annotation on top:
@Get('/resources/nbiot')
@UseGuards(JwtAuthGuard)
@Audience(<expected aud claim in JWT>)
async getNbiotResources() {}
How to get the access token
Call the v2.0/token endpoint of Entra ID on Proximus tenant
curl --location 'https://login.microsoftonline.com/e7ab81b2-1e84-4bf7-9dcb-b6fec01ed138/oauth2/v2.0/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=<application client id> \
--data-urlencode 'client_secret=<application secret>' \
--data-urlencode 'grant_type=client_credentials' \
--data-urlencode 'scope=api://<application client id>/.default'
Products
Once the JWT is valid (for APIs OAuth2.0 secured), the Ocp-Apim-Subscription-Key header has to have a correct value. Each API consumer (Organization) has their own header value. This value can be fetched on Organization page in Data Engine website under the tab API subscription.
Each API subscription can have assigned a Product, then each of the APIs can have assigned a Product too. Currently the Enco exposed APIs (API Nb-IoT Inbound & API Enco) have assigned Product Enco and customer exposed API (API Resources) has assigned Product resources. This configuration ensures that a customer with Ocp-Apim-Subscription-Key can only call API Resources.