Security
Local-first is an architecture here, not a promise.
RigorRun connects to the systems that hold your real records, using your real credentials. So the useful thing to publish is not a reassurance — it is where the boundaries actually are, what crosses them, and what this cannot defend against.
How it is built
The interface is served by the process, not by us
The runner binds a socket on 127.0.0.1 on an ephemeral port. There is no hosted console, no relay and no tunnel. A page on https cannot fetch http://127.0.0.1 in Firefox or Safari, so a hosted UI could not reach your staging box even if we wanted one — serving both halves from one loopback origin removes the problem rather than working around it.
Three checks before a request is answered
The socket is loopback-only; the Host header must be one of 127.0.0.1, localhost or ::1; and the interface is paired with a single-use code that is redeemed once for an HttpOnly, SameSite=Strict session cookie, so the code leaves the address bar immediately. Every mutating /api request is additionally checked against Sec-Fetch-Site and Origin.
Credentials go to the operating system, not into a file we invented
macOS Keychain, libsecret on Linux, DPAPI on Windows, with an owner-only file when none is present. The backend is chosen by a write-read-delete round trip rather than by platform name, and rigorrun doctor tells you which one you got. No command prints a secret, and rigorrun secrets set refuses a value on the command line, because that is shell history.
An imported project is inert until somebody agrees to it
A connector that arrived in a file is a command to run or a URL to open with your credentials. It is refused until somebody has seen it in full and said yes — a refusal rather than a warning, because opening it is the harmful act.
What leaves the machine
Three things can send a request, all three because you asked for them, and none of them to us. There is no analytics SDK, no beacon and no crash reporter in the package.
RigorRun does write a local activation.jsonl — a stage id, a timestamp, a counter and a coarse error class. It records no task content, no arguments, no results, no names, no URLs and no credentials, and there is no uploader and no endpoint. If telemetry is ever added, that is the shape it would send, and you can read the file first.
- rigorrun verify npm:…
- Downloads the named package from registry.npmjs.org so it can be pinned to the exact bytes and run in a container.
- Connecting your own system
- Requests go to the address you gave, with the credentials you configured. That is the product working; it is your server, not ours.
- An LLM-backed agent
- Only exists if you have set GROQ_API_KEY, GEMINI_API_KEY or OPENAI_COMPATIBLE_*. Then it talks to that provider. Unset, no such agent is available.
What this cannot defend against
These are carried on every verification record RigorRun writes, not only on this page.
- The container runtime daemon runs as root. RigorRun reduces blast radius but does not claim to prevent a container escape; an escape reaches the host.
- Where a state reading came only from the server’s own tools, it is corroboration and not proof: the server that may be misdeclaring a tool is the one answering the read.
- State is read from the container’s writable mounts, which is complete over durable storage and blind to state a process holds only in memory.
- Verification records are hashed, not signed. There is no HMAC, Ed25519 or sigstore attestation on a record yet, so a record proves integrity against accidental change and not against a determined author.
Reporting a vulnerability
Write to erbol@rigorrun.xyz. Include what you did, what happened, and the version from rigorrun --version. You will get a reply within 72 hours.
Please do not open a public issue for anything that could be used against somebody else's machine before it is fixed. There is no bounty — it would be dishonest to advertise one with no revenue behind it — but you will be credited in the changelog if you would like to be.
Verifying what you installed
The npm package is published from a GitHub Actions workflow that holds no npm token, using trusted publishing, and carries a SLSA build provenance attestation. You can check it against the source before you run it:
npm audit signatures
npm view rigorrun dist.integrity The source that built it is public, which is the point: provenance that points at a repository nobody can open proves very little.