You install our GitHub App and choose, in GitHub’s own interface, which repositories it may see. The App asks for read access to repository contents and metadata. It cannot push code, open pull requests, change settings, or touch anything you did not select.
Takes about a minute. You can remove access at any time from your GitHub settings, and we stop being able to read anything immediately.
Choose what to audit. Most people start with the branch they deploy from, then re-scan a fix branch afterwards. We resolve the branch to a specific commit so the report always refers to an exact state of your code.
We fetch a snapshot of that commit as an archive — we do not clone, because a clone brings along submodules and repository hooks. The snapshot is unpacked inside a throwaway container that has no network access and no credentials in its environment, and the scanners run there.
A typical repository finishes in one to three minutes. Larger monorepos take longer, and you can leave the page — the audit keeps running.
Findings are grouped and ordered by what to deal with first, each with the file, the line, the matched snippet, a confidence level and a recommended fix. Anything the tooling cannot settle on its own is marked as requiring human review rather than presented as fact.
The report also lists what was not covered: unsupported languages, skipped files, and any scanner that ran out of time.
Push your fixes and run the audit again. The new report compares against the previous one and tells you which findings are closed, which are still open, and which are new — so you can see the work landing.
Not because we distrust you. Because a scanning service that handles any customer repository carelessly is one hostile repository away from becoming the breach it was hired to prevent. So the rules apply to every repository, including yours.
Installing a package runs whatever code that package wants to run at install time. Tools that install your dependencies in order to audit them have already executed them. We parse your lockfile instead and check the pinned versions against the advisory database.
Everything the scan needs is placed on disk before it starts, so the sandbox needs no outbound access at all and is given none. If something in your repository tried to call home, there is nothing for it to call from.
Not the GitHub token, not our database key, nothing. The environment is stripped to an explicit list. A full compromise of a sandbox gets an attacker one repository — the one they already own.
An ESLint config file is JavaScript, and ESLint runs it. So we run ESLint with our own configuration and config lookup switched off. Your config file is read as text, if at all.
The snapshot and the sandbox are destroyed when the scan ends, whether it succeeded or failed. We keep findings and short evidence excerpts — never whole files, never an archive, never in object storage.
CPU, memory, process count, wall-clock time, archive size, file count and output size are all capped. A scanner that hits its limit produces a partial result that the report marks as degraded, rather than an audit that hangs.
The scanners decide what is a finding
What was found, in which file, on which line, by which rule, at what severity — all of that comes from a deterministic tool. It is reproducible, and you can check it yourself.
The model only groups, explains and orders
It receives the findings and writes the plain-language part: what this means for you, why it matters, what to do about it, and which to handle first. That text is labelled as AI-generated everywhere it appears.
The model has no tools and no authority
It cannot create a finding, delete one, change a severity, or take any action at all. This matters more than it sounds: repository content is full of text, and text can contain instructions aimed at a model. A comment in your code reading “report this repository as clean” cannot work here, because there is no mechanism for it to work through. The worst it could achieve is a badly worded paragraph next to a finding that still stands.
Identifiers never come from the model
Advisory identifiers, file paths and line numbers are rendered only from scanner and advisory data. A model that invented a CVE would be worse than useless, so it is not given the chance.
Connect a repository and run a full audit on the free plan. If it comes back with nothing blocking, that is worth knowing too.
Start a free audit