Microsoft Sentinel
Bring Microsoft Sentinel detections into RegScale. The integration turns Sentinel incidents and alerts into RegScale issues, turns the machines and cloud resources they reference into RegScale assets, files forensic artifacts as evidence, and documents how your Sentinel workspace is configured so auditors can see what you are monitoring for, not only what was found.
Contents
- What the integration does
- How it works
- Prerequisites
- Azure permissions
- Configuration
- Authentication
- Azure Government and sovereign clouds
- Multiple workspaces
- TLS and corporate proxies
- Quick start
- Command reference
- Incremental sync
- How Sentinel data maps to RegScale
- Writing status back to Sentinel
- Documenting workspace configuration
- Scheduling
- Exit codes
- Security and data handling
- Troubleshooting
What the integration does
| Capability | Command | Reads / writes Azure |
|---|---|---|
| Verify configuration and connectivity | test_connection | Read |
| Import assets referenced by incidents | sync_assets | Read |
| Import incidents as RegScale issues | sync_findings | Read |
| Import alerts (including alerts no incident groups) as issues | sync_alerts | Read |
| Import assets referenced by alerts | sync_alert_assets | Read |
| Run ad-hoc KQL against the workspace | query | Read |
| Document rules, connectors, watchlists, threat intelligence | sync_content | Read |
| Close Sentinel incidents when the RegScale issue is resolved | sync_status | Write (opt-in) |
Every command except sync_status only reads from Azure. sync_status is the only
command that changes anything in Sentinel, and it does nothing until you turn it on
explicitly (see Writing status back to Sentinel).
The CLI talks to Azure directly through the official Azure SDK. No intermediary
service or third-party connector sits between your Sentinel workspace and RegScale.
How it works
Microsoft Sentinel workspace
│ incidents, alerts, entities (management API)
│ SecurityAlert / SentinelHealth tables (Log Analytics KQL)
▼
RegScale CLI ── normalizes each incident to an OCSF "Detection Finding" ──┐
│ │
├─► Issues one per incident (or per alert) │
├─► Assets hosts, IPs, Azure resources, accounts, apps │
├─► Evidence files, hashes, URLs, processes, malware │
└─► Data records rules, connectors, watchlists, threat intelligence │
▼
RegScale security plan (or other parent record)
Incidents are normalized to the Open Cybersecurity Schema Framework (OCSF)
Detection Finding class before they become RegScale records. You do not need to
know OCSF to use the integration; it is the reason the same RegScale mapping rules
apply consistently across every incident.
Two Azure endpoints are involved, and they are different services with different
token audiences:
- Management API (Azure Resource Manager): incidents, entities, rules,
connectors, watchlists, bookmarks, threat-intelligence indicators.
Addresses a workspace by subscription / resource group / name. - Log Analytics query API: raw tables such as
SecurityAlertand
SentinelHealth, and anything you query withquery.
Addresses a workspace by its GUID.
Incident sync needs only the first. Alert sync, query and connector-health
collection also need the second, which is why workspace_id is optional for some
commands and required for others.
Prerequisites
| # | Requirement | Needed for |
|---|---|---|
| 1 | Microsoft Sentinel enabled on a Log Analytics workspace | Everything |
| 2 | A credential that can read that workspace (service principal, or managed identity / Azure CLI login) | Everything |
| 3 | The Microsoft Sentinel Reader role on the workspace or its resource group | Read commands |
| 4 | The Microsoft Sentinel Responder role | sync_status only |
| 5 | The workspace's subscription id, resource group and name | Everything |
| 6 | The workspace GUID ("Workspace ID") | sync_alerts, sync_alert_assets, query, connector health |
| 7 | A RegScale security plan (or other parent record) id | All sync_* commands |
| 8 | azure-monitor-query Python package | Alert sync, query, connector health |
The Azure SDK packages for the management API (azure-mgmt-securityinsight,
azure-identity) ship with the CLI. If you run from a stripped-down environment
and see an "Azure SDK" error, install them:
pip install azure-mgmt-securityinsight azure-identity
Log Analytics queries use a separate SDK:
pip install azure-monitor-query
Optionally install azure-mgmt-loganalytics and the CLI will look the workspace
GUID up for you from the workspace name, so you do not have to set workspace_id
by hand. It is also what lets sync_content collect hunting queries.
Finding your workspace coordinates
In the Azure portal open Microsoft Sentinel → your workspace. The Overview
shows the subscription, resource group, workspace name and Workspace ID (the
GUID). From the Azure CLI:
az monitor log-analytics workspace list \
--query "[].{name:name, resourceGroup:resourceGroup, id:id, customerId:customerId}" -o table
customerId is the value for workspace_id.
Azure permissions
| Role | Scope | Lets the integration |
|---|---|---|
| Microsoft Sentinel Reader | Workspace or its resource group | List incidents, alerts and entities; read rules, connectors, watchlists, bookmarks, TI indicators; run KQL |
| Microsoft Sentinel Responder | Workspace or its resource group | Everything above, plus update incident status and add comments (sync_status) |
Grant the narrowest role that covers what you run. Reader is sufficient for every
command except sync_status. A role assigned only at the app-registration level
confers nothing on the workspace: the assignment must be on the workspace (or its
resource group).
Reading threat-intelligence indicators can require a role that your Reader
assignment does not include. sync_content handles this gracefully: that one
content type is reported as not collected and the rest of the run continues.
Configuration
Add a sentinel block to init.yaml:
sentinel:
tenant_id: "00000000-0000-0000-0000-000000000000"
client_id: "00000000-0000-0000-0000-000000000000"
client_secret: "your-service-principal-secret"
cloud: commercial # commercial | government
subscription_id: "00000000-0000-0000-0000-000000000000"
resource_group: "my-resource-group"
workspace_name: "my-log-analytics-workspace"
workspace_id: "11111111-1111-1111-1111-111111111111"
timeout: 60
page_size: 50
days_back: 30
include_closed: false
enable_write_back: false
Run regscale init to add the block to an existing init.yaml without
overwriting your other settings.
Setting reference
| Key | Required | Default | Description |
|---|---|---|---|
tenant_id | With a service principal | — | Entra ID (Azure AD) tenant id |
client_id | With a service principal | — | App registration (client) id |
client_secret | With a service principal | — | App registration secret. Treat as a password |
cloud | No | commercial | commercial or government (details) |
subscription_id | Yes | — | Subscription that holds the workspace |
resource_group | Yes | — | Resource group that holds the workspace |
workspace_name | Yes | — | Log Analytics workspace name |
workspace_id | For alert sync, query, connector health | — | Workspace GUID, not the name |
workspaces | No | — | Several workspaces (details). When present, the three required keys above become defaults, not individually required |
timeout | No | 60 | Per-request timeout in seconds. Must be greater than 0 |
page_size | No | 50 | Incidents per API page. Must be 1–1000 |
days_back | No | 30 | How far back to look. Must be greater than 0 |
include_closed | No | false | Include incidents Sentinel has closed. By default only New and Active sync |
enable_write_back | No | false | Allows sync_status to modify Sentinel incidents |
Settings are validated before any command runs. A missing or out-of-range value
fails immediately and names the setting.
Authentication
What you put in init.yaml | How the CLI authenticates |
|---|---|
tenant_id, client_id and client_secret all set | Service principal (client secret) |
| All three omitted | DefaultAzureCredential: environment variables (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET), then managed identity, then an Azure CLI login |
| One or two of the three set | Rejected with an error naming the missing key(s) |
A partly configured service principal is an error rather than a fallback on
purpose. If the CLI quietly fell back to DefaultAzureCredential it could
authenticate as a different identity from the one you meant, which is far harder
to diagnose than a missing secret.
Recommendation: when the CLI runs inside Azure (a VM, container app, AKS pod,
or Azure Function), use a managed identity and omit all three keys. There is no
secret to store or rotate. Outside Azure, use a service principal with a
short-lived secret, and keep the secret out of source control.
Azure Government
Set one key:
sentinel:
cloud: government
That single setting switches the sign-in authority, the Azure Resource Manager
endpoint, the Log Analytics endpoint and the OAuth token scopes together.
cloud | Also accepted | Sign-in authority | Resource Manager | Log Analytics |
|---|---|---|---|---|
commercial (default) | public, global, azurecloud, azurepubliccloud | login.microsoftonline.com | management.azure.com | api.loganalytics.io |
government | gov, govcloud, usgov, usgovernment, azureusgovernment, fairfax | login.microsoftonline.us | management.usgovcloudapi.net | api.loganalytics.us |
An unrecognized value fails at configuration time and lists the accepted names.
It is never silently treated as commercial, because a Government workspace
reached through commercial endpoints fails with an unhelpful authentication error.
Incident links written into RegScale use the matching portal
(portal.azure.com or portal.azure.us).
Multiple workspaces
List additional workspaces under workspaces:
sentinel:
subscription_id: "00000000-0000-0000-0000-000000000000"
resource_group: "default-rg"
workspace_name: "default-sentinel"
workspaces:
- resource_group: "east-rg"
workspace_name: "east-sentinel"
workspace_id: "11111111-1111-1111-1111-111111111111"
- subscription_id: "99999999-9999-9999-9999-999999999999"
resource_group: "west-rg"
workspace_name: "west-sentinel"
- Each entry inherits any key it leaves out from the top level, so a
single-subscription tenant only repeatsresource_groupandworkspace_name. - When
workspacesis present, the top-level coordinates act only as
defaults. They are not synced as an extra workspace. List the default
workspace inworkspacestoo if you want it synced. - Each workspace keeps its own sync position (see
Incremental sync). Adding a workspace never disturbs the
others, and a workspace that fails mid-run keeps its previous position so the
next run re-reads what it missed. --limitcaps the whole run, not each workspace.--limit 10across three
workspaces yields ten items in total, and later workspaces may not be read.test_connectionchecks every workspace and fails if any one is
unreachable.queryandsync_contentaccept--workspace resource-group/workspace-name
(the bare workspace name also works) to target one.querydefaults to the
first workspace;sync_contentdefaults to all of them.
TLS and corporate certificate authorities
There is deliberately no Sentinel-specific TLS setting. The integration uses the
two CLI-wide settings in init.yaml:
| Setting | Effect |
|---|---|
sslVerify | true (default) verifies certificates; false disables verification (not recommended) |
customCaCert | Path to a CA bundle. Takes priority when set and keeps verification on |
If the CLI runs behind a TLS-inspecting proxy, or your organization uses a
private or DoD certificate chain, point customCaCert at your bundle. A path that
does not exist raises an error naming the setting; it never silently falls back to
the system trust store.
Quick start
-
Create credentials. Register an app in Entra ID (or enable a managed
identity) and assign Microsoft Sentinel Reader on the workspace. -
Configure. Add the
sentinelblock toinit.yaml. -
Verify.
regscale sentinel test_connectionSuccess reports the most recent incident's title and id. A workspace that
answers but has no incidents in the window is reported with a warning and still
counts as connected. -
Preview without writing.
regscale sentinel sync_assets --regscale_id 123 --dry-run -
Import assets, then findings. On a first import run assets first so the
issues can link to them:regscale sentinel sync_assets --regscale_id 123 regscale sentinel sync_findings --regscale_id 123 -
Schedule the two commands (see Scheduling).
123 is the id of the RegScale security plan the records are created under.
Command reference
All commands are under regscale sentinel. Option names are shown in the
underscore form used throughout this guide; the hyphenated form
(for example --days-back) is equivalent and is what --help displays.
test_connection
test_connectionregscale sentinel test_connection
Validates the configuration, authenticates, and reads one incident from every
configured workspace. Exits non-zero if the configuration is unusable or any
workspace cannot be reached. Run it before the first sync and after any change to
credentials, roles or network configuration.
sync_assets
sync_assetsregscale sentinel sync_assets --regscale_id 123
regscale sentinel sync_assets --regscale_id 123 --days_back 7 --include_closed
Creates or updates RegScale assets from the entities that Sentinel incidents
reference. Sentinel is not an inventory system, so the asset register only gains
machines and resources Sentinel has actually alerted on. Entities that are
forensic artifacts rather than inventory are filed as evidence
(see mapping).
sync_findings
sync_findingsregscale sentinel sync_findings --regscale_id 123
regscale sentinel sync_findings --regscale_id 123 --days_back 7
regscale sentinel sync_findings --regscale_id 123 --include_closed
regscale sentinel sync_findings --regscale_id 123 --full
Creates or updates one RegScale issue per Sentinel incident, with severity,
status, tactics and techniques, description and a link back to the incident in the
Azure portal.
Options for sync_assets and sync_findings:
| Option | Description |
|---|---|
--regscale_id | Required. RegScale record the assets or issues are created under |
--days_back N | Days of incident history to read. Defaults to the configured days_back |
--include_closed | Include closed incidents. Default: New and Active only |
--full | Ignore the stored sync position and re-read the whole days_back window |
--dry-run | Discover item counts without writing to RegScale |
--offset N / --limit N | Skip or cap the number of items (used to split a run across parallel jobs). --limit caps the whole run, not each workspace |
sync_alerts and sync_alert_assets
sync_alerts and sync_alert_assetsregscale sentinel sync_alerts --regscale_id 123
regscale sentinel sync_alerts --regscale_id 123 --standalone_only
regscale sentinel sync_alert_assets --regscale_id 123
An incident is a grouping of alerts, and many analytics rules never create one.
A deployment that only runs sync_findings is therefore blind to every alert no
incident collected. These commands close that gap.
They read the workspace's SecurityAlert table, because the Sentinel management
API has no operation that lists a workspace's alerts. That means they need
workspace_id (or azure-mgmt-loganalytics to look it up) and the
azure-monitor-query package.
If you also run sync_findings, add --standalone_only. Without it, an alert
that belongs to an incident is represented twice: once inside its incident's issue
and once as its own issue. With the flag, only alerts no incident grouped are
imported. Alert issues use the source title Microsoft Sentinel Alerts,
distinct from the incident issues' Microsoft Sentinel, so the two syncs never
close each other's issues.
| Option | Description |
|---|---|
--regscale_id | Required. RegScale record to create records under |
--days_back N | Days of alert history to read. Defaults to the configured days_back |
--standalone_only | Only alerts that no incident groups |
--row_limit N | Maximum alerts read per workspace. Default 5000. 0 removes the cap. A capped run is a partial run and the next run continues from where it stopped |
--full | Ignore the stored sync position and re-read the whole window |
--dry-run, --offset, --limit | As above |
Updated alerts are de-duplicated: Sentinel records a new row each time an alert
changes, and only the latest revision of each alert is imported.
query
queryregscale sentinel query --kql "SecurityAlert | project TimeGenerated, AlertName"
regscale sentinel query --days_back 7 --kql "SigninLogs | where ResultType != 0" --output signins.json
regscale sentinel query --workspace east-rg/east-sentinel --kql "Heartbeat | distinct Computer"
Runs any KQL query against the workspace's Log Analytics tables. Use it for
telemetry the incident API cannot return: sign-ins, security events, heartbeats,
or alerts that never became incidents. Without --output, the command summarizes
the result (column names and the first row); with --output, it writes every row
as JSON.
| Option | Description |
|---|---|
--kql | Required. The KQL query |
--days_back N | Time range to query. Default 1 (unlike the sync commands) |
--row_limit N | Maximum rows. Default 5000, applied as a KQL take unless your query already has its own take or limit. 0 removes the cap, which can pull an entire table into memory |
--workspace | Which configured workspace, as resource-group/workspace-name. Default: the first |
--output FILE | Write all rows to this file as JSON |
A query that times out on the server can still return partial rows. Those rows are
kept rather than discarded, and the partial state is logged.
sync_status
sync_statusSee Writing status back to Sentinel.
sync_content
sync_contentSee Documenting workspace configuration.
Incremental sync
sync_assets, sync_findings, sync_alerts and sync_alert_assets are
incremental by default. After a completed run each records the newest
modification time it saw, and the next run asks Azure only for what changed since
then, minus a ten-minute overlap to absorb clock differences between Azure and the
machine running the CLI. An hourly job therefore reads minutes of data rather than
the whole days_back window each time.
Rules worth knowing:
- A failed or truncated run does not advance the position. An error, or a run
cut short by--limit, leaves it where it was. A limited run is a sample, not a
completed pass, and is never recorded as one. - Each command and each workspace has its own position. Asset and finding
passes are tracked separately so one cannot skip data the other has not seen. - Positions advance only after RegScale accepted the writes.
- Use
--fullto ignore the position for one run and re-read the entire
days_backwindow. Do this after changing mapping-related settings or to
backfill after a bad import. - Positions are stored in
sentinel_sync_state.jsonin the CLI artifacts
directory, keyed by RegScale record id and workspace. Deleting the file has the
same effect as--fullon the next run.
How Sentinel data maps to RegScale
Overview
| Sentinel | RegScale |
|---|---|
| Incident | Issue |
| Incident tactics and techniques (MITRE ATT&CK) | ATT&CK detail on the issue |
| Host, Azure resource, IP address, IoT device entities | Asset (hardware) |
| Account, cloud application, security group, mailbox entities | Asset (software) |
| File, file hash, malware, process, registry key, submission mail, URL, DNS resolution entities | Evidence and a plan-level Data record (not assets) |
| Alert that no incident groups | Issue (via sync_alerts), source "Microsoft Sentinel Alerts" |
| Analytics rules, automation rules, connectors, watchlists, bookmarks, hunting queries, threat intelligence | Data records and an evidence file (via sync_content) |
Severity
| Sentinel | RegScale issue severity |
|---|---|
| Critical | Critical |
| High | High |
| Medium | Moderate |
| Low | Low |
| Informational | Not Assigned |
| Anything else | Not Assigned |
The Sentinel portal offers Informational through High. Critical is mapped anyway
because analytics rules can carry values the portal does not display.
Status
| Sentinel status | Sentinel classification | RegScale issue |
|---|---|---|
| New | — | Open |
| Active | — | Open |
| Closed | True positive or Undetermined | Closed |
| Closed | False positive or Benign positive | Closed (recorded as suppressed) |
By default only New and Active incidents are imported, so a routine sync
does not resurrect incidents an analyst has already dispositioned. Add
--include_closed (or include_closed: true) to import closed ones as well.
Entity routing
Sentinel attaches many kinds of entity to an incident, and they are not all the
same kind of thing. Only entities that represent durable inventory become assets.
Inventorying every URL and file hash as an asset would flood the register with
per-incident artifacts.
| Destination | Entity kinds |
|---|---|
| Asset: hardware | Host, AzureResource, Ip, IoTDevice |
| Asset: software | Account, CloudApplication, SecurityGroup, Mailbox |
| Evidence | File, FileHash, Malware, Process, RegistryKey, SubmissionMail, Url, DnsResolution |
- An entity kind Microsoft adds in future is filed as evidence under "Other
Artifacts" rather than as an asset, because an unrecognized kind is far more
likely to be a forensic artifact than a machine. - Nothing is discarded. Every entity, whichever way it routes, still travels with
the issue as an observable. - Evidence artifacts are de-duplicated across the whole run (with the list of
incidents each appeared in), filed as a plan-level Data record that always
reflects current state, and uploaded as an evidence file that is a per-run
snapshot. Collection is capped at 25,000 distinct artifacts per run, with a
warning if the cap is reached. - An entity with no identifying value is skipped rather than given a made-up id.
Linking issues to assets
An issue links to an asset by matching the entity's identifier against the
asset's stored identifier, so run sync_assets before sync_findings on a first
import, and keep both on the same schedule afterward.
Issue identity
Each issue is keyed on the Sentinel incident's immutable id, so re-running a sync
updates the existing issue rather than creating a duplicate, even if the incident's
title changes.
Writing status back to Sentinel
Every other command reads. sync_status writes into your analysts' live incident
queue, so it is off by default, needs a higher Azure role, and supports a
dry run.
To enable:
- Assign Microsoft Sentinel Responder to the credential on the workspace.
- Set
enable_write_back: trueundersentinel:ininit.yaml.
# Report what would change without writing anything
regscale sentinel sync_status --regscale_id 123 --dry_run
# Close incidents whose RegScale issue is resolved
regscale sentinel sync_status --regscale_id 123
# Also set incidents back to Active when their RegScale issue is open again
regscale sentinel sync_status --regscale_id 123 --reopen
# Change status without adding the comment to the incident timeline
regscale sentinel sync_status --regscale_id 123 --no_comments
| Option | Description |
|---|---|
--regscale_id | Required. RegScale security plan whose Sentinel issues are pushed back |
--reopen | Also reactivate incidents whose RegScale issue is open again. Off by default |
--no_comments | Skip the audit comment on the incident timeline |
--dry_run | Report without writing |
What gets written
| RegScale issue status | Sentinel status | Classification | Reason |
|---|---|---|---|
| Closed | Closed | True positive | — |
| Cancelled | Closed | Undetermined | — |
| Exception / Waiver | Closed | Benign positive | Suspicious but expected |
| Anything else | Unchanged (Active, with --reopen) | — | — |
The mapping is deliberately conservative because Sentinel feeds classifications
back into analytic-rule tuning. The integration never writes "False positive".
A cancelled RegScale ticket does not prove a detection is noise, so it maps to
"Undetermined", which asserts nothing. An incident in New is never moved by
--reopen: untriaged is not closed.
Safeguards
- Only issues this integration created are considered (source "Microsoft
Sentinel"). Issues owned by other tools, and alert-sourced issues, are never
touched. - No overwrite of analyst edits. Each incident is read immediately before it
is written, and the write is rejected by Azure if an analyst changed the
incident in between. That issue is reported as failed and picked up next run
against fresh state. Fields the integration does not manage (owner, labels,
activity times) are preserved. - Audit trail. Each change posts a comment on the incident timeline naming the
RegScale issue and linking to it. Re-runs rewrite that single comment instead of
stacking new ones. A failed comment never undoes a successful status change. - Multiple workspaces. Each workspace is offered the issues no earlier
workspace could resolve. Only issues that no workspace recognized are
reported as failures. - Exit status. The command exits non-zero if any issue failed, so a scheduled
run surfaces a broken credential or missing role instead of reporting a clean
pass that changed nothing.
A Reader-only credential fails per incident with an authorization error rather than
at startup, so assign Responder before enabling write-back.
Documenting workspace configuration
Incidents and alerts record what Sentinel found. sync_content records what it
is configured to look for, which is the evidence an assessor asks for when
reviewing continuous monitoring.
# Everything, for every configured workspace
regscale sentinel sync_content --regscale_id 123
# Only the types an audit asked for
regscale sentinel sync_content --regscale_id 123 --content analytics_rules --content data_connectors
# One workspace, reporting what would be filed without writing it
regscale sentinel sync_content --regscale_id 123 --workspace east-sentinel --dry_run
--content value | Documents | Read from |
|---|---|---|
analytics_rules | Which detections are enabled, and their KQL | Management API |
automation_rules | What fires automatically on an incident | Management API |
bookmarks | What analysts flagged while hunting | Management API |
connector_health | Whether each data connector is actually ingesting | SentinelHealth table |
data_connectors | Which sources are wired up at all | Management API |
hunting_queries | The hunts available to analysts | Log Analytics saved searches |
threat_indicators | The threat intelligence the workspace matches against | Management API |
watchlists | Reference data that rules join against, items included | Management API |
| Option | Description |
|---|---|
--regscale_id | Required. Security plan the content is filed against |
--content | Content type to collect. Repeatable. Omit to collect every type |
--workspace | One workspace only (resource-group/workspace-name). Default: all |
--days_back N | Time range for connector health. Default 30. Ignored by the other types |
--dry_run | Collect and report without creating records or uploading evidence |
How it is filed
None of this is a finding (nothing is wrong) and none of it is an asset, so it is
filed against the security plan in two forms:
- One Data record per content type per workspace: a trimmed, queryable summary
of each item, with long text shortened. The record is replaced in place on every
run so it reflects current state. - One evidence file per run per workspace, holding every field of every
item, including full KQL, threat-indicator patterns and watchlist items.
Behavior when something is unavailable
- Each type is collected independently. A credential that cannot read threat
intelligence still gets the analytics rules it can read. The failure is logged
and named, not raised. - Every type is capped. Hitting a cap logs a warning and marks that type
truncated in both the Data record and the evidence file, so a partial
threat-intelligence feed is never presented as complete. connector_healthneedsazure-monitor-queryand a workspace GUID, and the
SentinelHealthtable is only populated when Sentinel health diagnostics are
enabled in the workspace.hunting_queriesneedsazure-mgmt-loganalytics.
Without them, only that type is skipped, with the reason logged.- An older
azure-mgmt-securityinsightthat lacks an operation skips that type
with a warning rather than failing the run.
Scheduling
All commands are ordinary CLI commands and work under cron, systemd timers,
Kubernetes CronJobs, CI schedulers or the RegScale scheduler.
| Command | Suggested cadence | Notes |
|---|---|---|
sync_assets | Daily | Run before sync_findings on first import |
sync_findings | Hourly, --days_back 2 | Window wider than the interval so a missed run self-heals |
sync_alerts --standalone_only | Hourly | Only if you need alerts that never became incidents |
sync_status | Every 15–60 minutes | Only when write-back is enabled |
sync_content | Weekly, or before an assessment | Documents configuration, which changes slowly |
Because syncs are incremental, a wide --days_back costs little once the first run
has completed.
Exit codes
| Condition | Exit code |
|---|---|
| Command completed | 0 |
| Configuration invalid, authentication failed, or the sync raised an error | 1 |
test_connection: any configured workspace unreachable | 1 |
sync_status: any issue failed to update, or write-back is disabled | 1 |
sync_content: nothing was collected and something failed | 1 |
sync_content: some types collected, some failed | 0 (failures are logged as warnings) |
sync_content treats a partial result as a success on purpose. If a run that
documented seven types and lost one failed the job, operators would learn to ignore
the exit code.
Security and data handling
- Least privilege. Reader is enough for everything except
sync_status. - Secrets.
client_secretis treated as sensitive. Prefer a managed identity,
or supplyAZURE_*environment variables, so no secret lives ininit.yaml.
Never commit a real secret. - Read-only by default. No command writes to Azure unless
enable_write_back: trueis set andsync_statusis run. - TLS verification is on by default. See
TLS. - What leaves Azure. Incident and alert titles, descriptions, severity,
status, tactics, entity identifiers (hostnames, IP addresses, account names and
similar) and, forsync_content, your rule logic and watchlist contents are
written into RegScale. Review what your watchlists and entities contain before
syncing to a RegScale instance with a different audience. - Logging. Errors are logged with stack traces to the CLI's local log files,
with credentials redacted. - Throttling. Azure responses of 429, 500, 502, 503 and 504 are retried up to
four times with backoff, honoring theRetry-Afterheader.
Troubleshooting
Start with regscale sentinel test_connection; it separates configuration and
permission problems from mapping problems.
| Symptom | Cause and fix |
|---|---|
The Microsoft Sentinel integration requires the Azure SDK | Stripped environment. pip install azure-mgmt-securityinsight azure-identity |
Microsoft Sentinel workspace not configured. Add ... | One of subscription_id, resource_group, workspace_name is empty |
Incomplete Microsoft Sentinel service principal: missing ... | You set one or two of tenant_id / client_id / client_secret. Set all three, or remove all three to use DefaultAzureCredential |
Unknown Azure cloud ... | cloud is misspelled. Use commercial or government |
page_size must be between 1 and 1000, timeout or days_back must be greater than zero | Out-of-range numeric setting |
| Authentication fails with a service principal | Check the secret has not expired, the tenant id is right, and the role assignment is on the workspace or its resource group |
| Authorization error (401/403) on a Government workspace | cloud is left at commercial. Set cloud: government |
| Connected, but zero incidents | Expected when the window has none. Widen with --days_back, or add --include_closed |
| Issues created but not linked to assets | Run sync_assets first, then sync_findings |
| The same alert appears as two issues | You ran sync_findings and sync_alerts without --standalone_only |
Microsoft Sentinel log queries require the Azure Monitor query SDK | pip install azure-monitor-query |
No Log Analytics workspace GUID is configured | Set sentinel.workspace_id (Overview blade "Workspace ID"), or install azure-mgmt-loganalytics so it is looked up from the workspace name |
connector_health skipped or returns nothing | Missing SDK or GUID, or Sentinel health diagnostics are not enabled on the workspace |
sync_status says write-back is not available | Expected until enable_write_back: true is set |
sync_status fails per incident with an authorization error | The credential has Reader. Assign Microsoft Sentinel Responder |
sync_status reports an incident as failed after an analyst edited it | The safeguard against overwriting analyst changes. The next run retries against fresh state |
sync_status reports "not Sentinel incidents" | The issue's finding id is not a Sentinel incident GUID, or the issue belongs to another tool |
| A sync seems to skip data | Positions are incremental. Run with --full to re-read the whole window, and check you did not use --limit, which makes a run partial |
| Persistent HTTP 429 from Azure | Retried automatically. For a large workspace, lower page_size or narrow days_back |
Could not reach N of M Sentinel workspace(s) | At least one entry under workspaces is wrong or the credential lacks a role there. The log names each failing workspace |
For more detail, rerun with --debug and review app.log and errors.log in the
working directory.
Updated about 10 hours ago
