Evidence Schema
Draft v0.1
This schema is in draft. Fields marked [ACES] are additions the standard introduces on top of what current implementations store. All other fields reflect observed reality across production CSC/MCP connector deployments.
Evidence Object Schema
{
"$schema": "https://aces.compliancescorecard.com/schema/v0.1/evidence-object.json",
"aces_version": "0.1",
"id": "string (ULID)",
"collected_at": "string (ISO 8601)",
"tenant": {
"company_id": "string — MSP/top-level tenant identifier",
"client_id": "string — end-client identifier within MSP"
},
"connector": {
"connector_type_id": "string — slug of connector type (e.g. 'huntress', 'sentinelone')",
"security_connector_id": "string — instance ID of configured connector",
"collection_method": "string — e.g. 'collectAll', 'collectAgentStatus'",
"last_sync_at": "string (ISO 8601)",
"last_sync_status": "pending | in_progress | success | failed | partial",
"api_calls_made": "number (optional)",
"collection_duration_ms": "number (optional)"
},
"evidence_type": "string (free-form — see Evidence Types for conventions)",
"description": "string [ACES] — human-readable summary",
"location": {
"evidence_location": "string — URL or file path",
"evidence_location_type": "file_path | text",
"upload_source": "onedrive | sharepoint | sharepoint-gcc | googledrive | local | auto_generated",
"cloud_file_id": "string (optional)",
"cloud_file_url": "string (optional)"
},
"integrity": {
"file_name": "string",
"original_file_name": "string",
"file_size": "number (bytes)",
"mime_type": "string",
"hash_value": "string",
"hash_algorithm": "SHA256 | SHA512 | MD5",
"file_uploaded_at": "string (ISO 8601)",
"hash_generated_at": "string (ISO 8601)",
"is_tampered": "boolean",
"last_integrity_check": "string (ISO 8601)",
"verified_at": "string (ISO 8601, optional)",
"verified_by": "string (user ID, optional)",
"verification_notes": "string (optional)"
},
"responsibility": {
"responsibility": "msp | company | shared | tool",
"srm": "msp | client | shared",
"msp_responsibility_note": "string (optional)",
"company_responsibility_note": "string (optional)",
"shared_responsibility_note": "string (optional)",
"control_owner_id": "string (user ID, optional)",
"vendor": "string (optional — third-party tool name)",
"tool": "string (optional — tool satisfying this control)"
},
"conformity": {
"auditor_notes": "string (optional)",
"auditor_conformity_mark": "met | not met | null",
"implementation_statement": "string (optional)",
"policy_statement": "string (optional)",
"procedure_statement": "string (optional)",
"question_notes": "string (optional)"
},
"control_mappings": [
{
"framework": "string — framework key (e.g. 'cmmc-level2', 'cis-v8')",
"control": "string — control text or identifier",
"control_id": "string — machine-readable ID (e.g. 'AC.L2-3.1.2')",
"control_objective_id": "string (optional)",
"control_objective_item": "string (optional)",
"category": "string (optional — e.g. 'Access Control')",
"subcategory": "string (optional)"
}
],
"scoring": {
"sprs_score": "number — CMMC SPRS weight: 1, 3, or 5",
"sprs_value": "number — SPRS numeric contribution",
"assessment_methods": {
"examine": "string (optional — NIST 800-171A examine method)",
"interview": "string (optional — NIST 800-171A interview method)",
"test": "string (optional — NIST 800-171A test method)"
},
"scoring_instructions": "string (optional)"
},
"metrics": [
{
"category": "string — e.g. 'Endpoint Protection', 'access_control'",
"metric_key": "string — e.g. 'mfa_enrollment_percent'",
"metric_value": "string — always string, even for numbers",
"metric_type": "number | percentage | boolean | count | duration | datetime | json | string",
"unit": "string (optional — e.g. '%', 'days', 'devices', 'hours')"
}
],
"metadata": {
"tags": ["string"],
"notes": "string (optional)",
"expires_at": "string (ISO 8601, optional)",
"evidence_metadata": "object (optional — arbitrary key-value, tool-specific)"
}
}
Field Reference
Top-Level Fields
| Field | Type | ACES? | Description |
aces_version | string | [ACES] | Spec version (e.g., "0.1") |
id | string | — | Unique identifier (ULID recommended) |
collected_at | string | — | ISO 8601 timestamp when evidence was collected |
tenant | object | — | Two-level tenant identity (see below) |
connector | object | — | Connector instance that produced this evidence |
evidence_type | string | — | Free-form category string (see conventions below) |
description | string | [ACES] | Human-readable summary |
location | object | — | Where the evidence lives (file, URL, cloud) |
integrity | object | — | File hash and tamper-detection fields |
responsibility | object | — | RACI / SRM assignment |
conformity | object | — | Auditor fields and implementation statements |
control_mappings | array | — | Links to framework controls |
scoring | object | — | SPRS and assessment method fields |
metrics | array | — | N metric rows produced by this evidence collection |
metadata | object | [ACES] | Tags, notes, expiry |
tenant Object
| Field | Type | Description |
company_id | string | MSP / top-level tenant ID |
client_id | string | End-client ID within MSP |
Two-Level Tenancy
Real-world MSP deployments have two tenant levels. tenant_id alone (as in the original draft) is insufficient. Both company_id and client_id are required to uniquely scope evidence.
connector Object
| Field | Type | Required | Description |
connector_type_id | string | Yes | Slug of the connector type (e.g. huntress) |
security_connector_id | string | Yes | Configured instance ID |
collection_method | string | No | Which collection function ran |
last_sync_at | string | No | ISO 8601 last successful sync |
last_sync_status | enum | No | pending \| in_progress \| success \| failed \| partial |
api_calls_made | number | No | Count of API calls during collection |
collection_duration_ms | number | No | Wall-clock collection time in milliseconds |
location Object
| Field | Type | Values | Description |
evidence_location | string | any | URL or file path string |
evidence_location_type | enum | file_path \| text | Distinguishes file evidence from text/URL evidence |
upload_source | enum | see below | Provenance of uploaded evidence |
cloud_file_id | string | — | Provider-assigned file ID (OneDrive/GDrive) |
cloud_file_url | string | — | Direct URL to cloud-hosted file |
upload_source values: onedrive, sharepoint, sharepoint-gcc, googledrive, local, auto_generated
integrity Object
| Field | Type | Description |
file_name | string | Stored filename |
original_file_name | string | Original upload filename |
file_size | number | File size in bytes |
mime_type | string | MIME type (e.g. application/pdf) |
hash_value | string | Hash of file contents (up to 128 chars) |
hash_algorithm | enum | SHA256 \| SHA512 \| MD5 (default: SHA256) |
file_uploaded_at | string | ISO 8601 upload timestamp |
hash_generated_at | string | ISO 8601 hash generation timestamp |
is_tampered | boolean | True if tamper detected since upload |
last_integrity_check | string | ISO 8601 timestamp of last integrity verification |
verified_at | string | ISO 8601 when a human verified this evidence |
verified_by | string | User ID of verifier |
verification_notes | string | Verifier notes |
responsibility Object (RACI / SRM)
| Field | Type | Values | Description |
responsibility | enum | msp \| company \| shared \| tool | Who is responsible for satisfying this control |
srm | string | msp \| client \| shared | Shared Responsibility Model assignment |
msp_responsibility_note | text | — | MSP-specific responsibility note |
company_responsibility_note | text | — | Company-specific note |
shared_responsibility_note | text | — | Shared responsibility details |
control_owner_id | string | — | User ID of control owner |
vendor | string | — | Third-party vendor satisfying this control |
tool | string | — | Tool (product name) satisfying this control |
| Field | Type | Values | Description |
auditor_notes | text | — | Third-party auditor observations |
auditor_conformity_mark | string | met \| not met \| null | Auditor determination of conformity |
implementation_statement | text | — | How the control is implemented |
policy_statement | text | — | Relevant policy reference or text |
procedure_statement | text | — | Relevant procedure reference or text |
question_notes | text | — | Assessor notes on this control question |
control_mappings Array
| Field | Type | Required | Description |
framework | string | Yes | Framework key (e.g. cmmc-level2, cis-v8) |
control | string | Yes | Control text or display name |
control_id | string | No | Machine-readable ID (e.g. AC.L2-3.1.2) |
control_objective_id | string | No | Control objective identifier |
control_objective_item | string | No | Specific objective item text |
category | string | No | Domain/category (e.g. Access Control) |
subcategory | string | No | Sub-domain or practice group |
scoring Object
| Field | Type | Description |
sprs_score | number | CMMC SPRS weight assigned to this control: 1, 3, or 5 |
sprs_value | number | SPRS numeric point contribution (DoD methodology, 110-point base) |
examine | string | NIST 800-171A examine assessment method description |
interview | string | NIST 800-171A interview assessment method description |
test | string | NIST 800-171A test assessment method description |
scoring_instructions | string | Human-readable scoring guidance for assessors |
SPRS Scoring
SPRS (Supplier Performance Risk System) scoring applies to CMMC/NIST 800-171 assessments only. Weights of 1, 3, and 5 are assigned per DoD methodology. Non-CMMC evidence should omit sprs_score and sprs_value.
metrics Array
Each element is one normalized metric row from a connector collection. A single evidence collection typically produces N metric rows — one per measurement.
| Field | Type | Required | Description |
category | string | Yes | Metric grouping (e.g. Endpoint Protection, access_control) |
metric_key | string | Yes | Metric identifier (e.g. mfa_enrollment_percent) |
metric_value | string | Yes | Always stored as string — parse using metric_type |
metric_type | string | Yes | Value type — see Metric Types |
unit | string | No | Display unit (e.g. %, days, devices, hours) |
metric_value is always string
All connector implementations normalize metric values to strings before storage. Consumers must cast to the appropriate type using metric_type. This preserves JSON interoperability across connectors with heterogeneous outputs.
Evidence Types
evidence_type is stored as a free-form string. The following conventions are observed across production connectors:
| Convention | Source Connectors | Notes |
endpoint_protection | sentinelone, huntress | EDR coverage and health |
patch_management | ninjarmm, ncentral | Patch compliance |
access_control | msgraph (access_control category) | MFA, conditional access |
vulnerability_scan | connectsecure, nodeware, sentinelone | CVE data |
configuration_baseline | senteon, connectsecure | CIS benchmark compliance |
network_monitoring | auvik, liongard | Asset/network inventory |
security_awareness_training | breachsecurenow, cyberhoot, phin, symbol | SAT completion |
phishing_simulation | breachsecurenow, cyberhoot, phin, symbol | Phishing campaign data |
application_control | threatlocker | Application allow/deny |
identity_management | msgraph (identity category) | User/license inventory |
audit_logging | msgraph (audit category) | Log retention and access |
domain_security | domainscanner | DNS, SSL, email auth |
Framework Keys
Observed in production codebase:
| Key | Framework |
nist-csf | NIST Cybersecurity Framework |
nist-800-171 | NIST SP 800-171 |
cmmc-level1 / cmmc-level2 | CMMC 2.0 |
soc-2 | SOC 2 Trust Services Criteria |
iso-27001 | ISO/IEC 27001 |
pci-dss | PCI DSS |
hipaa | HIPAA Security Rule |
gdpr | GDPR |
cis-v8 | CIS Controls v8 |
ftc-safeguards | FTC Safeguards Rule |
| Framework | Format | Example |
| CMMC / NIST 800-171 | {Domain}.{Level}-{NistNumber} | AC.L2-3.1.2 |
| CIS Controls v8 | {Control}.{Safeguard} | 10.1 |
| NIST CSF 2.0 | {Function}.{Category}-{Subcategory} | DE.CM-04 |
ACES Additions vs Reality
Fields marked [ACES] are introduced by this standard and are not present in current CSC implementations. All other fields are grounded in observed production schema.
| Field | Status | Rationale |
aces_version | [ACES] | Schema versioning for evolution |
description | [ACES] | Canonical summary field (maps loosely to explanation in CSC) |
metadata.tags | [ACES] | Structured tagging (CSC has unstructured evidence_metadata json) |
metadata.expires_at | [ACES] | Evidence expiry for time-limited certifications |
control_mappings[].framework as canonical key | [ACES] | CSC uses mixed format; ACES standardizes to slug |