Inspiration

Small teams and solo founders ship products constantly without ever getting a real security assessment — proper pentests are expensive, slow, and need expertise most early teams don't have. We wanted to close that gap: point Glorify at a URL and get back a genuine security assessment, not a linter-grade checklist.

The project itself went through a real pivot. We started with an autonomous OWASP Top 10 pentest agent, detoured into a completely different idea — a multi-agent "AI jury" that researched and settled small disputes — and came back to the original pentest concept once we got access to Steel's private-beta Steel Computer: a full cloud Linux sandbox, not just a browser. That changed what was actually buildable. Instead of browser-only checks, we could run real tools — OWASP ZAP, Nuclei, sqlmap — autonomously, against a target we don't own any infrastructure for.

How we built it

Glorify is two small hand-rolled servers plus two things running in Steel's cloud. A Node dashboard (no framework, just node:http) handles login and the UI; a Python backend (Python's built-in http.server, no Flask/FastAPI) orchestrates everything else, and the two only ever talk to each other over localhost.

When you submit a target, the backend first gates it: any URL other than the exempt OWASP Juice Shop practice instance has to prove ownership via a /.well-known/steel-pentest-verify.txt token before anything runs. For external targets, it opens a real Steel Browser session — a Chromium instance Steel hosts, driven over CDP — to crawl the site, screenshot each page, and fingerprint the API endpoints it calls along the way.

The actual scanning happens on the Steel Computer, provisioned once up front with ZAP 2.17.0, Nuclei 3.11.1, and sqlmap already installed. Every interaction with it — launching a scan, checking progress, pulling results — is a single steel computer exec call: closer to running something over SSH and getting the output back than to a persistent connection. On that box, our own hand-written HTTP checks (an IDOR probe using two real accounts, a SQL-injection auth-bypass proof-of-concept, a weak-password-policy check, a clickjacking header check) run alongside ZAP's spider and active scan, Nuclei, and sqlmap — and every one of them normalizes its output into the same shape, so a hand-written check and a ZAP alert look identical by the time they reach the report.

Once findings come back, Claude writes the narrative — but on a deliberately short leash: the system prompt explicitly forbids it from inventing a finding or changing a tool-assigned severity. The tools do the detection; the model only explains and prioritizes what they found. Findings get mapped against the OWASP Top 10 and built into a PDF with ReportLab, with screenshots from the crawl embedded as evidence.

Challenges we ran into

Driving a remote sandbox that has no persistent session was the core engineering problem. A pentest can run 20–30 minutes, but every command to the Computer is a one-shot call — so scans had to be launched as a backgrounded process on the remote box and polled for every couple of seconds, catting log files and hitting ZAP's own REST API (which only exists on that machine's loopback) through the same exec channel, rather than driven directly.

The Computer also has a finite lifetime — ours runs for 8 hours — and can disappear mid-scan, so "the sandbox is just gone" had to become a real, detected failure mode rather than an assumption we could ignore.

Deciding how to let people scan real sites without turning this into a tool for attacking sites they don't own was its own design problem — we built an ownership-verification flow around a /.well-known token proof. In a later pass we actually caught that the backend had this logic fully built, but the dashboard never exposed it: every non-exempt target was silently unscannable because there was no UI path to complete verification at all. Finding and wiring that up was a good reminder that a feature existing in the backend isn't the same as a feature existing.

What we learned

We learned to treat a stateless, exec-based remote environment as if it were a persistent machine — polling patterns, idempotent restarts, and designing for "the environment might vanish" as a first-class case. We learned that hand-written checks and off-the-shelf scanners are more useful combined than either alone, as long as everything funnels into one findings shape before it reaches reporting. And we learned where to actually draw the line on what an LLM should be trusted to decide in a report meant to be trustworthy — writing the prose, never the severity.

Built With

Share this project:

Updates

Submission history