Catch malicious software before you install it.

swaudit runs candidate applications in an instrumented sandbox, records what they actually do, and produces a defensible report that supports your approve / reject decision. Every finding traced to evidence. Every limit stated.

Scope, up front: when the candidate is an installer, swaudit audits the installer — everything it unpacks, writes, spawns and dials, up to the point Windows requires administrator rights. That is the window a hostile installer does its damage in. What the software does after it is installed is not audited today. What that covers, and what it doesn't →

How it works See what it observes

Windows candidates executed in a disposable VM · authenticated in-guest evidence collection · signed reports an approver can verify independently · launches EXE, MSI, PowerShell, HTA, WSF and Batch · SSO / RBAC / multi-tenant / Slack / Jira Β· all green in CI

Watch a real audit

One unedited session, recorded in the product: a disposable Windows VM is provisioned, the desktop streams into the browser, a candidate exfiltrates planted credentials, and the detectors catch it while it happens. No staging — the findings and the verdict below are the ones this run actually produced.

  1. A fresh sandbox is provisioned. Every audit gets its own single-use Windows VM; it is destroyed when the session ends.
  2. Instrumentation comes up. In-guest collection, TLS interception, and planted credentials — before the candidate is allowed to run.
  3. The desktop appears, and the findings panel is empty. A clean machine reports nothing. That is the control: noise here would make everything after it meaningless.
  4. The candidate exfiltrates eight planted credentials — and the panel fills in real time with 13 high-severity honeytoken hits. Those markers exist nowhere outside this audit, so there is no innocent explanation for them leaving.
  5. The report says REJECT, with every finding traced to the exact captured evidence.
Enterprise-ready today. Not "on the roadmap." Not "contact sales." Shipping now.
6 Windows candidate formats SSO behind any OAuth2 proxy RBAC (3 roles) API tokens Meta-audit log β†’ NIST 800-53 Slack + Jira + webhooks Zero new deps
See the enterprise stack β†’

Every week, somebody wants to install something new.

A vendor's marketing page is not evidence. A privacy policy is not evidence. Behavior under instrumentation is evidence.

Static analysis

Looks at the binary on disk. Doesn't see what it does at runtime.

Insufficient

Package scanners

Catches known-CVE deps in the supply chain. Doesn't see what the binary actually transmits.

Insufficient

swaudit

Runs the candidate. Observes every process, file, registry and network action it takes, reads its TLS payloads in plaintext, and records every destination it dials. Produces a signed report with evidence.

Defensible

The dynamic-analysis advantage

Sophisticated malware doesn't look malicious. It behaves malicious β€” but only when nobody's watching.

Static scanners read the bytes on disk. That's a fundamentally bounded problem: an attacker who controls the binary controls what those bytes look like. Modern malware exploits this gap by making the on-disk form deliberately innocuous and only revealing its true behavior at runtime.

🧊 Static scanners can't see…

  • Packed / encrypted payloads that decrypt themselves at runtime β€” UPX, custom packers, "stub on disk, real code in memory."
  • Living-off-the-land binaries (LOLBins): nothing in the file is malicious, but the runtime sequence of commands is.
  • Time-bombs: malicious code gated on a date check, a domain DNS lookup, or a registry key set by another process.
  • Anti-analysis logic: "if I detect a debugger / VM / sandbox, behave perfectly; otherwise exfil."
  • Dynamic config fetch: the binary is benign until it pulls a runtime config from a remote endpoint.
  • Stage-2 payloads: the on-disk binary is just a downloader. The actual malware never touches the filesystem of the disassembler.

πŸ”¬ swaudit instruments and watches…

  • Every process, file, and network action the candidate takes in the VM — logged with PID, timestamp, and arguments.
  • Every TLS payload, decrypted: a per-session CA terminates HTTPS in-sandbox so we read the plaintext the candidate thought was private.
  • Every honeytoken: 18 fake credentials seeded at standard paths and env vars before the candidate runs. Any observation in egress is unambiguous exfiltration.
  • Beaconing patterns: periodic equal-spacing connects (low-jitter callbacks) β€” the classic C2 fingerprint.
  • Sensitive-path access: the user's .aws and .ssh directories, browser cookie and credential stores, and the registry hives that hold saved secrets.
  • PII patterns in TLS payloads: credit cards (Luhn-validated), JWTs, email addresses.

The honeytoken proof

We seed a fake cloud access key into the sandbox before the candidate starts. It is minted fresh for that one run, and nobody — including us — has ever published it. There is no plausible reason that exact string should ever leave the VM. If it appears in any TLS plaintext to any destination β€” that's exfiltration, full stop. Not a heuristic. Not a probability. Evidence.

This is what static analysis fundamentally cannot do. You can't detect intent in bytes β€” you can only detect it in behavior under observation.

Other dynamic-analysis tools exist (commercial sandboxes, EDR products), but they're built for a different job: continuous monitoring after deployment, alerting on observed-bad behavior. swaudit is built for the pre-approval moment β€” the auditor's defensible-decision-with-evidence step that EDR doesn't address. It's the difference between "we caught the breach" and "the breach never happened because we didn't approve the binary in the first place."

How is this different from what we already have?

Where swaudit fits in your existing stack

Static AV catches signature matches. SAST catches code patterns. EDR catches breaches that already happened. swaudit catches behavior at the moment of approval β€” the gap none of the others cover.

Capability Static AV
VirusTotal, Defender
SAST
Semgrep, Snyk
EDR
CrowdStrike, S1
swaudit
Catches signature-known malwareβœ“β€”βœ“βœ“
Catches packed / obfuscated payloadsβœ—βœ—βœ“βœ“
Catches novel / zero-day behaviorβœ—~~βœ“
Decrypts + inspects TLS exfil trafficβœ—βœ—βœ—βœ“
Honeytoken-based exfil proofβœ—βœ—~βœ“
Pre-deployment evaluationβœ“βœ“βœ—βœ“
Defensible report for non-technical approverβœ—~βœ—βœ“
Cryptographically signed evidence packβœ—βœ—~βœ“

Where they're complementary: swaudit doesn't replace your AV (you still want runtime protection on every endpoint) or your EDR (you still want post-breach forensics). swaudit covers the approval moment β€” the question of "should we install this in the first place?" β€” which is the gap your other tools were never built for.

Legend: βœ“ supported Β· ~ partial Β· β€” not the tool's job Β· βœ— not supported. Categories are general; individual products vary.

How it works

  1. 1

    Submit a binary

    Upload a Windows candidate through the web UI. Format is detected structurally, not from the file extension β€” we look inside the file rather than trusting its name, so a mislabelled candidate still routes correctly. Six formats are launched today, each with the host program a real Windows machine would use: .exe directly, .msi via msiexec, .ps1 via PowerShell, .hta via mshta, .wsf via wscript, and .bat / .cmd via cmd.

  2. 2

    Sandbox + instrument

    The candidate runs in its own disposable Windows VM — created for one audit, destroyed after it, sharing no kernel, filesystem, or namespace with the audit infrastructure, and never reused between audits. It is launched as a de-privileged standard user rather than an administrator. The collector is a system-level service inside the same VM: it records every process, file, and network action the candidate takes, and a local TLS-terminating proxy reads the plaintext of encrypted traffic. Unique-per-run honeytokens are planted in credential files, browser cookie stores, and environment variables before the candidate ever starts.

    Because the collector shares the guest with the candidate, every batch of evidence it sends is cryptographically authenticated with a key the candidate cannot read. If the collector is silenced, or a batch fails that check and is never redelivered, the audit is reported as inconclusive rather than clean. An audit that could not be collected properly never becomes an approval.

    The VM's system proxy is pointed at the in-guest interceptor before the candidate starts, with our certificate authority trusted at boot. So when the candidate dials a real exfiltration destination, we present a leaf certificate it accepts, read the request body in plaintext, and record it as evidence. What the candidate sees is an ordinary response; what the report gets is the payload it tried to send.

    For installers and apps where the malicious code only fires after a user interaction (click Install, accept the EULA, sign in), the auditor can also drive a candidate manually through a browser-based VNC view of the sandbox. The same in-guest collection, planted credentials, and TLS interception run in the background throughout. Auditor-only, never anonymous.

  3. 3

    Detect

    Every event flows through 21 streaming detectors + 3 post-enrichment detectors. The core set: HoneytokenHit (smoking gun β€” a planted token observed in outbound traffic), VendorDiff (unauthorized destination), SensitivePath (credential and key-file reads), SandboxDetection (probing for VM markers), HostFingerprint, TimeManipulation, Persistence (Run keys, Startup folders, services, scheduled tasks, Winlogon), PII (Luhn-validated CC numbers, JWT, email), Beaconing (regular-interval phone-home), CryptoMining (Stratum-port connects), NetworkDestination, KnownBadASN, KnownBadDomain, GeoPolicy.

    A second family targets attacker tradecraft directly: DefenseEvasion (clearing the event log, disabling Defender, deleting shadow copies), CredentialAccess (LSASS / SAM / NTDS / DPAPI / browser-credential-store reads), DiscoveryRecon (system, network, and account enumeration), LOLBinAbuse (certutil / mshta / regsvr32 living-off-the-land execution), DataStaging (archiving files for exfiltration), InputCapture (keystroke capture), and DNS (algorithmically-generated lookups, DoH resolvers that route around DNS visibility, and dynamic-DNS / fast-flux domains).

    Three of them exist to make blind spots visible rather than to find bad behavior, because "we observed nothing" and "we could not observe" are not the same answer. TLSCoverage reports every flow the proxy could not terminate β€” a certificate-pinned client's plaintext was never inspected, and the report says so instead of staying quiet. TLSReassembly catches a token or card number deliberately split across separate encrypted writes, which no single-event check can see. CloudMetadata flags reads of the cloud instance-credential endpoints that a naive link-local exemption would otherwise bury. A batch of evidence the collector abandoned rather than delivered, a collector that went silent, a candidate that never started, and a candidate that ran with administrator rights all floor the verdict too β€” an audit that could not see clearly never returns a clean approval.

  4. 4

    Report

    Markdown + HTML report with a recommended decision: REJECT / REVIEW / APPROVE. Severity-grouped findings with evidence references back to the JSONL event log. Network-destinations table enriched with PTR / ASN / country. Every finding is mapped to its MITRE ATT&CK® technique and grouped by tactic, so your security team can reason about the run in the framework they already use. Reports are Ed25519-signed for tamper-evident sign-off and independently verifiable offline. The auditor signs off through the web UI β€” an append-only decision with rationale, and separation of duties enforced so a submitter can't approve their own audit; a baseline is saved for re-audit on the next vendor release.

When the candidate is an installer

Most Windows software arrives as an installer, so this is the scope statement that matters most — which is why it is here and not in a footnote. An installer is audited as an installer.

What is audited

The installer's own behaviour, from the moment it starts until Windows demands administrator rights: what it unpacks and where, the files and registry values it writes, the processes it spawns, the destinations it dials, and the plaintext of the traffic the sandbox proxy can read.

A bundled third-party offer, a changed browser setting, a persistence key, a scheduled task, an undisclosed destination, a planted credential read and shipped — all of these are installed by the installer, and all of them are visible here. A hostile installer does its damage in exactly this window.

In scope

What is not audited

The installed product. What the software does on its second launch, after a reboot, as a background service, or through an update channel it registered is not observed today, in any run.

No verdict from swaudit speaks to it. "We did not look at that" is not "there was nothing there", and this page will not let the two be confused.

Out of scope

Why the line is there

The candidate is deliberately run as a de-privileged standard user, never as an administrator. An administrator-level candidate shares the collector's trust domain — it could read the evidence key, forge a clean batch, or delete the record of its own behaviour — so that control is what makes a clean verdict mean anything at all.

It is not relaxed to make an installer finish. A per-machine install needs privilege the sandbox does not grant, so the audit stops where the elevation does.

By design

How to read a run that stopped at the boundary. One of two things happens, and the report says which. Either the installer never starts at all — some declare up front that they require administrator rights, and a de-privileged launch cannot grant that — or it starts, unpacks, begins installing, reaches the step that needs elevation and exits with an error. In both cases the run is reported as inconclusive and can never be filed as an approval. That is neither an endorsement nor an accusation. It does not mean the software passed: the installed product was never exercised, and not exercised is not clean. It does not mean the software failed: nothing bad was necessarily observed, and the stop is our sandbox's isolation control doing its job, not the vendor's software misbehaving. It means the audit could not be completed — and saying so plainly is the whole point, because a run like this used to render a clean "no findings" verdict over software that never installed.

Not everything hits this boundary. Software that installs per-user, and portable software that needs no install at all, runs to completion as a standard user — its full behaviour is in scope, start to finish. That is also the shape an employee downloads and runs without asking anyone, which is where the approval question is loudest. Auditing what a per-machine installer does after elevation needs a different mechanism than a de-privileged launch, and it is not built.

Evidence integrity

The software being audited runs in the same sandbox as the thing watching it. So can it cheat?

This is the question that decides whether any verdict means anything. The collector shares the swaudit Windows VM with the untrusted candidate — so a defensible report has to prove the candidate cannot forge a clean verdict, destroy or fabricate evidence, steal the answer key to the planted credentials, or escalate out of the sandbox into your cloud account. Not "we don't think it can." Proven, on live hardware, by a probe that runs as the candidate itself and tries every one of these.

What the candidate tries What it would win Result
Read the collector's secret authentication keySign a forged batch of evidence and hand back a clean APPROVE verdictBlocked
Read that key where it sits at rest on the machineSame — forge a clean verdictBlocked
Write into, or delete from, the evidence queuePlant fake benign evidence, or erase the record of its own theft before it is sentBlocked
Mint the sandbox's own cloud credentialsBreak clean out of the sandbox and pivot into the cloud account entirelyBlocked
Read a planted-credential file as some other accountRead the honeytoken without the candidate "touching" it — attribution collapsesRestricted

The probe reports its own identity first, and the whole suite is thrown out as untrustworthy unless it is genuinely running as the de-privileged candidate — a control that "blocked" a privileged probe would prove nothing. Every result above was recorded in a single live run whose candidate still successfully stole and exfiltrated its planted credentials: the isolation fences the candidate without blinding the detection it protects.

Demonstrated end to end — with a negative control

In that same validation, a candidate that reads a planted credential and ships it over TLS is caught (HoneytokenHit) and the verdict is REJECT — reproduced across three independent live runs. The thing that makes the result mean something is the negative: the exact same credentials planted, a benign candidate that steals nothing, and zero hits. A positive without that negative would only prove the detector reacts to tokens existing, not to them being stolen.

Kept honest — we assert the gaps, too. A marker that is base64-encoded before it leaves, plain-http:// traffic, a client that pins its own certificate or opens a raw TLS socket that ignores the sandbox proxy, and a marker deliberately split across writes beyond the reassembly window are not claimed as caught. Each of those has a test that asserts it evades, so the coverage claim can never quietly drift into an overclaim. And every control above assumes the candidate runs de-privileged: a candidate granted administrator rights is floored to inconclusive rather than trusted, never quietly approved.

What swaudit observes

Every audit runs the candidate in a disposable Windows VM and watches what it actually does — not what its installer claims. The evidence below is what lands in the signed report.

Findings trace to raw evidence — the collected process, file or registry record, a decrypted payload, a timestamp. An auditor has to defend this report later, so nothing appears in it without a pointer to what produced it.

What about installers gated behind a click?

A lot of in-the-wild malware sits behind a UI gate. Headless audit boots the binary, the binary pops a "Welcome β€” click Install" prompt, the audit window expires, the binary exits without ever running its payload. Verdict lands at REVIEW. Real malware ships.

Interactive audit fixes this. The auditor drives the candidate manually through a browser-based VNC view of the Windows desktop while the same in-guest collection, planted credentials, and TLS interception keep recording throughout. Mouse and keyboard pass through to the candidate; the candidate sees a real human (sandbox-detection heuristics give up). The auditor captures screenshots as they go, each with a caption, and they are embedded in the rendered report so the approver can see exactly what was on screen at the moment a finding fired.

It fixes the click gate, not the elevation boundary. A human at the console can accept a licence and press Install. They cannot grant the candidate administrator rights, because running without them is the control that makes the evidence trustworthy. So on a per-machine installer, an interactive session observes the same window a headless one does — the installer's own behaviour, up to the point elevation is required. What that covers →

Available to authenticated auditors only. Anonymous visitors and submitters never reach this surface β€” running real binaries interactively is bounded by an explicit role gate plus a per-server concurrency cap.

Auditor quick-launch

Authenticated auditors only. Clicking a button opens a fresh interactive session in a new tab β€” a Windows VM boots, the candidate is staged and launched, and you drive it through the noVNC viewer.

Windows candidates. One pipeline. One report shape.

Every candidate is staged into a fresh Windows VM and launched as a de-privileged standard user. What differs per format is only which program the collector is asked to start.

Every format produces the same report shape — recommended decision, summary, severity-grouped findings with raw evidence, network destinations with ASN and country, planted-credential results, and a signature an approver can verify independently. Where the candidate is an installer — an .exe setup or an .msi — what is audited is the installer's own behaviour up to the point Windows requires administrator rights, not the software once installed. Read the scope →

Enterprise-ready out of the box, not on a roadmap.

Most security tools call themselves "enterprise" and mean we plan to support SSO eventually. swaudit ships the full enterprise-deployment plumbing today, tested in CI β€” SSO behind any OAuth2/OIDC proxy you already run, three-role RBAC enforced per handler, hashed API tokens and scoped machine-to-machine service accounts, per-tenant isolation, governed approval with separation of duties, a software-request approval queue, an append-only meta-audit log, and Slack + Jira + generic webhook fanout with durable retry. Zero new third-party dependencies in the entire enterprise layer.

SSO & RBAC

Sits behind any OAuth2 / OIDC reverse proxy (oauth2-proxy, Pomerium, Authentik, Keycloak). Identity is forwarded via standard X-Forwarded-Email / X-Forwarded-Groups headers. Three roles map to handler privileges: submitter, auditor, approver. Group membership at the IdP drives role assignment.

Production-ready

API tokens & read API v1

Issue revocable API tokens for CI/CD pipelines and dashboards, plus scoped service-account tokens (runs:read / findings:read) for machine clients. Tokens are stored hashed (SHA-256); the plaintext is shown once. A stable, versioned read API (/api/v1/runs…) returns verdicts and findings from the authoritative typed source β€” never by scraping a rendered report.

Production-ready

Meta-audit log

Every request through the server β€” submission, view, sign-off, policy view β€” lands in an append-only JSONL log with actor, source, roles, action, target, status, IP. Maps directly to NIST 800-53 AU-2/AU-3 audit-event controls.

Production-ready

Slack notifications

On every REJECT verdict, post a coloured attachment to your security channel: target, decision, finding counts, link to the full report. Configurable per event type β€” fire on all runs, only rejected runs, or only on sign-off.

Production-ready

Jira ticket creation

Auto-create a Jira issue for each REJECT verdict with the finding evidence in the description. Configurable project key, issue type, and assignee. Uses Atlassian REST API v3 β€” no plugin install on the Jira side.

Production-ready

Generic webhooks

Multiple destinations, per-event filters, custom headers (HMAC signing keys, auth tokens). Subscribe ServiceNow, PagerDuty, custom workflow engines, or your own SIEM intake. JSON payload includes the canonical Event shape β€” same data Slack and Jira receive. Delivery is durable and retried with backoff, and every attempt's outcome is observable β€” a failed endpoint doesn't silently drop the notification.

Production-ready

Multi-tenant isolation

Runs, tokens, reports, and artifacts are scoped per tenant β€” one customer or business unit never sees another's audits. Enforced on every read and write, with a dedicated support role that can cross tenants only through an audited crossing. Per-tenant configuration (retention, allowed detectors, policy overlay) sits on top.

Production-ready

Governed approval

An approval is an append-only decision event with a required rationale, optional conditions and expiry β€” not a mutable annotation that can be quietly overwritten. Separation of duties is enforced: a submitter cannot approve their own audit. Every decision and every supersession is chained and preserved for the record.

Production-ready

Software-request queue

A run is not a business request. Capture the requester, business owner, vendor, version, and intended use, with an immutable state history (submitted β†’ assigned β†’ in‑audit β†’ closed) and the audit run linked at creation. The bridge between "someone wants to install X" and a defensible approval decision.

Production-ready

Two ways to deploy

Cloud-hosted (SaaS)

Subscribe and log in

  • We host the audit infrastructure
  • You submit binaries via web UI, get signed reports
  • Tenant-isolated; binaries never persist beyond the audit window
  • Threat-intel feeds maintained for you
  • Per-audit billing, no infra to operate

Best for teams that want fast answers without standing up sandboxing infra.

Subscribe β†’

Self-hosted

Run it in your own cloud account

  • Same audit pipeline, same UI, same report format
  • Control plane ships as Docker Compose and runs wherever you like
  • Audits execute in disposable Windows VMs in your own cloud account, under credentials you supply β€” never on swaudit infrastructure
  • Reports, evidence packs, and the audit log stay in your storage
  • Commercial license

Best for teams that want the evidence and the audit trail to remain under their own control.

Get deployment instructions β†’

What self-hosted does not mean. Every audit runs a real Windows VM, so the candidate binary leaves your local network for the cloud account you configure. That is a deliberate trade β€” a hypervisor boundary is a stronger isolation guarantee than a container β€” but it means fully on-premise and air-gapped operation are not supported, and neither is any deployment without cloud credentials. The supported control-plane artifact is Docker Compose; there is no Helm chart, Kubernetes manifest, Terraform module, or bare-metal installer, and no supported backup, restore, or upgrade procedure. If binaries are contractually barred from leaving your premises, swaudit is not currently a fit, and we would rather tell you here.

Stop trusting marketing pages.

Submit a binary. Get evidence. Sign off with confidence.

By submitting, you agree to the swaudit Terms of Service and Privacy Policy.