Forward Capsule Security alerts into Microsoft Sentinel so your SOC can triage AI agent and shadow-AI signals alongside the rest of your security telemetry.
Capsule sends policy-violation alerts into your Microsoft Sentinel workspace via the Azure Monitor Logs Ingestion API, writing each alert as a row in a custom Log Analytics table (CapsuleAlert_CL) on your Sentinel-enabled workspace. From there, your existing Sentinel analytics rules and incident workflows can act on Capsule alerts.
Capsule authenticates as an approved Microsoft Entra ID application using the client-credentials flow. The application is granted a single, narrowly scoped Azure role on the data collection rule - it cannot read your workspace, query data, or access anything else in your tenant.
Capsule policy violation
→ Capsule sends to your Data Collection Endpoint
→ Data Collection Rule routes the record
→ CapsuleAlert_CL table in your Log Analytics workspace
→ Microsoft Sentinel analytics rules / incidentsThere are two ways to set this up. First authorize the Capsule application, then pick one:
- Option 1: Quick Setup (recommended) - deploy every Azure resource with a single ARM template, then paste the outputs into Capsule.
- Option 2: Manual setup - create each resource yourself, step by step.
Before you begin, ensure you have:
- Microsoft Sentinel enabled on a Log Analytics workspace
- Azure permissions to create a Data Collection Endpoint, a Data Collection Rule, and a custom table - typically Monitoring Contributor (or Contributor) on the resource group
- The ability to assign Azure RBAC roles on the data collection rule - User Access Administrator or Owner
- A Microsoft Entra ID account with Application Administrator or Global Administrator role (to grant admin consent to the Capsule application)
- A Capsule Security account with admin access
Do this first. Both Quick Setup and the manual flow assign a role to the Capsule application's service principal, so that principal must already exist in your tenant. Authorizing the app creates its service principal; Capsule then needs the principal's Object ID to scope the publishing role.
In Capsule, go to Settings → Notifications, open the Microsoft Sentinel connection dialog, and click Provision Capsule application. You'll be redirected to Microsoft to approve an admin-consent prompt - sign in as Application Administrator or Global Administrator and click Accept. Capsule materializes the service principal and captures its Object ID for you, then shows it in the dialog. You no longer copy any GUID by hand: the captured Object ID is the principalId Quick Setup asks for (and the principal the manual role assignment targets).
If you're not an Entra admin, or you've already authorized the Capsule app in this tenant (for example via the manual flow below on a previous install), check Skip - already authorized in the dialog to proceed without re-running consent. Then provide the existing service principal Object ID where the template or manual steps ask for it (read it with the
az ad sp showcommand below).
Use this only when you can't complete the portal flow (no portal access yet, or you prefer the CLI). The Capsule Sentinel application requests no Microsoft Graph permissions beyond the read access needed to look up its own service principal, so consent simply materializes the principal. Ask your Capsule contact for the Capsule application (client) ID first.
Option A - Admin-consent link (browser). Open the following URL, replacing {TENANT_ID} with your Microsoft Entra tenant ID (Entra ID → Overview → Tenant ID) and {CAPSULE_APP_ID} with the application ID from Capsule. Sign in as Application Administrator or Global Administrator and click Accept:
https://login.microsoftonline.com/{TENANT_ID}/adminconsent?client_id={CAPSULE_APP_ID}Option B - Azure CLI.
# Create the Capsule application's service principal in this tenant
az ad sp create --id {CAPSULE_APP_ID}If the service principal already exists you'll see an "already exists" error - that's harmless, continue.
Read the service principal Object ID (the principalId Quick Setup asks for, and the principal the manual role assignment targets):
az ad sp show --id {CAPSULE_APP_ID} \
--query "{appId:appId, objectId:id, displayName:displayName}" -o jsoncThe objectId field is the value you supply as principalId.
Use the
objectId, not theappId. These are different GUIDs. The role assignment targets the service principal's Object ID (objectId) - the application (client) ID (appId) is not interchangeable. Supplying the wrong GUID asprincipalIdstill deploys successfully, but Capsule then fails to publish with a runtime403because the role was granted to the wrong (or a non-existent) principal. To find the Object ID in the portal instead: Entra ID → Enterprise applications, select the Capsule app, and copy Object ID (not Application ID) from its Overview. (When you provision from the Capsule portal above, this value is captured for you.)
Instead of creating each resource by hand, deploy everything with a single one-click ARM template. It provisions a Data Collection Endpoint, a Data Collection Rule, the CapsuleAlert_CL custom table on your existing workspace, and the least-privilege Monitoring Metrics Publisher role assignment scoped to the rule - all in a new capsule-sentinel-rg resource group.
Authorize the Capsule application first - the template assigns a role to the Capsule service principal, so the principal must already exist or the deployment fails with
PrincipalNotFound.
You provide two values:
Workspace resource ID - the full ARM resource ID of your existing Sentinel-enabled Log Analytics workspace, in the form
/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<name>. To find it in the Azure portal: open Log Analytics workspaces, select your workspace, then in its left menu go to Settings → Properties and copy the Resource ID field. From the CLI:az monitor log-analytics workspace show -g <rg> -n <name> --query id -o tsv.Not the "Workspace ID". The workspace Overview page shows a Workspace ID that is a bare GUID (e.g.
xxxxxxxx-xxxx-...) - that is not what this field needs. Use the full slash-delimited Resource ID from the Properties page. Pasting the GUID fails deployment validation withThe template variable 'workspaceSubId' is not valid… index '2' is out of bounds.Capsule service principal Object ID - the
objectIdfrom Authorize the Capsule application. Use the service principal's Object ID, not the application (client) ID - a wrong-but-valid GUID deploys cleanly and only surfaces later as a runtime403.
On the custom-deployment pane:
- Subscription - select the subscription where the new
capsule-sentinel-rgresource group will be created (typically the one containing your workspace). - Region - choose the region for the resource group, Data Collection Endpoint, and Rule (commonly your workspace's region).
- Principal Id - paste the service principal Object ID.
- Workspace Resource Id - paste your workspace's full ARM resource ID.
- Leave Resource Group Name, Dce Name, and Dcr Name at their defaults unless you have a naming convention.
- Click Review + create, then Create. Deployment takes one to two minutes.
az deployment sub create \
--name capsule-sentinel-integration \
--location <your-region> \
--template-uri "https://capsule-security-us-east-1-public-demo.s3.us-east-1.amazonaws.com/microsoft-sentinel/capsule-sentinel-integration.json" \
--parameters principalId="<service-principal-object-id>" \
workspaceResourceId="/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.OperationalInsights/workspaces/<name>"Read the four connection values straight from the deployment outputs (this --name matches the CLI deploy above; a browser deploy is named Microsoft.Template-<timestamp> instead - see below):
az deployment sub show --name capsule-sentinel-integration \
--query "properties.outputs.{azureTenantId:azureTenantId.value, dceUri:dceUri.value, dcrImmutableId:dcrImmutableId.value, streamName:streamName.value}" -o jsoncThe four connection values are exposed as deployment outputs once the deployment succeeds (a failed deployment produces none).
Browser deploy: on the deployment-complete page, select Outputs in the left menu. (If you've navigated away: the template deploys at subscription scope, so the outputs live on the subscription deployment - open Subscriptions → your subscription → Settings → Deployments, find the deployment named
Microsoft.Template-<timestamp>, then Outputs. They are not under thecapsule-sentinel-rgresource group's Deployments blade, which only lists the nested module deployments.) Note that the portal names the deploymentMicrosoft.Template-<timestamp>, notcapsule-sentinel-integration- so the CLIshow --name capsule-sentinel-integrationabove only works if you deployed with the CLI. To read a browser deploy's outputs from the CLI, list the deployments first and use the actual name:az deployment sub list --query "reverse(sort_by([?contains(name,'Template')], &properties.timestamp))[0].name" -o tsvCLI deploy: use the
az deployment sub showcommand above.
In Capsule, go to Settings → Notifications, find Microsoft Sentinel, click Set up, and copy in the four values:
| Capsule field | Deployment output |
|---|---|
| Directory (tenant) ID | azureTenantId |
| Data Collection Endpoint URI | dceUri |
| DCR immutable ID | dcrImmutableId |
| Stream name | streamName |
Then click Test Connection and link your policies, as described in Configure the integration in Capsule. You're done - skip Option 2.
Create each Azure resource yourself instead of using the Quick Setup template. Authorize the Capsule application first - it's required either way.
In your Sentinel-enabled Log Analytics workspace, create a custom table named CapsuleAlert_CL with the schema below. The Logs Ingestion API requires a TimeGenerated column of type datetime.
| Column | Type | Description |
|---|---|---|
TimeGenerated | datetime | When the violation occurred |
Title | string | Alert title |
Description | string | Alert detail |
Severity | string | Informational, Low, Medium, or High |
PolicyName | string | The Capsule policy that triggered the alert |
EntityName | string | The affected agent or resource |
SourceUrl | string | Deep link back into the Capsule portal |
CapsuleTenantId | string | Your Capsule tenant identifier |
PolicyId | string | Capsule policy identifier |
EntityId | string | Capsule entity identifier |
IssueId | string | Capsule issue identifier |
AdditionalContext | dynamic | Remaining alert metadata as JSON |
Create a Data Collection Endpoint (DCE) in the same region as your workspace. After creation, record its Logs Ingestion URI - Capsule sends alerts to this address.
Create a Data Collection Rule (DCR) that validates incoming alerts and routes them to the custom table.
- Associate the DCR with the endpoint from step 2.
- Define an input stream for the schema from step 1. The stream must resolve to
Custom-CapsuleAlert_CL- when creating the DCR by hand, Azure prependsCustom-to the name you enter, so typeCapsuleAlert_CLand confirm the resulting stream isCustom-CapsuleAlert_CL(this is the value you enter as the Stream name in step 5). - Set the destination to your Log Analytics workspace, output table
CapsuleAlert_CL. - A pass-through transformation (
source) is sufficient unless you want to reshape rows.
After creation, record the DCR's immutable ID (for example, dcr-xxxxxxxxxxxxxxxx).
The Capsule application's service principal already exists from authorizing the Capsule application. Now grant it the single role it needs to publish alerts, scoped to the data collection rule from step 3:
| Role | Role definition ID | Scope |
|---|---|---|
| Monitoring Metrics Publisher | 3913510d-42f4-4e42-8a64-420c390055eb | The data collection rule (DCR) |
This is the only permission Capsule requires:
- No Microsoft Graph permissions are needed. Log ingestion uses the Azure Monitor data plane (
https://monitor.azure.com), not Microsoft Graph - so the application requests no mailbox, directory, or device permissions. - Scope the role to the DCR, not the subscription. Following least privilege, the Monitoring Metrics Publisher role only allows Capsule to publish records through that rule; it cannot read your workspace or query any data.
Assign the role via the Azure CLI:
az role assignment create \
--assignee "{CAPSULE_APP_ID}" \
--role "Monitoring Metrics Publisher" \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>"Use the DCR resource ID from step 3 as --scope. You can pass the role by ID instead with --role 3913510d-42f4-4e42-8a64-420c390055eb.
Here you pass the application (client) ID and the CLI resolves it to the service principal for you - unlike the Quick Setup template, which needs the resolved Object ID directly because ARM can't look it up.
Verify the assignment:
az role assignment list \
--assignee "{CAPSULE_APP_ID}" \
--scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>" \
--query "[].{role:roleDefinitionName, scope:scope}" -o jsoncYou should see exactly one Monitoring Metrics Publisher entry whose scope is the DCR (not the resource group or subscription).
Allow a few minutes for the role assignment to propagate before testing. If a later Test Connection or first alert returns 403, the assignment hasn't propagated yet or was scoped to the wrong resource - re-run the verify command above and confirm the scope is the DCR.
Quick Setup performs this assignment for you - you only need this step in the manual flow.
Log in to the Capsule Security portal.
Go to Settings → Notifications.
Find Microsoft Sentinel and click Set up.
Enter the connection values:
Field Where it comes from Directory (tenant) ID Your Microsoft Entra ID tenant ID (Entra ID → Overview) Data Collection Endpoint URI DCE Logs Ingestion URI (step 2) DCR immutable ID DCR immutable ID (step 3) Stream name Custom-CapsuleAlert_CL(step 3)Click Test Connection. Capsule now sends a single
[TEST]probe record through the real ingestion path - Azure access token → Data Collection Endpoint → Data Collection Rule → theCapsuleAlert_CLtable - rather than just checking credentials. A passing test therefore confirms, end to end, that the credentials and token, the DCE endpoint reachability, and the DCR's Monitoring Metrics Publisher role assignment are all working: a missing role now produces a failed test (e.g. a403) instead of a false success.One caveat - don't overclaim from a green check: the Logs Ingestion API returns
204the moment it accepts the batch, and the DCR transform then runs server-side, where any field the stream's schema doesn't declare is dropped silently. A passing test proves delivery and authorization, but does not guarantee every column lands in the table. Confirm the row actually arrived with the KQL query in After Setup: Verify Data Flow. The[TEST]probe row is harmless - leave it in place or delete it; it's filterable withCapsuleAlert_CL | where Title startswith "[TEST]".Link the Sentinel destination to the policies whose violations you want forwarded.
Once configured, Capsule forwards alerts for linked policies as they occur. To confirm alerts are actually landing in your workspace, open Logs on your Log Analytics workspace (or Microsoft Sentinel → Logs) and run:
CapsuleAlert_CL
| sort by TimeGenerated desc
| take 50You should see one row per forwarded alert, with columns such as Severity, Title, PolicyName, EntityName, and CapsuleTenantId.
If the query returns no rows, confirm whether the table is empty or missing:
CapsuleAlert_CL | countA result of 0 means the table exists but no alerts have arrived yet. An error such as "failed to resolve table" means the table was never created - revisit the custom-table step (or re-run the Quick Setup template).
If you expect older alerts, widen the time range past the query window's default:
CapsuleAlert_CL
| where TimeGenerated > ago(7d)
| project TimeGenerated, Severity, Title, PolicyName, EntityName, CapsuleTenantId
| sort by TimeGenerated descSteady-state ingestion latency is low - Azure quotes under 10 seconds on average once data reaches the endpoint. The first alert to a brand-new table can take noticeably longer: Azure provisions a dedicated storage container the first time a custom data type appears, a one-time overhead. So if Test Connection succeeded but the table is empty right after setup, confirm an alert has fired for a linked policy, then wait a few minutes and re-run the query before troubleshooting.
From here, build Sentinel analytics rules on CapsuleAlert_CL to raise incidents from Capsule alerts.
403 Forbiddenwhen sending alertsThe Monitoring Metrics Publisher role is not assigned to the Capsule service principal on this DCR, or the assignment hasn't propagated yet (allow a few minutes).
Most common cause: the role was granted to the wrong principal. If you deployed with an incorrect
principalId(e.g. the application/client ID instead of the service principal Object ID), the deployment succeeds but the grant targets the wrong identity. List the assignments actually on the DCR and confirm one matches theobjectIdfrom Authorize the Capsule application:az role assignment list \ --scope "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Insights/dataCollectionRules/<dcr-name>" \ --query "[?roleDefinitionName=='Monitoring Metrics Publisher'].{principalId:principalId, principalType:principalType}" -o tableIf the listed
principalIdisn't the Capsule service principal's Object ID, re-deploy the Quick Setup template with the correctprincipalId(re-running is safe and idempotent) or add the grant manually with the step 4 command.
404 Not Foundwhen sending alerts- The DCR immutable ID or stream name is incorrect, or the DCR isn't associated with the data collection endpoint.
401 Unauthorized- Confirm the Capsule application was authorized (see Authorize the Capsule application) so its service principal exists in your tenant.
Test passes, but no rows appear in
CapsuleAlert_CL- On a brand-new table, allow a few minutes for the one-time first-appearance provisioning (see After Setup: Verify Data Flow) and confirm an alert has actually fired for a linked policy.
- If rows still never arrive, the stream schema doesn't match the table columns, or the DCR transformation is dropping rows. Review the DCR transform and the table schema from the custom-table step.
For help with this integration:
- Email: support@capsule.security
- Include: Your organization ID, Entra tenant ID, Log Analytics workspace ID, and any error messages