Purpose
This guide explains how to connect Microsoft Graph Security API to Logsign as a Response integration, so an analyst can look up and triage Microsoft Graph security alerts, and look up Microsoft Entra ID (Azure AD) user records, directly from a Logsign Incident. This is a query/action integration, not a log collection poller: it does not pull alerts into Logsign on a schedule. It only runs when an analyst calls one of its methods from Settings > Integrations > Responses > +Device.
Do not confuse this with the separate Azure Graph Security data collection (poller) integration, which ingests alerts as Logsign events on a schedule and is configured under Settings > Integrations > Data Collection. The two use the same underlying Microsoft Graph Security alert data, but they are configured in different places, use different credentials entries, and this Response integration additionally exposes Microsoft Entra ID user lookups that the poller does not.
Important, time-sensitive finding: the alert methods in this integration (list-alerts, get-alert, update-alert) all call Microsoft's legacy /security/alerts endpoint. According to Microsoft's own documentation, this legacy alerts API is deprecated and is scheduled to retire on August 31, 2026. After retirement, Microsoft has indicated the endpoint stops returning data rather than being removed outright, so calls may start failing or returning empty results without a code change on Logsign's side. One secondary industry source (a Microsoft admin-center message summary, not the official reference page) cites a later date of October 15, 2026 for the same change; treat August 31, 2026, as published on Microsoft's live API reference, as the date to plan against, and verify the current status before then. This is a Microsoft-side platform change, not a Logsign bug, but it directly affects every customer using the alert methods of this integration. Migrating this integration to Microsoft's replacement /security/alerts_v2 and /security/incidents endpoints is a Logsign Engineering task and is out of scope for this document; it is flagged here so customers are not caught off guard.
Prerequisites
You need a Microsoft Entra ID (Azure AD) tenant and permission to register an application and grant admin consent to it (Cloud Application Administrator or Global Administrator, or an equivalent custom role; see Step 1). You also need to know which of the five methods below you actually plan to use, because the Graph application permissions differ between the alert methods and the user methods, and Microsoft's own guidance is to grant only what a specific method needs.
This integration authenticates entirely with the OAuth 2.0 client credentials grant (an application identity, not a signed-in user), against the global Microsoft cloud only. It does not support delegated (signed-in user) authentication, and it is hardcoded to call https://login.microsoftonline.com for the token and https://graph.microsoft.com/v1.0 for the API itself. If your organization operates in a Microsoft national cloud (US Government GCC High/DoD, or the China cloud operated by 21Vianet), this integration will not work: those clouds use different login and Graph endpoints entirely (for example login.microsoftonline.us and graph.microsoft.us for US Government), and this integration has no field to change them. This was confirmed by reading the integration's source code, not by testing against a national cloud tenant.
Step 1: Register an Azure AD application with least-privilege Graph permissions
Do not reuse an application that already holds broad Microsoft Graph permissions for something else. Register a dedicated application for this integration so its permission grant stays auditable and minimal.
- Sign in to the Azure Portal (or the Microsoft Entra admin center) with an account that can register applications. Registering the application itself does not require a tenant admin.
- Go to Microsoft Entra ID > App registrations > New registration. Give it a descriptive name, for example "Logsign Graph Security Response", leave the default single-tenant account type unless your organization specifically needs otherwise, and click Register.
- On the application's Overview page, copy and securely store the Application (client) ID and the Directory (tenant) ID. You will enter both in Logsign in Step 2.
- Go to Certificates & secrets > Client secrets > New client secret. Give it a description and an expiration period, then click Add. Copy the secret's Value immediately; Azure only displays it once. Set a calendar reminder before the expiration date, since an expired secret fails authentication with no advance warning from Logsign.
- Go to API permissions > Add a permission > Microsoft Graph > Application permissions, and add only the permissions for the methods you plan to use, from the table below. Application permissions (not delegated) are required because this integration authenticates as the app itself, with no signed-in user.
| If you plan to use | Add this Graph application permission | Notes |
|---|---|---|
| list-alerts, get-alert (read-only alert lookup) | SecurityEvents.Read.All |
Least privileged option for these two methods per Microsoft's own permissions table. Do not add SecurityEvents.ReadWrite.All unless you also need update-alert. |
| update-alert | SecurityEvents.ReadWrite.All |
Microsoft documents no lower-privileged application permission for writing to alerts. This permission also covers list-alerts/get-alert, so if you need update-alert you do not need to add SecurityEvents.Read.All separately. |
| list-users, get-user (user lookup) | User.Read.All |
Least privileged application permission that can enumerate arbitrary directory users (not just the calling identity). Do not grant User.ReadWrite.All or Directory.ReadWrite.All: this integration never writes to user objects, so a write-capable permission is unnecessary exposure. |
After adding the permissions, click Grant admin consent for <your tenant>. This step requires a Global Administrator, Privileged Role Administrator, or Cloud Application Administrator; a user without one of those roles can add the permission requests but cannot approve them. Application permissions are inert until admin consent is granted, so skipping this step is the most common reason this integration authenticates (gets a token) but then fails every actual API call with a 403.
Step 2: Configure the integration in Logsign
In Logsign, go to Settings > Integrations > Responses, search for Microsoft Graph Security API, click Configure, then +Device.
| Field | Required | Value / Notes |
|---|---|---|
| Tenant ID | Yes | The Directory (tenant) ID copied from the application's Overview page in Step 1, for example 72f988bf-86f1-41af-91ab-2d7cd011db47. The integration inserts this directly into the token request URL, https://login.microsoftonline.com/<Tenant ID>/oauth2/v2.0/token, so an incorrect value fails at the authentication step before any Graph call is attempted. |
| Client ID | Yes | The Application (client) ID from the same Overview page, for example 3fa1b2c4-.... Identifies which app registration is authenticating. |
| Client Secret | Yes | The client secret Value generated in Step 1 (not the Secret ID). Stored encrypted by Logsign. If it was regenerated or has expired, update this field with the new value; the integration has no way to detect an expiring secret in advance. |
There is no Base URL or Scope field on this integration, and that is intentional, not a missing field. Both values are fixed in the integration's code rather than left for you to fill in:
-
Base URL is always
https://graph.microsoft.com/v1.0, the Microsoft Graph global commercial cloud endpoint. There is no regional or per-tenant variation to configure for Microsoft Graph the way there is for some other cloud APIs; every commercial-cloud tenant is reached through this same host. The only situation where this matters is the national cloud limitation described under Prerequisites: because the host is hardcoded, tenants in US Government or China clouds cannot use this integration at all, regardless of what credentials they enter. -
Scope is always
https://graph.microsoft.com/.default. In the OAuth 2.0 client credentials flow,.defaultis not a single permission, it is a shorthand meaning "request a token for whatever application permissions have already been granted admin consent on this app registration." In practice this means the actual access your Logsign integration gets is entirely determined by which permissions you added and consented to in Step 1, not by anything you configure in Logsign. If a call fails with 403 Forbidden, the fix is almost always back in the Azure Portal (add the missing permission and grant consent again), not in this Scope value, because there is no Scope field to change.
For comparison, some other Microsoft Graph-based Response integrations in Logsign, such as Microsoft Entra ID Response Integration, do expose a visible Scope field where you paste in the same fixed value manually. This integration does not; the equivalent value is simply built into the code. Functionally the two approaches end up requesting the same kind of token, an application-only token scoped to whatever was admin-consented, this integration just does not surface that as an editable field.
Save the device, then use Test to confirm the integration can obtain an access token from login.microsoftonline.com with the credentials entered. Based on a review of the integration's code, the test call only exercises the token request; it does not call a real Graph endpoint such as /security/alerts or /users, so a successful test confirms your Tenant ID, Client ID and Client Secret are valid together, but does not confirm that the app has been granted (and consented to) the specific permission a given method needs. Run an actual method, for example list-alerts or list-users, after saving to confirm permissions end to end. This was not independently verified against a live Logsign UI for this guide.
Separately, the integration's underlying configuration structure includes an optional proxy URL field in the Go source code, but that field is not declared in the current asset manifest that drives the Logsign UI form. In practice this means there is currently no way to set an outbound proxy for this integration from the standard configuration screen, even though the code has a code path that would use one if it were populated. Flag this to Logsign support if your environment requires the integration to call Microsoft Graph through a proxy.
Available Methods
Every method below is invoked from within an Incident's Responses panel by selecting the configured Microsoft Graph Security API device and the method name.
list-alerts
Lists Microsoft Graph security alerts (aggregated across connected providers such as Microsoft Defender for Endpoint, Microsoft Defender for Cloud Apps, Microsoft Entra ID Protection and Microsoft Sentinel) via the legacy GET /security/alerts endpoint. Requires application permission SecurityEvents.Read.All (or SecurityEvents.ReadWrite.All, which also covers this). See the deprecation warning under Purpose: this endpoint retires August 31, 2026 per Microsoft's current documentation.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| filter | string | No | OData $filter expression, for example an equality check on a property. Microsoft documents specific $filter keywords per originating provider (for example "MCAS" for Microsoft Defender for Cloud Apps, "IPC" for Entra ID Protection); confirm the correct keyword for the provider you are filtering on in Microsoft's own reference before relying on it. |
| select | string | No | OData $select, a comma-separated list of alert properties to return instead of the default set, for example assignedTo,category,severity. |
| order_by | string | No | OData $orderby. |
| top | integer | No | OData $top. Microsoft caps this at 1000 alerts per the legacy alerts API documentation. Recommended to use on its own for the first page rather than combined with skip. |
| skip | integer | No | OData $skip, capped at 500 by Microsoft; combinations that exceed the cap return 400 Bad Request rather than an empty page. Prefer following the response's pagination link over manually incrementing skip, if your workflow supports it. |
| count | boolean | No | OData $count. |
get-alert
Retrieves a single alert by ID via GET /security/alerts/{alertId}. Requires application permission SecurityEvents.Read.All (or SecurityEvents.ReadWrite.All).
| Parameter | Type | Required | Notes |
|---|---|---|---|
| alert_id | string | Yes | The alert's unique ID, as returned by list-alerts. |
update-alert
Updates editable properties on an existing alert (assignment, status, feedback, closing it, tags, comments and vendor metadata) via PATCH /security/alerts/{alertId}. Requires application permission SecurityEvents.ReadWrite.All; Microsoft documents no lower-privileged option for this write operation.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| alert_id | string | Yes | The alert's unique ID. |
| status | string, enum unknown / newAlert / inProgress / resolved | No | Alert lifecycle status. |
| feedback | string, enum unknown / truePositive / falsePositive / benignPositive | No | Analyst triage feedback. |
| assigned_to | string | No | Name of the analyst the alert is assigned to. |
| closed_date_time | string (ISO 8601 date-time) | No | For example 2026-07-27T00:00:00Z. |
| comments | array of string, enum "Closed in IPC" / "Closed in MCAS" | No | Microsoft's API only accepts these two exact literal values in the comments array for this legacy endpoint; free-text comments are rejected. This matches Microsoft's own published documentation for this method. |
| tags | array of string | No | Free-text labels. |
| vendor_provider, vendor_provider_version, vendor_sub_provider, vendor_name | string | See note | Combined by the integration into the request's vendorInformation object. Microsoft's API documentation marks vendorInformation.provider and vendorInformation.vendor as required on every update, but Logsign's form does not enforce vendor_provider or vendor_name as mandatory fields. Based on a review of the integration's code, submitting an update with these left blank sends no vendorInformation object at all, which Microsoft's API is expected to reject. Always fill in vendor_provider and vendor_name when calling update-alert, even though the form will let you submit without them. Not independently verified against a live tenant for this guide. |
list-users
Lists Microsoft Entra ID user objects via GET /users. Requires application permission User.Read.All.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| search | string | No | OData $search. Microsoft Graph requires the request header ConsistencyLevel: eventual whenever $search (or certain $filter/$count combinations) is used against the /users endpoint's advanced query capabilities. Based on a review of the integration's code, it does not set this header on any request. If Microsoft enforces this requirement for your tenant, calls to list-users with the search parameter populated may fail with 400 Bad Request. Not independently verified against a live tenant for this guide; if you hit this, test list-users without the search parameter (using filter instead) as a workaround while this is confirmed with Logsign support. |
| filter | string | No | OData $filter, for example startswith(displayName,'A'). |
| select | string | No | OData $select, comma-separated property list. |
| count | boolean | No | OData $count. Same ConsistencyLevel caveat as search above may apply. |
get-user
Retrieves a single user by ID or userPrincipalName via GET /users/{id}. Requires application permission User.Read.All.
| Parameter | Type | Required | Notes |
|---|---|---|---|
| user_id_or_principal_name | string | Yes | Either the user's object ID (a GUID) or their userPrincipalName, for example jane.doe@contoso.com. |
Notes and Limits
- This is a query/action integration, not a log collector. It does not ingest Graph Security alerts or Entra ID user data into Logsign's event store on its own; each call returns data only for the specific request an analyst makes at that moment.
- The alert methods (list-alerts, get-alert, update-alert) use Microsoft's legacy alerts API, scheduled to retire August 31, 2026 per Microsoft's current documentation. Plan around this; it is a Microsoft-side platform retirement, not something fixable from the Logsign configuration screen.
- Throttling: Microsoft Graph enforces service-specific and tenant-level rate limits and returns HTTP 429 Too Many Requests with a
Retry-Afterheader (in seconds) when exceeded. Based on a review of the integration's code, it does not read or honor the Retry-After header and does not retry automatically; a throttled call simply returns as a failed response to Logsign. If you run a high volume of calls (for example, bulk alert lookups from a playbook loop), build a delay into the playbook itself rather than relying on this integration to back off automatically. Microsoft's exact numeric limits for the Security API and for /users are not published as fixed per-minute figures and can vary by tenant and licensing; this was not independently load-tested for this guide. - Authentication is entirely OAuth 2.0 client credentials against the Microsoft global commercial cloud. There is no support for delegated (signed-in user) auth, and no support for Microsoft national clouds (US Government, China), because both the token endpoint and the Graph base URL are hardcoded in the integration.
- The client secret has an expiration date you set in Azure. This integration has no mechanism to warn you before it expires; an expired secret fails every call with an authentication error until you generate a new secret in Azure and update the Client Secret field in Logsign.
- A proxy URL field exists in the integration's underlying configuration structure but is not exposed in the current asset manifest, so it cannot currently be set from the standard Logsign configuration screen. See Step 2.
Troubleshooting
| Symptom / Code | Likely Cause | What to Check |
|---|---|---|
| 401 Unauthorized (at Test / token step) | Wrong Tenant ID, Client ID, or Client Secret, or the client secret has expired. | Re-copy the Tenant ID and Client ID from the app registration's Overview page in Azure. Check Certificates & secrets for the secret's expiration date; generate a new secret if it has expired and update the Client Secret field. |
| 403 Forbidden (Test succeeds, but a method call fails) | The token was issued successfully, but the app registration was never granted (or never had admin consent granted for) the specific Graph permission that method needs. | In Azure, go to API permissions on the app registration and confirm the permission listed for that method in Step 1's table is present and shows "Granted" under the Status column, not just "Not granted". Click Grant admin consent again if it shows as requested but not granted. |
| 400 Bad Request on update-alert | Most likely, vendor_provider and vendor_name were left blank. Microsoft requires vendorInformation.provider and vendorInformation.vendor on every alert update, but Logsign's form does not mark them as required. | Re-submit the update with vendor_provider and vendor_name populated. See the update-alert notes above. |
| 400 Bad Request on list-users with search populated | Possibly a missing ConsistencyLevel: eventual header, which Microsoft Graph requires for $search on /users and which this integration's code does not appear to set. Not independently confirmed for this guide. | Retry the same lookup using the filter parameter instead of search. If that succeeds, the ConsistencyLevel header is the likely cause; report this to Logsign support. |
| 429 Too Many Requests | Microsoft Graph's rate limit was exceeded for your tenant or for the specific Security/Users service. | Reduce call frequency, especially inside playbook loops. This integration does not automatically retry or back off, so repeated bursts will keep failing until the rate limit window resets. |
| 404 Not Found on get-alert or update-alert | The alert ID does not exist, was already resolved and aged out on the provider's side, or (from August 31, 2026 onward) the legacy alerts API itself has been retired by Microsoft. | Re-run list-alerts to confirm the alert ID is still current. If this starts happening broadly after the retirement date above, treat it as the expected effect of Microsoft's platform change, not a Logsign configuration issue. |
| Empty alert list from list-alerts with no error | The app has read permission but no alerts match the current filter, or (per Microsoft's own documented behavior for this endpoint) one of the underlying provider integrations timed out and was silently dropped from the aggregated response. | Retry without a filter first to confirm alerts exist at all. Microsoft's API returns 206 Partial Content with a warning header, not a hard error, when one provider's alerts fail to load; this integration does not surface that warning separately. |
| get-user or list-users returns fewer fields than expected | Microsoft Graph's /users endpoint returns only a default subset of properties (businessPhones, displayName, givenName, id, jobTitle, mail, mobilePhone, officeLocation, preferredLanguage, surname, userPrincipalName) unless a $select is specified. |
Use the select parameter to explicitly request additional properties you need. |