AxiomGitHub (opens in a new tab)

How it works

It doesn't read your site.
It uses it.

Every other tool in this category parses your HTML and checks it against rules. That finds mechanical faults and misses the failures that actually lock people out. Axiom drives a real browser and a real keyboard, then reads your source for what a browser can never see.

The live-site pipeline

Map the site

A breadth-first crawl from your entry URL, staying on one origin and honouring robots.txt. Breadth-first matters: it reaches the pages linked from your homepage — the ones users actually see — before descending into archives. Concurrency is capped at three pages, with a page cap and a wall-clock budget on top.

Observe each page under its real security policy

Runtime listeners are attached before navigation, so the earliest and most interesting errors are captured rather than missed. This pass never bypasses your Content Security Policy — the reason why is below.

Instrument, then operate the page

A second pass injects the accessibility engine and then presses Tab, over and over, recording every element focus lands on: its position, its label, and whether focusing it visibly changed anything at all.

Re-render it on a phone

The same page at 390×844, measured for content running off the edge, tap targets under 24px, and text under 12px.

Request every link

Each unique URL discovered anywhere on the site, checked once — HEAD first, falling back to GET for servers that reject it — and reported with the pages that link to it.

Merge symptoms into causes

The same faint grey appears on every page sharing a stylesheet. That is one problem with forty symptoms, so it is reported once, with the list of places — not forty times.

The part we got wrong first

Bypassing CSP hides the bugs CSP causes.

To inject an audit harness into a page you have to bypass its Content Security Policy. But a site whose CSP blocks its own scripts looks perfectly healthy through a bypassed browser — the very failure you want to find is the one you just suppressed.

Pass 1 — observeCSP left intactconsole · network · timingPass 2 — instrumentCSP bypassedaxe · keyboard walkMergeby root causeOne report+ agent prompt
We found this by running Axiom on Axiom: the single-pass version reported our own site clean while a console error sat in the browser.

The keyboard walk

A button nobody can reach is invisible in the markup.

A <div> with a click handler works perfectly with a mouse and does not exist for anyone without one. No parser can tell you that. So Axiom presses Tab through the entire page, records every stop, and compares what it reached against everything on the page that behaves like a control.

tab  1  → input[email]           focus ring: none      ⚠
tab  2  → input[text]            focus ring: none      ⚠
tab  3  → button "Start trial"   focus ring: visible   ✓
tab  4  → a "Docs"               focus ring: visible   ✓
        ── sequence complete, 4 stops ──

never reached:
  <div>  "Sign up free"   click handler, not a control
  <span> "Dismiss"        role="button", no tabindex

The walk is driven through real key events, not element.focus(), because only real keypresses exercise the browser's actual focus algorithm — including tabindex, traps, and handlers that intercept keydown.

The code audit

The bugs a browser can never see.

You cannot test for SQL injection or a missing rate limit from outside — and you should never fire payloads at a server you do not own. With the source, you read the vulnerability directly. That is static analysis, and it is both legal and more thorough: it sees every route, not just the ones a crawler can reach.

Walk

Your files, skipping node_modules, build output and minified bundles.

Scan

Secret patterns, injection and auth shapes, dependency and config checks.

Mask

Every secret reduced to a prefix and three characters before display.

Your code never leaves your machine. The CLI runs entirely locally and makes no network calls at all. The web upload unzips in memory, scans, and discards — nothing is written to disk, stored, logged, or sent to any model.

Where it refuses

It will not invent alt text

For an image it cannot interpret, it says a human is needed. A plausible-sounding alt attribute silences the audit while lying to the screen-reader user it was meant to help.

It reports shapes, not proofs

Pattern analysis says what dangerous shape it detected — never that something is proven exploitable. Its job is to put your eyes on the twelve lines that deserve them.

It will not attack anything

No probing rate limits, forcing logins, or firing injection payloads. Everything it reports, it observed from what a page and its server volunteer to any browser.

139 checks run on every audit — see the full list.