Import from Security Tools
Build a pipeline that pulls data from your existing RMM, SIEM, or GRC tooling and pre-populates your SCH assessments — without sending sensitive asset data to any third-party service.
How it works
Pull from your tool
Write a script on your own infrastructure that authenticates with your security tool's API and extracts the relevant data. Your API credentials never leave your environment.
Map to the schema
Transform the raw data into the SCH pre-fill JSON format. Your script applies the thresholds and decides whether a control is pass, partial, or fail.
Import & review
Upload the JSON file in your SCH assessment. Answers are pre-populated for review. You confirm or override each one before running Phronesis analysis.
Privacy boundary: The evidence_summary field is the only field that may reach the Phronesis AI Service. It must contain only aggregated, identifier-free text — no hostnames, IP addresses, device names, or usernames. Use evidence_detail and raw_stats for sensitive specifics — these are stored in the Evidence Vault (GCS) and are never transmitted to Phronesis.
Schema reference
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "ce" |
| generated | Required | ISO 8601 datetime — used to warn if data is stale |
| source | Optional | Free-text identifier for your pipeline (e.g. "ninjone") |
| questions | Required | Object keyed by radio name (e.g. q3_1). Each entry contains the fields below. |
| → suggested_value | Required |
Radio answer to pre-fill.
pass
fail
unsure
|
| → evidence_summary | Optional | Aggregated, identifier-free summary. Max 500 chars. May reach Phronesis. No hostnames or IPs. |
| → evidence_detail | Vault only | Detailed evidence with identifiers. Stored in Evidence Vault. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats object. Stored in Evidence Vault. Never sent to Phronesis. |
Example
// ce-prefill.json — generated by your NinjaOne transform script { "assessmentType": "ce", "source": "ninjone", "generated": "2026-05-13T09:00:00Z", "questions": { "q3_1": { "suggested_value": "pass", "evidence_summary": "Automated patching active; 142/142 devices patched within 14 days" }, "q3_2": { "suggested_value": "fail", "evidence_summary": "87% of endpoints patched for high/critical within 14 days; 18 overdue", "evidence_detail": "Overdue: WS-042 (3 patches), WS-107 (1 patch) ...", "raw_stats": { "total": 142, "patched_14d": 124, "overdue": 18 } }, "q5_1": { "suggested_value": "pass", "evidence_summary": "AV active and updated on 142/142 managed endpoints" } } }
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "caf" |
| generated | Required | ISO 8601 datetime |
| source | Optional | Pipeline identifier |
| questions | Required | Object keyed by CAF radio name (pattern: caf_[A-D][0-9]+[a-z]?_[0-9]+) |
| → suggested_value | Required |
achieved
partial
not-achieved
na
|
| → evidence_summary | Optional | Aggregated summary. Max 500 chars. May reach Phronesis. |
| → evidence_detail | Vault only | Sensitive detail. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats. Never sent to Phronesis. |
Example
{
"assessmentType": "caf",
"source": "qualys",
"generated": "2026-05-13T09:00:00Z",
"questions": {
"caf_B3_1": {
"suggested_value": "partial",
"evidence_summary": "Patch management policy exists; 87% of systems patched within SLA"
},
"caf_C1a_1": {
"suggested_value": "partial",
"evidence_summary": "SIEM ingesting logs from 94% of assets; 6 assets pending onboarding",
"raw_stats": { "total_assets": 187, "siem_covered": 175 }
}
}
}
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "iso27001" |
| generated | Required | ISO 8601 datetime |
| source | Optional | Pipeline identifier |
| questions | Required | Object keyed by ISO radio name (pattern: iso_(CL[1-7]|AA)_[0-9]+) |
| → suggested_value | Required |
implemented
partial
not-implemented
na
|
| → evidence_summary | Optional | Aggregated summary. Max 500 chars. May reach Phronesis. |
| → evidence_detail | Vault only | Sensitive detail. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats. Never sent to Phronesis. |
Example
{
"assessmentType": "iso27001",
"source": "servicenow-grc",
"generated": "2026-05-13T09:00:00Z",
"questions": {
"iso_CL3_1": {
"suggested_value": "partial",
"evidence_summary": "Risk register exists; 23 open risks, 8 without treatment plans"
},
"iso_AA_4": {
"suggested_value": "partial",
"evidence_summary": "Access reviews completed for privileged accounts quarterly; standard users annually only",
"raw_stats": { "privileged_accounts": 47, "orphaned_accounts": 14 }
}
}
}
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "dora" |
| generated | Required | ISO 8601 datetime |
| source | Optional | Pipeline identifier |
| questions | Required | Object keyed by DORA radio name (pattern: dora_P[1-5]_[0-9]+) |
| → suggested_value | Required |
achieved
partial
not-achieved
na
|
| → evidence_summary | Optional | Aggregated summary. Max 500 chars. May reach Phronesis. |
| → evidence_detail | Vault only | Sensitive detail. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats. Never sent to Phronesis. |
Example
{
"assessmentType": "dora",
"source": "servicenow-itsm",
"generated": "2026-05-13T09:00:00Z",
"questions": {
"dora_P2_1": {
"suggested_value": "achieved",
"evidence_summary": "ICT incident classification policy documented; criteria align with DORA Article 18"
},
"dora_P2_3": {
"suggested_value": "partial",
"evidence_summary": "2 major incidents in past 12 months; 4-hour initial report SLA met on 1 of 2",
"raw_stats": { "major_incidents_12m": 2, "sla_met": 1 }
}
}
}
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "ai-governance" |
| generated | Required | ISO 8601 datetime |
| source | Optional | Pipeline identifier |
| questions | Required | Object keyed by AI Gov radio name (pattern: aig_D[1-6]_[0-9]+) |
| → suggested_value | Required |
achieved
partial
not-achieved
na
|
| → evidence_summary | Optional | Aggregated summary. Max 500 chars. May reach Phronesis. No model names or dataset paths. |
| → evidence_detail | Vault only | Sensitive MLOps detail. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats. Never sent to Phronesis. |
Example
{
"assessmentType": "ai-governance",
"source": "azure-ml",
"generated": "2026-05-13T09:00:00Z",
"questions": {
"aig_D3_1": {
"suggested_value": "achieved",
"evidence_summary": "Data catalogue maintained; 94% of AI training datasets catalogued with lineage and quality scores",
"raw_stats": { "total_datasets": 104, "catalogued": 98 }
},
"aig_D5_1": {
"suggested_value": "partial",
"evidence_summary": "Adversarial robustness testing completed for 6 of 9 production models"
}
}
}
Fields
| Field | Required | Description |
|---|---|---|
| assessmentType | Required | Must be "soc" |
| generated | Required | ISO 8601 datetime |
| source | Optional | Pipeline identifier |
| questions | Required | Object keyed by SOC radio name (pattern: soc_(G|T|P|Pr|S|TOM|AI)[0-9]+) |
| → suggested_value | Required |
fully-implemented
partially-implemented
not-implemented
na
|
| → evidence_summary | Optional | Aggregated summary. Max 500 chars. May reach Phronesis. No system names or analyst IDs. |
| → evidence_detail | Vault only | Sensitive SOC metrics. Never sent to Phronesis. |
| → raw_stats | Vault only | Machine-readable stats. Never sent to Phronesis. |
Example
{
"assessmentType": "soc",
"source": "splunk",
"generated": "2026-05-13T09:00:00Z",
"questions": {
"soc_G1": {
"suggested_value": "fully-implemented",
"evidence_summary": "SIEM deployed; ingesting from 100% of critical assets; avg detection-to-alert 4.2 min"
},
"soc_AI1": {
"suggested_value": "partially-implemented",
"evidence_summary": "SOAR deployed; 8 of 15 target playbooks automated; MTTR reduced 34% since deployment",
"raw_stats": { "playbooks_target": 15, "playbooks_live": 8, "mttr_reduction_pct": 34 }
}
}
}
Building your pipeline
These are illustrative examples showing the two-layer pattern. The extraction layer is reusable across assessments; only the mapping layer changes per framework.
🖥 NinjaOne → CE & CAF
# extract/ninjone.py def get_patch_status(api_key): devices = ninjone_api.get_devices() patched = [d for d in devices if d.days_since_patch <= 14] return { "total": len(devices), "patched_14d": len(patched), "overdue": len(devices) - len(patched) } # map/ce.py def map_updates(stats): pct = stats["patched_14d"] / stats["total"] return { "suggested_value": "pass" if pct >= 0.95 else "fail" if pct < 0.80 else "unsure", "evidence_summary": f"{pct:.0%} of endpoints patched " f"within 14 days" }
☁️ Splunk / Sentinel → SOC
# extract/splunk.py def get_detection_metrics(token): return splunk_api.run_search( "index=main sourcetype=alerts " "| stats avg(triage_mins) as mttr" ) # map/soc.py def map_siem(metrics): mttr = metrics["mttr"] return { "suggested_value": "fully-implemented" if mttr < 5 else "partially-implemented" if mttr < 15 else "not-implemented", "evidence_summary": f"SIEM deployed; avg detection-to-" f"alert {mttr:.1f} min" }
📋 ServiceNow → ISO 27001
# extract/servicenow.py def get_risk_register(instance, token): risks = snow_api.get_risks(instance) open_risks = [r for r in risks if r.state == "open"] no_treatment = [r for r in open_risks if not r.treatment_plan] return { "open": len(open_risks), "no_treatment": len(no_treatment) } # map/iso27001.py (iso_CL3_1) def map_risk_register(stats): gap = stats["no_treatment"] return { "suggested_value": "implemented" if gap == 0 else "partial" if gap <= 5 else "not-implemented", "evidence_summary": f"Risk register active; {stats['open']}" f" open risks, {gap} without treatment" }
⚡ Multi-assessment runner
# run.py — generate any assessment # python run.py --assessment ce \ # --output ce-prefill.json import argparse, json, datetime MAPPERS = { "ce": map_ce, "caf": map_caf, "iso27001": map_iso27001, "dora": map_dora, "soc": map_soc, "ai-governance": map_ai_gov, } def run(assessment, output): raw = extract_all() # shared extractors mapper = MAPPERS[assessment] result = { "assessmentType": assessment, "generated": datetime.datetime.utcnow() .isoformat() + "Z", "questions": mapper(raw) } json.dump(result, open(output, "w"))
Common questions
suggested_value and evidence_summary fields are used in the assessment. The evidence_detail and raw_stats fields are stored in the Evidence Vault (GCS) and are never sent to the Phronesis AI Service.suggested_value. SCH does not enforce thresholds — it accepts whatever label your script produces. The user reviews and can override any pre-filled answer before running analysis. This keeps compliance judgement with your organisation and assessor, not baked into the platform.questions object only needs to contain entries for the questions you want to pre-fill. Any question not included in the file is left blank for manual entry. You can pre-fill the technical controls from tooling and complete the governance/policy questions manually.python run.py --assessment caf) calls the shared extractors and the relevant mapper, producing the correct output file for whichever assessment you need.Ready to run your first import?
Download a schema, build your transform script, and pre-populate your assessment in minutes.