Documentation
Quickstart
ACYRA_Scan ships as a Python package with a Typer CLI and a FastAPI REST API. Everything below assumes an installed environment on Kali (or the bundled Docker image).
Install
Scanner binaries (nmap, nuclei, subfinder, httpx, …) should be on PATH. On Kali most already are.
bash
python3 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" cp .env.example .env # add API keys (all optional)
CLI
bash
acyra catalog # list tools, integrations, skills acyra scan example.com --skill full_scan --authorized acyra scan 192.0.2.0/28 --skill network_recon --authorized -o json acyra scan example.com -s osint --authorized --save acyra scans # list persisted scans acyra report <scan_id> # show a persisted scan acyra serve # start the REST API
Targets accept any mix of single IP, CIDR, range (10.0.0.1-50), domain or URL.
REST API
Start with acyra serve — docs at /docs. Auth is via the X-API-Key header.
| POST | /scans | Start a scan (background job) → 202 + scan_id |
| GET | /scans | List scans (scoped to your client) |
| GET | /scans/{id} | Full result: assets + findings |
| GET | /scans/{id}/summary | Counts + severity breakdown |
| GET | /scans/{id}/findings | Findings for one scan (min_severity) |
| GET | /findings | Cross-scan finding search (SQL-indexed) |
| GET | /assets | Cross-scan asset inventory (kind, q, source) |
| GET | /catalog | All tools / integrations / skills |
| GET | /usage | Your plan + this month's scan usage |
| POST | /me/keys | Generate a personal API key (shown once) |
| POST | /auth/login | Email + password → session cookie |
| POST | /admin/invites | Invite a user (admin / org-admin) |
| GET | /admin/access-requests | Review onboarding requests (admin) |
| PUT | /admin/webhook | Configure scan-complete webhook |
| GET | /admin/audit | Audit trail (admin) |
start a scan
curl -X POST localhost:8000/scans \
-H 'X-API-Key: <key>' -H 'Content-Type: application/json' \
-d '{"targets":["example.com","192.0.2.0/28"],
"skills":["full_scan"],"authorized":true}'Auth & tenancy
admin — manages tenants & keys, sees everythingoperator — run + read own client's scansviewer — read-only, own client
Each client carries its own scope allow/deny list. An operator key can only scan targets inside its client's authorized scope — an out-of-scope target is rejected with 403 before any packet is sent. Keys look like acyra_<prefix>_<secret> and are shown once at creation.
Embedding
python
import asyncio
from acyra import run_scan
async def main():
result = await run_scan(["client.example.com"], ["full_scan"], scan_id="job-123")
print(result.summary())
for f in result.findings:
if f.severity.rank >= 3: # high / critical
print(f.severity.value, f.source, f.title, f.cve)
asyncio.run(main())