adscan ci
Run a full ADscan assessment unattended — no prompts, safe defaults, one exit code.
adscan ci runs the complete scan pipeline with no prompts. Every question that the interactive shell would ask resolves to a documented default, so the run either finishes or fails — it never sits waiting on stdin.
This is the entry point automation uses. The Enterprise appliance's worker and the ADscan platform both drive scans by shelling out to adscan ci; it is the same engine adscan start runs, with the operator decisions pre-resolved.
Stability
The scan itself is the same code path as an interactive run. What is still settling is the surface around it: defaults, flag names and the shape of the console output can change between releases. Pin a version if you are wiring it into a pipeline you cannot babysit.
Usage
adscan ci {auth|unauth} --type {ctf|audit} --interface IFACE [options]The launcher forwards everything after ci to the runtime inside the container, so adscan ci --help shows the full argument list from the runtime itself.
Required arguments
| Argument | Values | Notes |
|---|---|---|
mode (positional) | auth, unauth | Authenticated or unauthenticated scan. |
--type, -t | ctf, audit | Engagement type. This is not cosmetic — see What --type changes. |
--interface, -i | e.g. eth0, tun0 | The interface ADscan scans from. |
Then, depending on mode:
authneeds--domain,--dc-ip,--usernameand--password.unauthneeds--hosts(a CIDR or range), or--dc-ipto target a known DC and skip host discovery.
# Unauthenticated, against a known DC
adscan ci unauth --type audit --interface eth0 --dc-ip 10.0.0.1
# Authenticated
adscan ci auth --type audit --interface eth0 \
--domain corp.local --dc-ip 10.0.0.1 \
-u alice -p 'S3cr3t!'--password accepts an NT hash as well as a cleartext password.
Segmented networks: a separate DNS server
On a segmented network the AD-zone DNS server is sometimes a different host from the domain controller. --dns-server IP covers that case: the DNS server resolves the domain zone, hostnames, and SRV records, while --dc-ip stays the authentication and enumeration target.
adscan ci unauth --type audit --interface eth0 \
--dc-ip 10.0.0.1 --dns-server 10.0.9.53The flag feeds only name resolution, including the Kerberos SPN lookup that keeps a scan on Kerberos instead of degrading to NTLM when a target only has an IP. When you omit it, ADscan resolves against --dc-ip exactly as before.
When a scan starts from a host range instead of a known DC and the controller does not answer DNS on port 53, ADscan detects a separate DNS server on the range on its own, and an unattended run adopts it only when it is the single such host and it actually resolves the domain zone. You do not need to pass --dns-server in that case unless you want to name the resolver explicitly.
What --type changes
| Value | Behaviour |
|---|---|
audit | The full pass. Every check runs, the finding set stays complete, and the exposure report is written automatically at the end of the scan. |
ctf | Stops once the domain is compromised, and adds the lab-oriented steps (flag collection). No report is written unless you ask for one. |
Use audit for anything you will report on. A ctf run exits early by design, so its finding set is sparse.
The report
An audit run writes the exposure report on its own — HTML and PDF, into the workspace, with no flag. See The exposure report.
--generate-report is the PRO flag: it renders the Client Deliverable Kit through the same engine adscan deliver uses, inline at the end of the run.
| Flag | Default | Effect |
|---|---|---|
--generate-report | off | Render the deliverable after a successful scan. Requires PRO. |
--only LIST | report | Which deliverables to render. CI stays report-only by default so the platform does not double-generate the full kit. Pass e.g. report,playbook to widen it. |
--frameworks LIST | none | ens, nis2, iso27001, dora, pci_dss — comma-separated. Nothing is selected unless you ask. |
--report-theme | none | premium_dark or corporate_light. |
--report-format | pdf | Only pdf is supported. |
--report-engine | chromium | Only chromium is supported. |
--report-renderer | cytoscape | Attack-path renderer. |
--report-template | premium | Only premium is supported. |
--display-name NAME | — | Client-facing name on the report cover. |
--client-logo PATH | — | Client logo (PNG/SVG/JPG) beside the ADscan mark on the report cover. Saved to config and reused on later runs. |
`--frameworks` selects nothing by default
An unattended run has no prompt to fall back on, so a kit rendered without --frameworks carries no compliance mapping at all. Name the regimes the client actually needs.
--client-logo co-brands the cover with the client's logo beside the ADscan mark. It works on the exposure report an audit run writes on its own — so a LITE run co-brands with adscan ci --client-logo — as well as the PRO kit. It takes a PNG, SVG or JPG and is saved for later runs. Keeping the ADscan mark is the free behaviour; removing it for a fully white-labelled report is a paid capability.
Workspace
| Flag | Effect |
|---|---|
--workspace NAME, -w | Name the workspace. A random name is generated when omitted. |
--keep-workspace | Keep an auto-created workspace after the run. Without it, a workspace ci created is deleted when the scan ends. |
Keep the workspace if you intend to re-render deliverables later with adscan deliver, or to re-run a single path with adscan execute — both read data a scan already collected.
Output and diagnostics
| Flag | Effect |
|---|---|
--show-structural | Show the structural band in the Tactical Findings panel (hidden by default). |
-v, --verbose | Verbose output. |
-d, --debug | Debug output. Floods the console; the workspace debug log is written at DEBUG regardless. |
Artifacts land in the workspace, not the working directory:
~/.adscan/workspaces/<workspace>/
├── technical_report.json
├── adscan_exposure_report_<timestamp>.html
├── adscan_exposure_report_<timestamp>.pdf
├── domains/<domain>/attack_graph.json
└── logs/adscan.debug.logUnder GitHub Actions (GITHUB_ACTIONS=true) the generated report is additionally copied into ./artifacts/ in the working directory, so a workflow can upload it without knowing the workspace path. Nothing is copied there on a normal run.
Exit codes
| Code | Meaning |
|---|---|
0 | The scan completed. |
1 | The scan failed. |
2 | The scan completed but CTF flag validation did not pass. |
Behaviour that differs from an interactive run
- Prompts resolve to defaults. Every confirmation and selector answers itself with the conservative option and logs what it chose.
- Spray selection is deterministic. ADscan walks the priority order (user-as-password, then owned-credential reuse, then blank), skips anything already covered or with no eligible accounts, and stops. It cannot loop.
- Live dashboards collapse to plain lines.
cimarks itself non-interactive, so the Rich live surfaces fall back to inline logging instead of writing alt-screen escapes into a captured log. - The two optional telemetry questions never appear.
Launcher flags
These are consumed by the launcher on the host rather than forwarded to the scan, and appear in adscan --help:
adscan ci unauth --type audit --interface eth0 --dc-ip 10.0.0.1 \
--offline # refuse every outbound connection
--no-telemetry # keep the run local--pull-timeout, --scan-config and --allow-low-memory are also launcher-side.
Related
- Scanning commands — what each phase does.
- execute & doctor — run one verb, or check the environment before committing to a scan.
- adscan deliver — render the deliverable kit from a workspace
cikept.