- 10 minutes to read

Protect the Nodinite Log API with OAuth 2.0 and Entra ID

By default, the Nodinite Log API accepts Log Events from any client that can reach it. When Nodinite runs in OpenID Connect / OAuth 2.0 mode, you can require a bearer access token on every Log Event. This guide shows how to:

  1. Register the Log API in Microsoft Entra ID.
  2. Register a client for each system that sends Log Events.
  3. Turn on authentication in the Nodinite Portal.
  4. Get a token and send Log Events.
  5. Harden (recommended for production): allow only approved clients to send Log Events.

Note

This guide continues Register Nodinite Applications in Azure AD (Entra ID) with OpenID. Complete that guide first. Nodinite must already run in OpenID mode, with the webApi, webClient, and NodiniteInstallationClient app registrations in place.

Understanding the Protected Log API

sequenceDiagram participant C as Logging client participant IDP as Microsoft Entra ID participant L as Nodinite Log API C->>IDP: 1. Request token for the Log API (client ID + secret) IDP-->>C: 2. Access token C->>L: 3. POST Log Event + Authorization: Bearer token L-->>C: 4. Log receipt

The logging client gets a token for the Log API from Entra ID with the client credentials flow, and sends it with every Log Event.

Key Components

App registration Purpose
logApi Represents the Nodinite Log API. Clients request their tokens for it.
Logging client (one per sending system) The identity of a system that sends Log Events, such as an integration, a custom logger, a script, or the Pickup Service.

Important

Who can send Log Events with the basic setup: the Log API accepts any valid token issued for it, and Entra ID issues a Log API token to any application registered in your tenant. The client needs no permission for it. So after Steps 1–4, any app registration in your tenant can send Log Events. Before, anyone who could reach the Log API could. To allow only clients you approve, also complete Step 5: Harden. We recommend it for every production environment.

Basic vs Hardened Setup

Steps 1–4 only Steps 1–5 (hardened)
Who can send Log Events Any app registration in your tenant Only clients assigned AppRole_LogApi_write
Extra work per new client None Add the permission and grant admin consent (Step 5.2)
A client that is not approved Gets a token, and its Log Events are accepted Gets no token (AADSTS501051)

Prerequisites

  • Nodinite v7 runs in OpenID mode with Entra ID, and users can sign in to the Web Client.
  • You can create app registrations in Entra ID.
  • You can sign in to the Nodinite Portal and edit the environment's OpenID settings.
  • You have a list of every system that sends Log Events to this Log API.

Warning

Once authentication is on, every client that sends Log Events must send a valid bearer token. A client without one gets 401 Unauthorized, and its Log Events are lost. Before you turn authentication on in Step 3, check that every logging client in your list can get and send a token.

Step 1: Register the Log API (logApi)

1.1 Create the App Registration

  1. In the Microsoft Entra admin center, go to Entra ID > App registrations > + New registration.
  2. Name: logApi, or your own convention, for example nodinite-prod-logapi.
  3. Supported account types: Accounts in this organizational directory only.
  4. Redirect URI: leave it empty.
  5. Select Register.
  6. Note the Application (client) ID. You enter it in the Nodinite Portal in Step 3.

Overview of the logApi app registration in Entra ID
You register the logApi application. It needs no secret or redirect URI, because it only represents the API.

1.2 Expose the API

  1. Open Expose an API.

  2. Next to Application ID URI, select Add.

    Expose an API page with the Add link for the Application ID URI
    Select Add next to Application ID URI.

  3. Accept the default api://<logApi-client-id>, then select Save.

    Edit application ID URI panel with the default api:// value
    You set the Application ID URI for the logApi application.

1.3 Set the Access Token Version to 2

  1. Open Manifest.
  2. Set requestedAccessTokenVersion to 2 (in older manifest views, accessTokenAcceptedVersion).
  3. Select Save.

logApi manifest with requestedAccessTokenVersion set to 2
You set requestedAccessTokenVersion to 2 in the logApi manifest.

Warning

Don't skip this step. By default, Entra ID issues version 1 tokens, which have the issuer https://sts.windows.net/<tenant>/. Nodinite expects the version 2 issuer https://login.microsoftonline.com/<tenant>/v2.0, so it rejects every version 1 token with 401 Unauthorized.

The logApi application is ready.

Step 2: Register a Logging Client

Create one client app registration per system that sends Log Events. You can then audit and revoke each system on its own.

  1. Go to Entra ID > App registrations > + New registration.
  2. Name: a name that identifies the system, for example logApi-client-orders-integration.
  3. Supported account types: Accounts in this organizational directory only.
  4. Redirect URI: leave it empty.
  5. Select Register and note the Application (client) ID.
  6. Open Certificates & secrets. Upload a certificate (recommended), or select + New client secret.
  7. If you create a secret, copy the Value immediately, because it is shown only once. Store it in a secret store, for example Azure Key Vault, and note the expiry date. When the secret expires, the client stops sending Log Events.

Certificates and secrets page of a logging client with one client secret
You create a client secret for the logging client.

Note

The basic setup needs no API permissions on the client. To require them, see Step 5: Harden.

The logging client is registered.

Step 3: Enable Authentication in the Nodinite Portal

  1. In the Nodinite Portal, open the environment's OpenID settings and scroll to the Log API section.
  2. Under Audiences, enter the Application (client) ID of the logApi app registration (Step 1.1), then select Add.
  3. Check Enable Authentication.
  4. Save the settings and deploy the change to the environment.

Portal OAuth Log API settings with Enable Authentication and Audiences
You add the logApi audience and enable authentication for the Log API. See OAuth Log API settings.

Important

Enter the plain Application (client) ID, for example 757be812-1f79-4923-9103-16028f6e808a. Don't enter the api://… URI. A version 2 token (Step 1.3) carries the client ID as its audience (aud).

Warning

From now on, the Log API rejects Log Events without a valid token. Turn this on in a test environment first. Switch production over only after every logging client sends tokens.

The Log API now requires a bearer token.

Step 4: Get a Token and Send a Log Event

Placeholder Value
<tenant-id> Your Entra ID Directory (tenant) ID
<client-id> The logging client's Application (client) ID (Step 2)
<client-secret> The logging client's secret (Step 2)
<logapi-client-id> The logApi Application (client) ID (Step 1.1)
<logapi-base-url> The Log API base URL, for example https://nodinite.contoso.com:40002/LogAPI/. See Find the base URL.

The token request always uses the scope api://<logapi-client-id>/.default.

PowerShell

$body = @{
    grant_type    = 'client_credentials'
    client_id     = '<client-id>'
    client_secret = '<client-secret>'
    scope         = 'api://<logapi-client-id>/.default'
}
$token = (Invoke-RestMethod -Method Post `
    -Uri 'https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token' `
    -Body $body).access_token

$logEvent = Get-Content -Raw .\logevent.json   # a Nodinite JSON Log Event

Invoke-RestMethod -Method Post `
    -Uri '<logapi-base-url>api/LogEvent' `
    -Headers @{ Authorization = "Bearer $token" } `
    -ContentType 'application/json' `
    -Body $logEvent

curl

TOKEN=$(curl -s -X POST "https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token" \
  -d "grant_type=client_credentials" \
  -d "client_id=<client-id>" \
  --data-urlencode "client_secret=<client-secret>" \
  --data-urlencode "scope=api://<logapi-client-id>/.default" | jq -r .access_token)

curl -X POST "<logapi-base-url>api/LogEvent" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  --data @logevent.json

For a JSON formatted Log Event and samples in C#, Python, and Node.js, see Log using REST.

Pickup Service

On the Destination tab of each source configuration in the Pickup Service, check Protected and fill in:

Field Value
Client ID The logging client's Application (client) ID (Step 2)
Client Secret The logging client's secret (Step 2)
Scope api://<logapi-client-id>/.default
IDP Token Endpoint https://login.microsoftonline.com/<tenant-id>/oauth2/v2.0/token

Pickup Service Destination tab with Protected checked and the OAuth fields (7.x)
With Protected checked, the Pickup Service gets a token with the client credentials grant before it calls the Log API.

Endpoints

Endpoint Token required
POST /LogAPI/api/LogEvent Yes
POST /LogAPI/api/LogEvent/Batch Yes
POST /LogAPI/api/LogEvent/Validate Yes
POST /LogAPI/api/LogEvent/Batch/Validate Yes
GET /LogAPI/api/LogEvent/EndPointTypes, EndPointDirection, EventDirection No (reference data)
GET /isalive No (health check)

Tip

To test a token without storing anything, POST to /LogAPI/api/LogEvent/Validate. A 400 or 200 response means the token was accepted. A 401 means it was rejected. See Troubleshooting.

Tokens expire after about an hour. Request a new token before it expires, or when the Log API returns 401.

Step 5: Harden: Allow Only Approved Clients

With Steps 1–4, any app registration in your tenant can get a Log API token and send Log Events. That's acceptable in a test environment, but in production you usually want to decide exactly which systems can log.

This step adds an app role to logApi, assigns it to each approved client, and makes Entra ID refuse Log API tokens to every other application. The Log API itself doesn't change: Entra ID simply stops issuing tokens to clients you haven't approved.

5.1 Create an App Role on logApi

  1. Open the logApi app registration → App roles > + Create app role.
  2. Fill in the fields:
    • Display name: Log Writer
    • Allowed member types: Applications
    • Value: AppRole_LogApi_write
    • Description: Applications that send log events to the Nodinite Log API
  3. Select Apply.

Edit app role panel creating the Log Writer app role for applications
You create the AppRole_LogApi_write app role.

5.2 Assign the Role to Each Approved Client

  1. Open the logging client app registration → API permissions > + Add a permission > My APIs > logApi.

  2. Select Application permissions, check AppRole_LogApi_write, then select Add permissions.

    Request API permissions panel with the AppRole_LogApi_write application permission selected
    You add the AppRole_LogApi_write application permission to the logging client.

  3. Select Grant admin consent for <tenant>. The status changes from Not granted to Granted.

    API permissions list with Grant admin consent and the Not granted status
    Grant admin consent so the status changes to Granted.

Repeat this for every approved logging client.

5.3 Require Assignment

  1. Go to Entra ID > Enterprise apps > All applications and open logApi.
  2. Open Properties, set Assignment required? to Yes, then select Save.

logApi enterprise application properties with Assignment required set to Yes
You set Assignment required? to Yes on the logApi enterprise application.

From now on, Entra ID issues Log API tokens only to clients that have been assigned the role. Every other application gets the error AADSTS501051 when it requests a token. See Microsoft: Controlling tokens without the roles claim.

Warning

Complete 5.2 for every logging client before you complete 5.3. Once assignment is required, a client without the role can't get a token and stops sending Log Events.

Only approved clients can send Log Events.

Troubleshooting

Symptom Likely cause Fix
Log API returns 401, and the token's iss is https://sts.windows.net/… logApi still issues version 1 tokens Step 1.3: set requestedAccessTokenVersion to 2, then request a new token.
Log API returns 401, and the token's aud is not the logApi client ID Wrong scope, or the Audiences value is wrong Request the token with api://<logapi-client-id>/.default. In the Portal, Audiences must contain the plain logApi client ID (Step 3).
Log API returns 401 for a client that worked before Authentication was turned on and the client sends no token Update the client to send a bearer token, see Step 4.
Token request fails: AADSTS501051 Assignment required is on and the client has no role (Step 5) Step 5.2: add and grant AppRole_LogApi_write for the client.
Token request fails: AADSTS7000215 Wrong client secret Use the secret Value, not the secret ID.
Token request fails: AADSTS7000222 The client secret has expired Create a new secret and update the client.

Tip

To see what a token contains, paste it into jwt.ms, which decodes it in your browser. Check iss, aud, and exp.

What You've Accomplished

  • logApi registered: the Log API has its own identity in Entra ID and issues version 2 tokens.
  • Log API protected: the Log API rejects Log Events without a valid token.
  • One client per system: each sending system has its own credential that you can audit and revoke.
  • Hardened (Step 5): Entra ID issues Log API tokens only to clients you approved.

Next Steps