Skip to content

Security

Breeze Security dashboard showing posture score, vulnerability counts, and compliance status

The Security module provides continuous visibility into the security posture of every managed device. The Breeze agent collects antivirus status, firewall state, disk encryption details, local administrator accounts, and password policy configuration from each endpoint. That data flows into the API where it is scored, trended, and surfaced through a unified dashboard. When the agent detects threats during a scan, those threats can be quarantined or removed directly from the console. A built-in recommendations engine analyzes posture data across the fleet and produces prioritized, actionable guidance to reduce risk.


Partner admins can restrict dashboard access to specific source IP addresses or CIDR ranges from Settings -> Security -> IP Allowlist. The allowlist is partner-level: once configured, authenticated dashboard requests and password login attempts for that partner are checked before access continues. Agent endpoints use separate agent authentication and are not affected.

The allowlist requires working proxy trust. In production, set TRUST_PROXY_HEADERS=true and configure TRUSTED_PROXY_CIDRS so the API trusts only your reverse proxy hop, such as Caddy behind Cloudflare Tunnel. If Breeze cannot determine a trusted client IP, the allowlist fails open and reports inactive status instead of creating a false lockout guarantee. See Environment Variables for the proxy trust and IP_ALLOWLIST_ENFORCEMENT_MODE settings.

Platform administrators bypass the partner allowlist as a break-glass path, and each bypass is audited. Operators can also set IP_ALLOWLIST_ENFORCEMENT_MODE=off to globally disable enforcement during an emergency, then return it to enforce after correcting the partner settings.


The agent reports a SecurityStatus payload on each heartbeat. The payload includes the detected AV provider, real-time protection state, definition freshness, firewall status, disk encryption status, local admin accounts, and password policy configuration.

Field Description
provider Normalized security provider identifier (e.g. windows_defender, bitdefender)
providerVersion Version string of the installed AV product
definitionsVersion Virus definition / signature version
definitionsDate Timestamp of the most recent definitions update
realTimeProtection Whether real-time scanning is active. null when the agent could not read it (collection failed or never reported); the UI shows Unknown and the device is not counted as protected or unprotected
lastScan Timestamp of the most recent completed scan
lastScanType Type of last scan: quick, full, or custom
threatCount Number of active threats on the device
firewallEnabled Whether the host firewall is active. null when the agent could not read it; shown as Unknown
encryptionStatus Disk encryption state: encrypted, partial, or unencrypted
encryptionDetails Per-volume encryption breakdown (method, mount point, protection status)
localAdminSummary Local administrator account inventory with issue flags
passwordPolicySummary Password policy settings (min length, complexity, lockout, history)
gatekeeperEnabled macOS Gatekeeper status (macOS only)
  • AV detection: Windows Security Center (root/SecurityCenter2) via CIM, with fallback to Get-MpComputerStatus for Windows Server
  • Firewall: Get-NetFirewallProfile queries all three profiles (Domain, Private, Public)
  • Encryption: Get-BitLockerVolume reads BitLocker protection status and encryption percentage per volume
  • Local admins: Get-LocalGroupMember -Group 'Administrators' enumerates the local Administrators group
  • Password policy: secedit /export /areas SECURITYPOLICY reads min length, complexity, max and min age, lockout threshold, and history count from the local security policy. If the export fails, NetUserModalsGet (what net accounts uses) supplies everything except complexity, which then shows as Unknown. A max age of 0 means passwords never expire, which fails the 90-day check

The agent normalizes detected AV products to one of the following provider identifiers. On Windows, multiple AV products may be registered simultaneously through the Security Center.

Provider ID Display Name Vendor
windows_defender Microsoft Defender Microsoft
elastic_defend Elastic Defend Elastic
bitdefender Bitdefender Bitdefender
sophos Sophos Sophos
sentinelone SentinelOne Singularity SentinelOne
crowdstrike CrowdStrike Falcon CrowdStrike
malwarebytes Malwarebytes Malwarebytes
eset ESET ESET
kaspersky Kaspersky Kaspersky
emsisoft Emsisoft Emsisoft
webroot Webroot SecureAnywhere OpenText
withsecure WithSecure Elements WithSecure
cylance Aurora Endpoint Defense (CylancePROTECT) Arctic Wolf
other Other Other

ThreatDown (Malwarebytes’ business brand) reports as malwarebytes. F-Secure products report as withsecure. Aurora Endpoint Defense still registers with Windows Security Center as CylancePROTECT and reports as cylance.


Security → IOC Scans (/security/scans) is the console for running on-demand scans and working detected threats without leaving the browser. It has three tabs:

  • Scans — pick one or more devices (single- or multi-select), choose a scan type (Quick, Full, or Custom with an explicit path), and start the scan. Submission progress is shown per device as each request queues. Below that, Active Scans shows what’s currently queued or running, and Scan History lists the most recent completed and failed runs with their result and duration.
  • Threats — a filterable list of detected threats (by status, severity, device) across the fleet. Selecting a threat opens its detail view, where you can Quarantine, Restore, or permanently remove it; the bulk-action toolbar on the list lets you quarantine or remove several threats at once. Restoring a quarantined threat moves it back to allowed without re-scanning.
  • Sweeps — run a detection rule set across many devices at once and follow the progress, cancel it, or open a group of sweeps by its link. See IOC sweeps.

Quarantine, Remove and Restore send a command to the device; they do not change the threat on their own. Since v0.117.0 the threat keeps its current status until the agent reports the result, and only then shows quarantined, removed or allowed. If the device is offline, the threat keeps its previous status until the device comes back and runs the command. Earlier versions changed the status as soon as the action was queued, so a threat on an offline device could show as quarantined when nothing had happened on the device.

Auto-quarantine runs under an approving user

Section titled “Auto-quarantine runs under an approving user”

IOC auto-quarantine (set on the Security feature of a configuration policy) moves files on every device the policy reaches with no one reviewing each scan, so it is treated as a device-execution grant. Saving Security settings with auto-quarantine on needs the devices:execute permission and MFA; with auto-quarantine off, devices:write is enough, and turning it off is never restricted. Because auto-quarantine is on by default, a technician with only devices:write must turn it off before the Security settings will save.

Scheduled scans quarantine only while the user who approved auto-quarantine is active and still holds devices:execute. Policies that had auto-quarantine on before v0.122.1 keep running under the user who created them on the same terms. Otherwise the policy shows Auto-quarantine is paused and its scans run detect-only until a user with devices:execute and MFA saves the Security settings again. A scan you start by hand runs under your own permissions; without a completed MFA check in your session it runs detect-only.

Security → Detection Rules (/security/detection-rules, v0.125.0+) is where you manage the YARA rule sets that IOC scans and sweeps use. Every change is checked on the server, with the same compiler devices use, before any device receives it. Scanning with rule sets needs agent 0.124.0 or later; older agents fall back to the built-in legacy signatures.

The list shows each set’s owner (Breeze (built-in), All organizations or Organization), how many rules it has and its published version, with badges such as Has errors, Not published and Disabled.

  1. Click New rule set and give it a name, an optional description and an owner: One organization, or All organizations (partner-wide) if you work at partner level.
  2. On the Rules tab, add a rule: a name (letters, digits and underscores), a severity (Low, Medium, High or Critical), optional tags, and the YARA source.
  3. Save. Breeze checks the rule and, if every rule in the set compiles, publishes the set as a new numbered version (“Saved and published as version N”).

There is no separate Publish button: adding, editing or deleting a rule republishes the set, and so does turning Enabled or Auto-quarantine on or off once the set has been published. If a rule does not compile, its row shows the error with the line number, a “Not published: fix the errors below” banner stays up, and devices keep the last good version.

The built-in Breeze set is read-only and updates with Breeze releases. A set holds up to 500 rules, each up to 64 KB of source.

The Import IOCs tab turns a list of indicators into rules. Paste one indicator per line (# starts a comment) or a JSON array. Breeze recognises MD5, SHA-1 and SHA-256 hashes, file names, file paths, domains, IP addresses and text strings; prefix a line (for example sha256:) to set the type yourself. Defanged values such as example[.]com are refanged, and duplicates are flagged.

Give the batch a label and a severity (High by default), review the preview, then click Import N IOCs. Each indicator type becomes one exact-match rule (split if it would grow too large), and the set is republished. Keep in mind:

  • Domains and IP addresses match text inside scanned files, not network traffic.
  • Hash indicators make full scans slower.
  • One import takes up to 1,000 indicators and 256 KB of text. Importing the exact same batch again is refused.

The Test a file tab scans a file you upload (up to 10 MB) against the set’s current rules, including changes that are not published yet, and lists the rules that matched. You can give the path the file would have on a device, since some rules match on it. The test runs in a sandbox on the Breeze server, not on a device. The file is not kept; the audit log records only its SHA-256, size and match count. Each user can run 10 tests every 10 minutes. If the server cannot isolate the scan, the tab says file tests are not available; editing, importing and device scans keep working.

Choose which sets devices scan with on a configuration policy’s Security tab, under Detection rule sets (up to 20 per policy). Both scheduled policy scans and manual scans send the selected sets to the device. A device can use only sets owned by its own organization, its partner’s all-organizations sets, and the built-in set. A new Security policy starts with the built-in set selected; with no set selected, scans use the built-in legacy signatures only. A set that was deleted or is out of reach shows as Unavailable rule set and must be removed before the policy can be saved.

To run sets across many devices right now, use Sweep now in the rule-set editor; see IOC sweeps.

Viewing rule sets needs devices:read. Creating, editing, deleting, importing and testing need devices:write, and turning on a set’s Auto-quarantine also needs devices:execute. Site-restricted users cannot edit rule sets, and only partner-level users can edit all-organizations sets. The AI assistant can import indicators only with approval, and never into a set that has auto-quarantine on.

A detection rule set lives under Security → Detection Rules; each time you publish it, it gets a numbered version. An IOC sweep runs one or more published rule sets against many devices at once and pins the exact versions it was approved with.

A sweep is one request that fans out into one ordinary IOC scan per eligible device, so every result shows up in the usual Scan History and Threats views. Start one from a rule set (Sweep now in the rule-set editor), from the API, or from the AI assistant. Follow it on the Sweeps tab of Security → IOC Scans: the list shows the rule sets and their versions, progress, how many scans ran with degraded coverage, threats found, who started it and when, and its state (Active, Completed, Cancelled or Expired). A sweep that spans several organizations is stored as one row per organization; they share a group, and #sweeps&group=<groupId> in the page address opens that group.

A sweep never quarantines or removes anything, whatever the rule set’s auto-quarantine setting says. On Windows it also does not start a Microsoft Defender scan, unlike a single-device scan started from the Scans tab. A match is reported as a threat, and you decide what to do with it from the Threats tab.

Choose the scope when you start the sweep:

  • All reachable devices — every device your account can access.
  • Organizations, Sites, Device groups or Devices — only those.

Scopes defined by device policies are not offered. A request is limited to 10,000 devices. Devices outside your access are never included, and asking for one explicitly is refused.

A device in scope can be skipped for one of three reasons, each shown with its count in the preview:

Reason Meaning
agent_too_old The agent is older than 0.124.0 and cannot run YARA rule sets. Update it and sweep again.
busy_same_sweep An identical sweep is still active on the device.
rule_set_not_eligible The device’s operating system or organization is outside the rule set’s reach.

Users limited to certain sites or devices do not see skip counts; the Sweeps tab shows a dash for them.

Sweep now opens a five-step dialog: scope, scan type (Quick, Full, or Custom with up to 20 paths of at most 1,024 characters), duration, preview and confirm. The preview shows how many devices in how many organizations will be scanned, the rule-set versions, and the skipped devices with the reason for each. Nothing is written until you confirm. Confirming sends a digest of what you previewed; if the devices or rule sets changed in the meantime, the dialog shows the new preview and asks again instead of running something you did not approve. If the same sweep is already running, the dialog links to it.

Multi-factor authentication above 50 devices

Section titled “Multi-factor authentication above 50 devices”

A sweep of more than 50 devices needs an interactive sign-in with multi-factor authentication satisfied, as your organization’s policy requires. When no second factor is enforced, a signed-in password session counts. If the check fails, the dialog says so and you can sign in again or narrow the scope. API keys and other machine credentials are refused above 50 devices whether or not multi-factor authentication is enforced; narrow the scope or run the sweep from the console.

When you confirm, the sweep pins each rule set’s published version and content hash. Every scan of the sweep runs exactly those versions, and a threat found by a pinned scan shows Version N in its rule panel. If someone republishes a pinned rule set while the sweep is running, the scans that have not started yet fail with rule_set_changed rather than silently running different rules. Once at least one scan has failed that way, the Sweeps tab marks the row Rules changed since this sweep started with Sweep again with the current rules; a sweep that finished before the republish is not marked. The API reports the count as progress.ruleSetChanged on each sweep, and GET /security/scans/:deviceId returns each scan’s sweepId and ruleSetErrors.

A sweep stays open for 24 hours by default; you can set 1 to 72 hours. An offline device keeps its queued scan and runs it when it returns within that time. When the time is up, scans that have not started become Expired, the sweep becomes Expired, and scans already running on a device are allowed a grace period before they are closed out.

Each device runs one scan at a time. The server hands scans to devices in small batches on a timer, and also limits how many scans run at once per device, per organization and per partner, so a large sweep takes a while and does not flood a site. An organization can have 5 active sweeps at once, a partner at most 200 running scans, and a user can start 10 sweeps per hour. These limits and the operator settings behind them:

Setting Default Meaning
SECURITY_SWEEP_MAX_DEVICES 10000 Devices per request
SECURITY_SWEEP_MAX_ACTIVE_PER_ORG 5 Active sweeps per organization
SECURITY_SWEEP_PARTNER_RUNNING_CAP 200 Running sweep scans per partner
SECURITY_SWEEP_PUMP_INTERVAL_MS 30000 How often queued scans are handed out
SECURITY_SWEEP_PUMP_BATCH 100 Scans admitted per sweep per organization per tick
SECURITY_SWEEP_TTL_HOURS_DEFAULT 24 Default duration
SECURITY_SWEEP_MFA_DEVICE_THRESHOLD 50 Devices above which multi-factor authentication is required
SECURITY_SWEEP_RUNNING_GRACE_MINUTES 65 Grace for scans already running at expiry
IOC_HUNT_FOUR_EYES_DEVICE_THRESHOLD 25 Devices above which an AI-started sweep needs a second approver

Cancel stops a sweep; Cancel all stops every sweep of a group. Scans still queued stop at once. A scan already delivered to a device finishes there, because the agent cannot be recalled, and the confirmation says how many are still finishing. Cancelling an already finished sweep does nothing. You need permission to run commands on the devices, and a user limited to certain sites or devices can cancel only sweeps they started.

Sweeping again with the same rule sets, scope and scan type while one is active is refused with a link to the running sweep. Once it has finished, a new sweep starts fresh against the current published versions. A sweep does not remember its devices, so choosing Sweep again with the current rules reopens the dialog with the rule sets, scan type and any custom paths filled in and asks for the scope again.

A scan counts as degraded when it completed or timed out on the legacy engine, or when some rules in the set could not be loaded on the device. The Sweeps tab shows the count, and the sweep’s tone turns to a warning so a clean-looking result is not mistaken for full coverage. Failed, expired and cancelled scans are counted separately.

The AI assistant and MCP clients use the ioc_hunt tool: listing rule sets, previewing, listing and checking sweeps are Tier 1 and need no approval; cancelling a sweep is Tier 2; starting a sweep and importing IOCs are Tier 3 and need an approved action (see AI features and MCP server). A sweep started by the assistant is supervised up to 25 expected devices, and above 25 it needs a second approver. An assistant sweep covers one organization at a time. Importing IOCs adds them to a rule set and publishes it; importing into a set that has auto-quarantine turned on is refused. ioc_hunt is not part of any AI agent’s tool catalog.

Every sweep writes audit events for its organization row: security.scan_sweep.create, security.scan_sweep.cancel, security.scan_sweep.expire and security.scan_sweep.complete. They record the rule-set pins, scan type, scope kind, counts and origin (web, API, AI chat or MCP), never paths, device ids or IOC values.


The agent scans for known threat signatures using both filename pattern matching and file content analysis. Detected threats are classified by type and severity:

Threat Type Description
malware General malicious software (e.g. Mimikatz, EICAR test file)
trojan Trojan horse programs (e.g. Emotet, Trickbot)
ransomware Ransomware indicators (e.g. ransom notes, decryption instructions)
spyware Spyware and surveillance tools
pup Potentially unwanted programs
Severity Meaning
low Minimal risk; informational detection
medium Moderate risk; should be reviewed
high Significant risk; prompt action recommended (e.g. Mimikatz, EICAR, ransomware notes)
critical Severe risk; immediate action required (e.g. CobaltStrike beacons, Emotet)

A threat found by a detection rule shows the rule, its rule set and the matched strings in the threat’s rule panel. When the scan ran pinned rule-set versions (every IOC sweep does), the panel also shows Version N, the version of the rule set that was dispatched to the device. Threats found by the built-in signatures, and threats from scans that did not pin a version, show no version.

Each threat progresses through a status lifecycle:

Status DB Status Description
Active detected, failed Threat is present and unresolved
Quarantined quarantined Threat file moved to an isolated quarantine directory
Removed removed, allowed Threat file deleted or explicitly allowed

You can take action on detected threats directly from the API:

Terminal window
# Quarantine a threat (moves file to quarantine directory)
POST /security/threats/{threatId}/quarantine
# Permanently remove a threat
POST /security/threats/{threatId}/remove
# Restore a quarantined threat (mark as allowed)
POST /security/threats/{threatId}/restore

Each action queues a command to the agent and updates the threat status in the database. The quarantine directory defaults to:

Platform Path
Windows %ProgramData%\Breeze\quarantine
macOS /Library/Application Support/Breeze/quarantine
Linux /var/lib/breeze/quarantine

Initiate an on-demand security scan on a specific device by posting to the scan endpoint:

Terminal window
POST /security/scan/{deviceId}
{
"scanType": "quick",
"paths": []
}
Scan Type Description
quick Scans high-risk locations: temp directories, Downloads folder, startup/launch directories
full Comprehensive scan of all major system locations (entire drives on Windows, /Applications, /Library, /Users on macOS, / tree on Linux)
custom Scans only the paths specified in the paths array

The scan is queued as a SECURITY_SCAN command to the agent. The response returns a scan record with status queued and a 202 Accepted status code.

Status Description
queued Scan command sent to the agent, waiting for execution
running Agent is actively scanning
completed Scan finished; results include threatsFound count and durationSeconds
failed Scan encountered an error
cancelled The scan was stopped before it ran, for example when its sweep was cancelled
expired The scan never ran because its sweep’s time ran out
Terminal window
GET /security/scans/{deviceId}?scanType=quick&status=completed&startDate=2026-02-01

Returns paginated scan history for the device, filterable by scanType, status, and date range.


The security posture system computes a 0-100 score for each device based on eight weighted factors:

Factor Label Weight Description
patch_compliance Patch Compliance 25% Are critical and important patches up to date?
encryption Disk Encryption 15% Is full-disk encryption active on all volumes?
av_health AV Health 15% Is AV installed, real-time protection on, and definitions fresh?
firewall Firewall Status 10% Is the host firewall enabled?
open_ports Open Ports Exposure 10% Are unnecessary listening services exposed?
password_policy Password Policy 10% Does the local password policy meet baseline requirements?
os_currency OS Currency 10% Is the operating system version current and supported?
admin_exposure Admin Exposure 5% Are local admin accounts minimized and hardened?

The overall score is graded on a letter scale:

Grade Score Range
A 90 - 100
B 80 - 89
C 70 - 79
D 60 - 69
F 0 - 59

Each device is assigned a risk level based on its posture:

Risk Level Meaning
low Device is fully protected (score high, no active issues)
medium Minor gaps detected (e.g. firewall off or encryption missing)
high Multiple protection gaps or elevated threat count
critical Severe exposure: unprotected with active threats

The posture worker runs hourly via BullMQ, computing scores for every device across all organizations. Organization-level snapshots aggregate:

  • devicesAudited – total devices scored
  • lowRiskDevices, mediumRiskDevices, highRiskDevices, criticalRiskDevices – risk distribution
  • Per-factor average scores
  • topIssues – most common compliance gaps

The API evaluates each device’s local password policy against baseline requirements:

Rule Requirement
Minimum length 12+ characters
Complexity required Enabled
Maximum password age 90 days or fewer
Account lockout threshold 1-5 failed attempts
Password history 5+ remembered passwords

A device is compliant only if all five checks pass.

The admin audit identifies three categories of risk in local administrator accounts:

Issue Type Description
default_account Built-in administrator accounts that are still enabled
weak_password Admin accounts with passwords older than 180 days
stale_account Admin accounts with no login activity in 90+ days
Terminal window
GET /security/trends?period=30d

Returns time-series data points showing how the overall posture score has changed over the requested period (7d, 30d, or 90d). The response includes a summary with current score, previous score, absolute change, and directional trend (improving, declining, or stable).


The recommendations engine analyzes posture data across the fleet and generates prioritized, actionable guidance. Recommendations are computed dynamically based on how many devices fall below threshold scores for each security factor.

  1. The engine loads the latest posture snapshots for all devices in the organization.
  2. For each security factor, it counts devices scoring below the target threshold (e.g. AV health below 80, firewall below 90).
  3. If any devices are affected, a recommendation is generated with priority scaled to the percentage of the fleet impacted.
  4. Recommendations are sorted by priority (critical first), then by affected device count.
Category Trigger Threshold Baseline Priority
antivirus AV health score below 80 High
vulnerability_management Active threats + open ports/OS currency below 70 Critical
firewall Firewall score below 90 High
encryption Encryption score below 90 High
password_policy Password policy score below 85 Medium
admin_accounts Admin exposure score below 85 Medium
patch_compliance Patch compliance score below 90 High

Priority is dynamically escalated based on what percentage of the fleet is affected:

Fleet % Affected Dynamic Priority
45%+ Critical
25-44% High
10-24% Medium
Under 10% Low

The final priority is the higher of the baseline priority and the dynamic priority.

Each recommendation can be in one of three states:

Status Description
open Active recommendation requiring attention
completed Marked as resolved by an administrator
dismissed Acknowledged but not acted upon

Completing or dismissing a recommendation creates an audit log entry. To mark a recommendation:

Terminal window
# Mark as completed
POST /security/recommendations/{id}/complete
# Dismiss
POST /security/recommendations/{id}/dismiss

The dashboard endpoint aggregates all security data into a single response for rendering the security overview UI.

Terminal window
GET /security/dashboard?orgId={orgId}
Field Description
totalDevices Total number of devices with posture data
protectedDevices Devices at posture risk level low that are online (posture score 85 or higher)
atRiskDevices Devices at posture risk level medium or high
unprotectedDevices Devices at posture risk level critical
offlineDevices Devices not currently reporting
totalThreatsDetected Total threat count across all devices
activeThreats Threats in active status
quarantinedThreats Threats currently quarantined
removedThreats Threats that have been removed
securityScore Fleet-wide average posture score (0-100)
providers AV provider distribution with device counts and coverage percentages
antivirus Real-time protection counts: protected, unprotected, and unknown (state could not be read)
firewall Firewall counts: enabled, disabled, and unknown
firewallEnabled / firewallDisabled Firewall state counts (devices with an unknown state are in neither)
encryption BitLocker and FileVault enabled counts
passwordPolicyCompliance Average password policy factor score
adminAudit Summary of default/weak/stale admin account issues with top affected devices
recommendations Top security recommendations with priority and category
trend 30-day score trend as timestamp/score data points

protectedDevices, atRiskDevices and unprotectedDevices measure overall posture risk (falling back to per-device status when no posture snapshot exists), not antivirus coverage: a device with real-time protection on still counts as at risk when its posture score is below 85. For antivirus coverage, read the antivirus block. The Antivirus page tiles and the Security overview card both use it: the total is protected + unprotected + unknown, and coverage is protected divided by that total.

For a detailed per-factor breakdown, use the score breakdown endpoint:

Terminal window
GET /security/score-breakdown

Returns each posture component with its score, weight, status (good/warning/critical), and the count of affected devices below the threshold.


Breeze tracks disk-encryption status across your fleet and can escrow each device’s recovery key — so when a user is locked out of a BitLocker (Windows) or FileVault (macOS) volume, you retrieve the key from Breeze instead of hunting through spreadsheets or Active Directory.

The Encryption page (under Security) lists every device with its encryption method as the agent reported it (BitLocker, FileVault, LUKS, or None; Unknown when an encrypted device sent no method detail), status (Encrypted, Partial, Unencrypted), and whether a recovery key has been escrowed. An Unknown tile counts those devices. The TPM column shows a dash: the agent does not collect TPM state yet. Filter by status, operating system, or escrow state (Key escrowed / Key missing) to find machines that are protected but whose recovery key isn’t yet on file.

Open a device’s Security tab to see its Recovery Keys panel:

  • Collect now — asks the agent to report the device’s current recovery key. The request is queued and runs the next time the device is online.
  • Rotate key — requests a new recovery key be generated and escrowed (where the platform supports rotation).
  • Reveal — shows an escrowed key’s value. Every reveal is recorded in an audit trail.

Recovery keys are stored encrypted at rest. Access is org-scoped, and each time a key is collected, revealed, or rotated the action is written to a recovery-key access log so you retain a full history of who saw which key and when.

Terminal window
# List escrowed recovery keys for a device
GET /security/encryption/devices/:deviceId/recovery-keys
# Reveal a specific key (audited)
POST /security/encryption/devices/:deviceId/recovery-keys/:keyId/reveal
# Ask the agent to collect/report the device's key
POST /security/encryption/devices/:deviceId/recovery-keys/collect
# Request key rotation
POST /security/encryption/devices/:deviceId/recovery-keys/rotate

Security policies define the expected AV/EDR configuration (scan schedule, real-time protection, auto-quarantine, exclusions) for devices.

Policy Ownership: Organization vs. Partner-Wide

Section titled “Policy Ownership: Organization vs. Partner-Wide”

A security policy is owned at one of two scopes, chosen when the policy is created and fixed for the life of the policy:

  • This organization only — the default. The policy applies only to devices in the organization it was created for.
  • All organizations (partner-wide template) — the policy applies to devices in every organization you manage. Use this for a baseline AV/EDR posture you want enforced everywhere without recreating the policy per customer.

In the Security Policy Editor, partner-level users see a Scope selector when creating a new policy — choose All organizations or This organization only. The selector only appears on create; ownership cannot change afterward.

Creating, editing, or deleting a partner-wide security policy requires a partner-level user with full access to every organization under the partner (not a user restricted to a subset of organizations). Users without that access can still see partner-wide policies but cannot modify or delete them.

Terminal window
# Create a policy
POST /security/policies
{
"name": "Standard Endpoint Policy",
"description": "Baseline security policy for all workstations",
"providerId": "windows_defender",
"scanSchedule": "weekly",
"realTimeProtection": true,
"autoQuarantine": true,
"severityThreshold": "medium",
"exclusions": ["C:\\Temp\\build"]
}

To create a partner-wide policy instead, add "ownerScope": "partner" to the request body — no orgId is needed, since the partner is derived from your login.

Setting Default Description
ownerScope organization organization (default) or partner. Create-only — cannot be changed by a later update
scanSchedule weekly Scheduled scan frequency: daily, weekly, monthly, or manual
realTimeProtection true Whether real-time protection should be enforced
autoQuarantine true Automatically quarantine threats at or above the severity threshold
severityThreshold medium Minimum severity to trigger auto-quarantine: low, medium, high, critical
exclusions [] File paths to exclude from scanning

All security endpoints require authentication and are scoped to organization, partner, or system roles.

Method Endpoint Description
GET /security/status List security status for all devices (filterable by provider, status, risk level, OS)
GET /security/status/:deviceId Get security status for a specific device
GET /security/threats List all detected threats (filterable by severity, status, category, provider, date range)
GET /security/threats/:deviceId List threats for a specific device
POST /security/threats/:id/quarantine Quarantine a detected threat
POST /security/threats/:id/remove Remove a detected threat
POST /security/threats/:id/restore Restore a quarantined threat
POST /security/scan/:deviceId Trigger an on-demand security scan
GET /security/scans/:deviceId List scan history for a device
POST /security/sweeps/preview Preview an IOC sweep: device count per organization, rule-set versions, skipped devices and a previewDigest. Writes nothing. Needs devices:execute
POST /security/sweeps Start an IOC sweep; the body is the preview request plus the previewDigest. Needs devices:execute. Errors: SWEEP_SCOPE_CHANGED, SWEEP_ALREADY_RUNNING, TOO_MANY_ACTIVE_SWEEPS, MFA_REQUIRED, RATE_LIMITED, SWEEP_TOO_LARGE, NO_ELIGIBLE_DEVICES, RULE_SET_NOT_FOUND, RULE_SET_NOT_PUBLISHED, ORG_OUT_OF_SCOPE, SITE_OUT_OF_SCOPE, DEVICE_OUT_OF_SCOPE
GET /security/sweeps List sweeps (filterable by state and orgId, paginated). Needs devices:read
GET /security/sweeps/:id Get one sweep with its progress. Needs devices:read
GET /security/sweeps/groups/:groupId Get every sweep of a group with the combined progress. Needs devices:read
POST /security/sweeps/:id/cancel Cancel a sweep; returns cancelledQueued, cancelledUndelivered and stillRunning. Needs devices:execute
POST /security/sweeps/groups/:groupId/cancel Cancel every sweep of a group. Needs devices:execute
GET /security/posture List security posture for all devices (filterable by score range, risk level)
GET /security/posture/:deviceId Get detailed posture for a specific device
GET /security/dashboard Get aggregated security dashboard data
GET /security/score-breakdown Get per-factor score breakdown
GET /security/trends Get posture score trend over time (7d, 30d, 90d)
GET /security/firewall List firewall status per device with profile details
GET /security/encryption List encryption status per device with volume details
GET /security/password-policy List password policy compliance per device
GET /security/admin-audit Audit local admin accounts across the fleet
GET /security/recommendations Get prioritized security recommendations
POST /security/recommendations/:id/complete Mark a recommendation as completed
POST /security/recommendations/:id/dismiss Dismiss a recommendation
GET /security/policies List security policies for the organization. Partner-scoped tokens also see their own partner-wide policies
POST /security/policies Create a new security policy. Accepts ownerScope: "organization" (default) or "partner"
PUT /security/policies/:id Update an existing security policy. Does not accept ownerScope — ownership is immutable. Updating a partner-wide policy requires full partner org access

The agent could not detect a known AV provider. Common causes:

  • Windows: The AV product is not registered with Windows Security Center. This can happen with server-only installations or EDR tools that do not register as AV. The agent will still attempt to query Defender directly as a fallback.
  • macOS: The agent detects only CylancePROTECT / Aurora Endpoint Defense and Microsoft Defender for Endpoint on macOS. For Defender, check that the mdatp CLI is in PATH (which mdatp) and the app bundle exists at /Applications/Microsoft Defender.app. For Cylance, check that /Applications/Cylance/CylanceUI.app or /Library/LaunchDaemons/com.cylance.agent_service.plist exists.
  • Linux: The agent does not currently detect Linux AV providers. The provider will always be other on Linux endpoints.

The agent failed to query the encryption subsystem. Check:

  • Windows: Ensure the device has BitLocker support and the Get-BitLockerVolume cmdlet is available. Requires admin privileges.
  • macOS: Ensure fdesetup is accessible. The agent runs fdesetup status which requires appropriate permissions.
  • Linux: Ensure lsblk is installed. LUKS detection looks for crypt type entries in the block device tree.
  • Windows: The agent queries Get-NetFirewallProfile. If all three profiles (Domain, Private, Public) return False, the firewall is reported as disabled.
  • macOS: The agent checks socketfilterfw --getglobalstate first, then falls back to reading com.apple.alf preferences.
  • Linux: The agent checks ufw, firewall-cmd, and systemctl is-active firewalld in order. If none are available, firewall status cannot be determined.

The posture worker runs on an hourly schedule via BullMQ. If no posture data is available:

  1. Confirm the security posture worker is running (check logs for [SecurityPostureWorker] Security posture worker initialized).
  2. Verify the device has reported at least one SecurityStatus payload via heartbeat.
  3. Check that Redis is connected and the security-posture queue is processing jobs.
  • Verify the scan status is completed by checking GET /security/scans/:deviceId.
  • The agent’s built-in scanner uses a limited set of known signatures (EICAR, Mimikatz, CobaltStrike, Emotet, ransomware notes). It does not perform heuristic or behavioral analysis.
  • Files larger than 25 MB are skipped during scanning. Content pattern matching reads only the first 1 MB of each file.
  • Quarantine directories and system paths (e.g. /proc, /sys, WinSxS, $Recycle.Bin) are excluded by default.