Skip to content
ADscan Docs
ADscan PRO

Report Outputs

What's in the PDF, what's in the JSON, and how to use each in your workflow.

Output files

After a successful adscan ci --generate-report run:

~/.adscan/workspaces/<workspace>/
├── report.pdf              ← client-ready compliance report
└── technical_report.json   ← structured data for pipeline integration

ADscan also copies the PDF to ./artifacts/report.pdf in your current working directory.

The PDF

The PDF is designed to be handed directly to a client or board. It requires no editing.

Structure

SectionAudienceContent
Cover pageAllClient name, domain, date, ADscan PRO branding
Executive summaryCISO / boardRisk score, critical findings count, top attack paths, remediation priority
Attack pathsTechnicalFull exploitation chains from initial access to Domain Admin, with MITRE ATT&CK mapping
FindingsTechnicalPer-vulnerability: description, evidence, CVSS, remediation steps
Compliance mapperAuditorFramework-specific section (ISO 27001 / ENS / DORA / PCI DSS)
AppendixTechnicalRaw scan metadata, tool versions, scope

Compliance mapper (ISO 27001 example)

Each finding is mapped to the relevant ISO/IEC 27001:2022 Annex A control.

Example mapping:

FindingISO 27001 ControlStatus
Kerberoastable service accountsA.5.17 — Authentication information❌ Non-compliant
Unconstrained delegationA.8.2 — Privileged access rights❌ Non-compliant
Password never expires (DA)A.5.17 — Authentication information❌ Non-compliant
ADCS ESC1 templateA.8.3 — Information access restriction❌ Non-compliant

The compliance section includes:

  • Control reference + title
  • Finding linked to the control
  • Current status (compliant / non-compliant / not applicable)
  • Remediation recommendation specific to the control

Themes

ThemeBest for
premium_darkPentest firms, technical audiences, modern look
corporate_lightEnterprise clients, compliance auditors, printable

Set with --report-theme premium_dark or --report-theme corporate_light.

The JSON

The JSON is structured for programmatic consumption — designed to be parsed and ingested into your own reporting pipeline.

Top-level structure

{
  "metadata": { ... },
  "summary": { ... },
  "findings": [ ... ],
  "attack_paths": [ ... ],
  "compliance": { ... }
}

metadata

{
  "domain": "corp.example.com",
  "dc_ip": "10.10.10.10",
  "scan_date": "2026-04-26T10:42:00Z",
  "adscan_version": "8.0.0",
  "frameworks": ["iso27001"],
  "display_name": "Acme Corp"
}

summary

{
  "risk_score": 87,
  "critical": 3,
  "high": 7,
  "medium": 12,
  "low": 4,
  "attack_paths_count": 5,
  "domain_admin_paths": 2
}

findings[]

Each finding entry:

{
  "key": "kerberoast",
  "title": "Kerberoastable Service Accounts",
  "severity": "high",
  "cvss": 7.5,
  "description": "...",
  "evidence": { "affected_accounts": ["svc_sql", "svc_iis"] },
  "remediation": "...",
  "mitre": {
    "technique_id": "T1558.003",
    "technique_name": "Steal or Forge Kerberos Tickets: Kerberoasting"
  },
  "compliance": {
    "iso27001": {
      "control_id": "A.5.17",
      "control_title": "Authentication information",
      "status": "non_compliant"
    }
  }
}

attack_paths[]

{
  "id": "path_001",
  "tier": "tier0",
  "steps": [
    { "step": "kerberoast", "from": "low_priv_user", "to": "svc_sql" },
    { "step": "dcsync", "from": "svc_sql", "to": "DOMAIN\\Administrator" }
  ],
  "total_steps": 2,
  "exploited": true
}

compliance

{
  "iso27001": {
    "overall_status": "non_compliant",
    "controls_evaluated": 12,
    "controls_failed": 5,
    "controls_passed": 7,
    "findings_by_control": { ... }
  }
}

Using the JSON in your pipeline

The JSON is stable across ADscan PRO versions. Fields are additive (new fields may appear, existing fields are not removed).

Common integrations:

import json

with open("technical_report.json") as f:
    report = json.load(f)

# Extract all critical + high findings
critical_findings = [
    f for f in report["findings"]
    if f["severity"] in ("critical", "high")
]

# Extract time saved estimate
scan_date = report["metadata"]["scan_date"]
domain = report["metadata"]["domain"]

Feedback on the JSON schema

If you need a field that's not there, or a different structure for a specific section, let us know. The JSON schema is actively shaped by partner feedback during the beta.

Find this useful?
Pass it to the next pentester running an AD engagement
Running 2+ AD engagements/year?
Get PRO free — beta access·Free in exchange for feedback
Automated PDF reports. Save ≥1 day per engagement.

ADscan — AD pentest automation for security consultants

Report Outputs | ADscan