Security
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.
Admin IP Allowlist
Section titled “Admin IP Allowlist”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.
Security Status
Section titled “Security Status”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.
Collected Fields
Section titled “Collected Fields”| 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) |
Detection Methods by Platform
Section titled “Detection Methods by Platform”- AV detection: Windows Security Center (
root/SecurityCenter2) via CIM, with fallback toGet-MpComputerStatusfor Windows Server - Firewall:
Get-NetFirewallProfilequeries all three profiles (Domain, Private, Public) - Encryption:
Get-BitLockerVolumereads BitLocker protection status and encryption percentage per volume - Local admins:
Get-LocalGroupMember -Group 'Administrators'enumerates the local Administrators group - Password policy:
secedit /export /areas SECURITYPOLICYreads min length, complexity, max and min age, lockout threshold, and history count from the local security policy. If the export fails,NetUserModalsGet(whatnet accountsuses) supplies everything except complexity, which then shows as Unknown. A max age of 0 means passwords never expire, which fails the 90-day check
- AV detection: CylancePROTECT / Aurora Endpoint Defense via its app bundle (
/Applications/Cylance/CylanceUI.app) and launch daemon (com.cylance.agent_service), then Microsoft Defender for Endpoint viamdatp health --output json, with app bundle fallback. Cylance is attributed first; Defender takes the provider only when nothing else was found or when it is the only product with real-time protection on - Gatekeeper:
spctl --statuschecks Gatekeeper enforcement state - Firewall:
socketfilterfw --getglobalstateordefaults read com.apple.alf globalstate - Encryption:
fdesetup statusdetects FileVault state - Local admins:
dscl . -read /Groups/admin GroupMembershiplists admin group members - Password policy:
pwpolicy -getglobalpolicyparses min chars, complexity, lockout, and history
- Firewall: Checks
ufw status,firewall-cmd --state, andsystemctl is-active firewalldin order - Encryption:
lsblk -Jwalks the block device tree looking forcrypttype entries (LUKS) - Local admins:
getent group sudoorgetent group wheelenumerates privileged group members - Password policy: Parses
/etc/login.defsfor min length and max age, checks PAM modules for complexity, and reads/etc/security/faillock.conffor lockout threshold
Supported Providers
Section titled “Supported Providers”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.
The IOC Scans Page
Section titled “The IOC Scans Page”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.
Detection rules
Section titled “Detection rules”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.
Rule sets
Section titled “Rule sets”- 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.
- 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.
- 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.
Import IOCs
Section titled “Import IOCs”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.
Test a file
Section titled “Test a file”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.
Using rule sets in a policy
Section titled “Using rule sets in a policy”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.
Permissions
Section titled “Permissions”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.
IOC sweeps
Section titled “IOC sweeps”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.
What a sweep is
Section titled “What a sweep is”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.
Sweeps only detect
Section titled “Sweeps only detect”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.
Scope and eligibility
Section titled “Scope and eligibility”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.
Preview and confirmation
Section titled “Preview and confirmation”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.
Pinned rule versions
Section titled “Pinned rule versions”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.
Duration and offline devices
Section titled “Duration and offline devices”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.
Pacing
Section titled “Pacing”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
Section titled “Cancel”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.
Running it again
Section titled “Running it again”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.
Degraded coverage
Section titled “Degraded coverage”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.
AI assistant and MCP
Section titled “AI assistant and MCP”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.
Audit events
Section titled “Audit events”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.
Threat Detection
Section titled “Threat Detection”Threat Types and Severity
Section titled “Threat Types and Severity”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) |
Which rule fired
Section titled “Which rule fired”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.
Threat Status Lifecycle
Section titled “Threat Status Lifecycle”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 |
Threat Actions
Section titled “Threat Actions”You can take action on detected threats directly from the API:
# Quarantine a threat (moves file to quarantine directory)POST /security/threats/{threatId}/quarantine
# Permanently remove a threatPOST /security/threats/{threatId}/remove
# Restore a quarantined threat (mark as allowed)POST /security/threats/{threatId}/restoreEach 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 |
Security Scans
Section titled “Security Scans”Triggering a Scan
Section titled “Triggering a Scan”Initiate an on-demand security scan on a specific device by posting to the scan endpoint:
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.
Scan Lifecycle
Section titled “Scan Lifecycle”| 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 |
Viewing Scan History
Section titled “Viewing Scan History”GET /security/scans/{deviceId}?scanType=quick&status=completed&startDate=2026-02-01Returns paginated scan history for the device, filterable by scanType, status, and date range.
Compliance and Posture
Section titled “Compliance and Posture”Security Posture Scoring
Section titled “Security Posture Scoring”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 |
Risk Levels
Section titled “Risk Levels”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 |
Organization-Level Posture
Section titled “Organization-Level Posture”The posture worker runs hourly via BullMQ, computing scores for every device across all organizations. Organization-level snapshots aggregate:
devicesAudited– total devices scoredlowRiskDevices,mediumRiskDevices,highRiskDevices,criticalRiskDevices– risk distribution- Per-factor average scores
topIssues– most common compliance gaps
Password Policy Compliance
Section titled “Password Policy Compliance”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.
Admin Account Audit
Section titled “Admin Account Audit”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 |
Compliance Trend Tracking
Section titled “Compliance Trend Tracking”GET /security/trends?period=30dReturns 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).
Security Recommendations
Section titled “Security Recommendations”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.
How Recommendations Are Generated
Section titled “How Recommendations Are Generated”- The engine loads the latest posture snapshots for all devices in the organization.
- For each security factor, it counts devices scoring below the target threshold (e.g. AV health below 80, firewall below 90).
- If any devices are affected, a recommendation is generated with priority scaled to the percentage of the fleet impacted.
- Recommendations are sorted by priority (critical first), then by affected device count.
Recommendation Categories
Section titled “Recommendation Categories”| 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 Escalation
Section titled “Priority Escalation”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.
Recommendation Lifecycle
Section titled “Recommendation Lifecycle”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:
# Mark as completedPOST /security/recommendations/{id}/complete
# DismissPOST /security/recommendations/{id}/dismissSecurity Dashboard
Section titled “Security Dashboard”The dashboard endpoint aggregates all security data into a single response for rendering the security overview UI.
GET /security/dashboard?orgId={orgId}Dashboard Response Fields
Section titled “Dashboard Response Fields”| 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.
Score Breakdown
Section titled “Score Breakdown”For a detailed per-factor breakdown, use the score breakdown endpoint:
GET /security/score-breakdownReturns each posture component with its score, weight, status (good/warning/critical), and the count of affected devices below the threshold.
Disk Encryption & Recovery Keys
Section titled “Disk Encryption & Recovery Keys”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.
Encryption overview
Section titled “Encryption overview”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.
Recovery keys on a device
Section titled “Recovery keys on a device”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.
Recovery-key API
Section titled “Recovery-key API”# List escrowed recovery keys for a deviceGET /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 keyPOST /security/encryption/devices/:deviceId/recovery-keys/collect
# Request key rotationPOST /security/encryption/devices/:deviceId/recovery-keys/rotateSecurity Policies
Section titled “Security Policies”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.
# Create a policyPOST /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 |
API Reference
Section titled “API Reference”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 |
Troubleshooting
Section titled “Troubleshooting”Agent reports provider: "other"
Section titled “Agent reports provider: "other"”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
mdatpCLI is inPATH(which mdatp) and the app bundle exists at/Applications/Microsoft Defender.app. For Cylance, check that/Applications/Cylance/CylanceUI.appor/Library/LaunchDaemons/com.cylance.agent_service.plistexists. - Linux: The agent does not currently detect Linux AV providers. The provider will always be
otheron Linux endpoints.
Encryption status shows unknown
Section titled “Encryption status shows unknown”The agent failed to query the encryption subsystem. Check:
- Windows: Ensure the device has BitLocker support and the
Get-BitLockerVolumecmdlet is available. Requires admin privileges. - macOS: Ensure
fdesetupis accessible. The agent runsfdesetup statuswhich requires appropriate permissions. - Linux: Ensure
lsblkis installed. LUKS detection looks forcrypttype entries in the block device tree.
Firewall status not detected
Section titled “Firewall status not detected”- Windows: The agent queries
Get-NetFirewallProfile. If all three profiles (Domain, Private, Public) returnFalse, the firewall is reported as disabled. - macOS: The agent checks
socketfilterfw --getglobalstatefirst, then falls back to readingcom.apple.alfpreferences. - Linux: The agent checks
ufw,firewall-cmd, andsystemctl is-active firewalldin order. If none are available, firewall status cannot be determined.
Posture score is 0 or not available
Section titled “Posture score is 0 or not available”The posture worker runs on an hourly schedule via BullMQ. If no posture data is available:
- Confirm the security posture worker is running (check logs for
[SecurityPostureWorker] Security posture worker initialized). - Verify the device has reported at least one
SecurityStatuspayload via heartbeat. - Check that Redis is connected and the
security-posturequeue is processing jobs.
Threats not appearing after scan
Section titled “Threats not appearing after scan”- Verify the scan status is
completedby checkingGET /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.