Offline, air-gapped, and nothing leaves the host
You already know the constraint, so this page is about whether this tool actually meets it. Static application security testing, dependency matching and vulnerability matching all run on the machine that holds the code. One switch hard-refuses every network call at the process boundary. Entitlement is online-first with roughly 14 days of offline grace, and a machine that will never see the network runs from an air-gap licence file we issue on request. The vulnerability archive is checksummed and can be carried in on a disk.
- No source upload, ever
- One switch closes the boundary
- Air-gap licence file on request
- Vulnerability data delivered offline
What offline means here_
Every scanner in this category calls itself offline. These are the four things we mean by it, written so that a reader can catch us out if any of them is untrue.
01
No source upload, ever
The detection runs locally. There is no optional cloud feature that quietly sends code away for deeper analysis, and no tier that unlocks one. If there were, the rest of this page would be worthless.
02
One usage call, on by default, and you can read all of it
We will not write “no telemetry” here, because it would be untrue. A usage heartbeat is on by default and posts to our servers at most once a day. It carries eight fields at most: which product ran, an install id, the version, the operating system family, a timestamp, a count of how many scans ran, a device token while you are signed in, and a short list of the language names seen in the last scan. It never carries a path, a project name, a finding or a line of source. Setting VULKRO_OFFLINE or VULKRO_NO_HEARTBEAT reduces it to zero egress, and the next section prints the body field by field.
03
An account, verified without your code
The product requires an account, and your first sign-in starts a 14-day trial of the full product. Entitlement is online-first: the signed lease refreshes on that same daily call and keeps working for roughly 14 days without one. A machine that will never reach the network runs from an air-gap licence file instead, bound to that machine and verified locally. That file is the escape hatch rather than the default, and we issue it on request at license@vulkro.com.
04
An enforceable air gap
One switch makes the process refuse every outbound call at the boundary rather than merely declining to make one. With an air-gap licence file installed, the review runs fully disconnected, and the vulnerability archive arrives by disk, internal mirror or your own feed.
Everything the scan needs stays on your machine: the code it reads, the map it builds of how your product fits together, the findings it writes, and the optional local model it can consult without leaving the machine. One line leaves.
- Stays on this machine
- source code, call graph + taint, findings, account layer, and the local model on 127.0.0.1
- One crossing
- The usage and entitlement call: eight fields at most, at most once a day, and nothing derived from the contents of your code. Turn it off, or run from an air-gap licence file, and this line does not exist at all.
- Never crosses
- source code, file paths, file names, finding contents, project names, the hardware fingerprint
The vulnerability archive is distributed with a checksum and verified against it when it lands. That is a check on integrity in transit, and it is deliberately not described as a signature check, because those are different guarantees and only one of them is on offer. How the archive is built, how often it is refreshed and how to move it into a network with no route out are in the offline vulnerability matching guide, and the outbound inventory is itemised in the network reference.
The one crossing_
A privacy claim that cannot be checked is a policy. This call is on by default. Here is the entire body of it, field by field, with what each field carries.
- The eight fieldsThe eight fields are: the product that ran, an install id, the version, the operating system family, a timestamp, a count of scans since the last call, a device token while you are signed in, and a short sorted list of the language names seen in the last scan. Six of those are present on an anonymous run. The install id is minted at install and is not a hardware fingerprint, so it cannot be correlated with a machine you own elsewhere. The scan counter is how a per-seat licence is enforced without anybody looking at what was scanned. The language list is capped in length and is never a path or a filename.
- What is not in the bodyWhat is not in the body: no source, no file paths, no file names, no project names, no findings, no repository or branch, and no hardware fingerprint. There is no field one of those could travel in.
- VULKRO_OFFLINE, VULKRO_NO_HEARTBEATSetting VULKRO_OFFLINE or VULKRO_NO_HEARTBEAT reduces this to zero egress. VULKRO_OFFLINE goes further and makes the process refuse every outbound call rather than skipping this one. On a machine running from an air-gap licence file there is no cadence, no call and no body at all, because the entitlement was verified locally from the file.
| Field and example value | What it carries |
|---|---|
| "product": "vulkro", | which binary made the call |
| "install_id": "3f9c1a7e-5b40-4c8d-9a21-7ce4d0b28f16", | a random id minted at install, not a hardware fingerprint |
| "version": "0.28.0", | the build that is running |
| "os": "macos", | operating system family, not a machine name |
| "scans_since_last_heartbeat": 4, | how many scans ran since the last call |
| "timestamp": "2026-08-15T09:41:02Z" | when the call was made |
The position_
Plot this category on two axes, whether it runs where your code already is and whether anyone is accountable for it, and one of the four cells is nearly empty.
| Who is behind it | Runs on your machine, one binary | Runs in somebody else’s cloud |
|---|---|---|
| Free, community supported | Several genuinely good command-line scanners live here. You get the tool, a forum, and whatever accuracy claim the project makes about itself. | The free tiers of the hosted platforms, which is the same trade as the paid cell to the right with a lower ceiling. |
| Paid, with a vendor accountable | Vulkro. A supported product that runs entirely on your machine as one binary, with a published measurement method behind the accuracy claim. | Almost everything else that a company pays for in this category. You connect a repository, code or snippets leave the building, and telemetry comes with it. |
No vendor is named here on purpose. The quadrant describes the shape of the category. The measured figures and the method behind them are published in the benchmark documentation.
- 01
The free offline tools are real and some of them are good. The trade is that you get community support and an accuracy claim the project makes about itself. The paid products are almost all hosted, which means connecting a repository and accepting that code, or fragments of it, leaves the building. If your constraint is that it must not, then the paid cloud column is not a decision you get to make.
- 02
What the middle cell is supposed to give you is both: somebody accountable for the product, and a scan that never leaves the machine. That is the position this product occupies, and the only way to make it credible is to publish how the accuracy is measured rather than asking you to take the architecture as evidence of quality.
One binary_
A disconnected environment is the worst place to be running four separate tools, each with its own update path and its own data feed.
- The application code itself
- Secrets, including the ones you removed
- Infrastructure, containers and built images
- Dependencies, matched against data on your disk
01
The application code itself
Broken access control, injection, server-side request forgery, records fetched without an ownership check, request bodies written straight onto stored records, and authorisation gaps on endpoints, found by following an untrusted value from the request that carried it to the call that trusted it.
Learn more02
Secrets, including the ones you removed
Entropy checks alongside provider-specific formats, across the working tree and the commit history behind it, because deleting the line never deleted the credential.
Learn more03
Infrastructure, containers and built images
Infrastructure definitions and container build files read as configuration, and built images unpacked so the packages baked into their layers are matched too.
Learn more04
Dependencies, matched against data on your disk
Manifests and lockfiles read for the versions they resolved to and matched with no network call, ranked by whether your own code reaches the affected function.
Learn more
Values are followed across file boundaries in Python, JavaScript, TypeScript and Go. In Java the trace stops at the first file boundary, so a Java result on the same codebase is narrower than a Python or Go one. Those five, plus Salesforce Apex in the Salesforce build, are the whole list: there is no Ruby, C#, PHP or Kotlin parser. The per-language depth is set out on what the scanner covers and in the supported detection reference, because a language you rely on being absent is something you should learn here rather than after installing.
Measured, not asserted_
The result below comes from a test built out of real applications with real, publicly documented vulnerabilities in them, at the strict setting we recommend for a gate.
33 of 83
Real vulnerabilities found
Measured against vulkro 0.28.0, measured 2026-09-18
- Measured against vulkro 0.28.0
- Measured 2026-09-18

- 33 of 83 found
- 50 missed, published
- 20 false alarms
Every vulnerability in this test is a real, publicly documented bug in a real application, confirmed by reading the code at that exact version. The ones Vulkro cannot find stay in the test rather than being removed.
- 01
The detection engine is closed, and that is the licensed product. What is published instead is the thing that decides whether the claim is worth anything: the way accuracy is measured, the provenance of every vulnerability in the test, and the ones the review fails to find. You can check the catch rate and the false-alarm rate without anybody handing over the rule engine, which is the honest version of this trade rather than an invitation to read the source.
- 02
Note what the middle row costs us to publish. A vulnerability the review cannot find stays in the test rather than being removed from it, so every figure above is lower than it would be if we curated the test to flatter the result.
Honest scope_
Offline solves exactly one problem, and it is worth being precise about which one.
5 manifest and lockfile formats are read (npm, PyPI, Go modules, crates.io, Maven), but the published archive does not currently carry all 5: the default one ships npm and Python packages, and the wider archive adds Go modules, crates.io and Maven. The archive is distributed with a checksum and verified against it on arrival, which is an integrity check and not a signature check. On a disconnected machine, confirm which ecosystems the copy you carried in actually covers before reading an empty result as a clean one.
- Running on your machine says nothing about how much the review finds. That is a separate argument, made with a measurement, and it is made further up this page rather than implied by the word offline.
- This is a read of your code and your configuration. It does not attack a running system, and it is not a substitute for someone paid to try.
- Code analysis covers Python, JavaScript, TypeScript, Go and Java, plus Salesforce Apex in the Salesforce build. There is no Ruby, no C#, no PHP and no Kotlin parser, so a project in any of those gets dependency matching from its manifest and nothing else. That list is written here rather than left to be discovered after installing.
- A disconnected machine cannot refresh anything on its own. The vulnerability archive is as current as the copy somebody carried in, which is a property of the constraint rather than a shortcoming of the tool.
Evaluate it the way you will run it: disconnected.
Your first sign-in starts a 14-day trial of the full product. For an air-gapped evaluation, write to license@vulkro.com for the air-gap licence file and the offline vulnerability archive, and the machine never needs a route out at all.
Everything here runs on the same engine
Vulkro reviews your codebase and Vulkro for Salesforce reviews your Salesforce build. Vulkro Red is the other half of the team: it takes what the review found and works out what an attacker would actually do with it.