Metric Types¶
Draft v0.1
This page is in draft. Content may change before v1.0.
Every metric row produced by an ACES-compliant connector includes a metric_type field that declares how to interpret metric_value. Because metric_value is always stored as a string, consumers must use metric_type to cast it correctly.
See also: Evidence Schema → metrics array
Type Reference¶
number¶
A numeric measurement. Cast metric_value to float or integer.
Unit examples: devices, policies, users, licenses, checks, segments, versions
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| auvik | total_devices | "142" |
| huntress | agents_total | "87" |
| sentinelone | active_threats_count | "3" |
| connectsecure | total_vulns | "412" |
| ninjarmm | patches_pending | "24" |
| msgraph | total_users_licensed | "55" |
| threatlocker | total_devices | "98" |
percentage¶
A ratio expressed as a value between 0 and 100. Always paired with unit: "%". Cast metric_value to float.
Unit examples: %, percent
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| huntress | agents_online_percentage | "97.7" |
| sentinelone | agent_coverage_pct | "94.2" |
| connectsecure | compliance_score_percent | "78.5" |
| ninjarmm | patch_compliance_percent | "85.0" |
| msgraph | mfa_enrollment_percent | "100.0" |
| breachsecurenow | training_completion_pct | "72.3" |
| threatlocker | denial_rate_percent | "12.4" |
| liongard | agent_health_pct | "91.6" |
| auvik | network_coverage_pct | "100.0" |
boolean¶
A true/false state. metric_value will be "true" or "false" (string). Cast to boolean.
Unit examples: none
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| msgraph | audit_log_enabled | "true" |
| msgraph | legacy_auth_blocked | "false" |
| msgraph | mfa_required_by_policy | "true" |
| msgraph | mailbox_auditing_enabled | "true" |
| msgraph | devices_api_accessible | "true" |
| msgraph | location_restrictions_enabled | "false" |
count¶
A discrete integer count. Semantically distinct from number — use count when the value represents a tally of discrete events or items (incidents, denied actions, alerts). Cast to integer.
Unit examples: incidents, actions, alerts, requests, events
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| huntress | incidents_critical | "2" |
| huntress | incidents_auto_resolved | "14" |
| sentinelone | threats_by_severity_critical | "1" |
| sentinelone | cve_critical_count | "7" |
| threatlocker | total_denied_actions | "1842" |
| threatlocker | pending_approvals | "3" |
| liongard | active_alert_count | "0" |
duration¶
A time span. metric_value is a numeric string representing the duration in the unit specified. Cast to float.
Unit examples: hours, minutes, seconds, ms, days
Connector examples:
| Connector | metric_key | Unit | Example value |
|---|---|---|---|
| huntress | mean_time_to_detect_hours | hours | "4.2" |
| huntress | mean_time_to_resolve_hours | hours | "18.5" |
| sentinelone | avg_threat_resolution_hours | hours | "6.1" |
| sentinelone | collection_duration_ms | ms | "2341" |
| msgraph | audit_log_retention_days | days | "90" |
datetime¶
An ISO 8601 timestamp string. metric_value is a timestamp — do not cast to a number. Parse as datetime.
Unit examples: none
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| auvik | last_scan_date | "2026-03-21T14:32:00Z" |
| nodeware | last_scan_date | "2026-03-20T09:15:00Z" |
| msgraph | last_audit_event_at | "2026-03-22T00:00:00Z" |
| msgraph | last_exchange_audit_at | "2026-03-21T18:00:00Z" |
| msgraph | latest_alert_at | "2026-03-22T06:12:00Z" |
| sentinelone | last_collection_at | "2026-03-22T12:00:00Z" |
| breachsecurenow | last_campaign_date | "2026-03-01" |
json¶
A structured object or array, serialized as a JSON string inside metric_value. Parse metric_value with JSON.parse() before use.
Unit examples: none
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| msgraph | license_types | "{\"M365 Business Premium\": 42, \"E3\": 13}" |
| msgraph | severity_distribution | "{\"high\": 2, \"medium\": 5, \"low\": 1}" |
| msgraph | os_distribution | "{\"Windows 11\": 80, \"Windows 10\": 18, \"macOS\": 4}" |
| msgraph | device_type_distribution | "{\"laptop\": 85, \"desktop\": 17}" |
| auvik | device_types_breakdown | "{\"router\": 4, \"switch\": 12, \"workstation\": 98}" |
string¶
A plain text value that does not fit another type. Use for grades, status strings, identifiers, and human-readable labels.
Unit examples: none
Connector examples:
| Connector | metric_key | Example value |
|---|---|---|
| domainscanner | overall_grade | "B+" |
| domainscanner | dns_security_status | "pass" |
| domainscanner | domain | "acme-corp.com" |
| auvik | last_scan_date | "2026-03-21" (when no time component) |
| msgraph | mfa_evidence_source | "Microsoft Graph API" |
| sentinelone | alerts_evidence_source | "SentinelOne Management Console" |
| threatlocker | agent_versions_unique | "3" (distinct version count as label) |
Type Selection Guide¶
| Question | Answer → Type |
|---|---|
| Is it a ratio of total? (X out of Y) | percentage |
| Is it a tally of discrete events? | count |
| Is it a continuous measurement (size, quantity)? | number |
| Is it true or false? | boolean |
| Is it a time span? | duration |
| Is it a point in time? | datetime |
| Is it a structured object/array? | json |
| Doesn't fit any above? | string |
Implementation Notes¶
-
Always store as string.
metric_valuemust be a string in all serialized forms, regardless of the underlying type. This is a deliberate design decision to support heterogeneous connector outputs in a single table. -
Type is authoritative. Consumers must not infer type from value shape. A value of
"1"could be anumber,count, orboolean— always checkmetric_type. -
Unit is display-only. The
unitfield is for human display purposes. It does not affect howmetric_valueshould be parsed. Parsing is always governed bymetric_type. -
No nested types.
metric_typeis always a single scalar type. Usejsonfor complex structures — do not nest ACES metric rows.