Security
Where your data goes, who can see it, how long we keep it, and when Ryvx is and isn't allowed to fire a real exploit.
This page is written for whoever has to sign off on Ryvx before your team can use it: data handling, sub-processors, retention, access control, and the authorization model, stated plainly and checked against our own code and database schema rather than written from memory.
Ryvx can also fire real, working exploits against real targets, but only when exploitation is requested and the target has been authorized. The rest of this page governs when that's acceptable and what happens when it isn't: a hard precondition for using Ryvx against anything you don't personally control, not a nice-to-have.
What "authorized" means
--i-am-authorized is required on every run against anything other than a local/loopback target. Passing it is an assertion that you own the target, or hold explicit written permission from its owner (a signed engagement letter, a bug bounty program's published scope, or equivalent) to test it.
--i-am-authorized alone is that assertion, not proof: recorded in the run's own args, but not independently checked. Real verification sits on top of it: an HTTP well-known-file domain-control challenge, the same shape as ACME's http-01 challenge. A live external target must either pass this check or have you explicitly assert ownership instead: on the CLI, that's --skip-verification-i-own-this; on a hosted scan, it's the scan form's own “Skip domain verification: I own this target and accept responsibility” checkbox. Both are loud and audited (recorded in the run's audit log, or against the scan row itself), and neither is a way around the policy: they don't prove anything technically, they're you accepting legal responsibility for the claim in place of proving it. Running Ryvx against a target you do not have explicit permission to test is a misuse of the tool and, depending on jurisdiction, may be a criminal offense (e.g. under the US Computer Fraud and Abuse Act or the UK Computer Misuse Act) regardless of what this tool allowed you to type on the command line or tick in a form.
Safeguards already built in
PoC-or-reject gate
Every finding requires a working proof-of-concept before it's recorded: the tool hard-rejects anything without real supporting evidence.
Human approval on production targets
Exploitation against a production-tagged target requires a live human approval before it fires, and auto-denies (never silently proceeds) when run non-interactively. On a hosted scan, that pause is on by default no matter which preset or plan you pick; it only lifts when the person submitting the scan explicitly ticks “Auto-approve exploitation” on the scan form itself, and that choice is recorded against the scan row. On the local CLI, three presets (Compliance-Only, OSINT to Exploit, and Full Pentest) set auto-approve by default and say so in their own --help text; every other preset leaves the gate on. A request that times out, hits a network error, or is never answered resolves to a denial, the same as an explicit no. There is no path where silence becomes an approval.
Append-only audit log
Every tool call any agent makes is written to an append-only audit log, giving a full chain-of-custody trail for what ran against a target.
None of these substitute for actual authorization: they bound what an already-authorized run can do, they don't establish that authorization exists in the first place.
Where your data goes
Local (CLI and desktop app): scan output stays on the machine that ran it, under a run directory on disk, findings, PoC evidence, traffic captures, the LLM transcripts of the scan itself, reports, and audit logs alike. Nothing about a local scan reaches us at all unless you point it at a hosted model (see sub-processors below).
Hosted platform: a scan runs inside its own Docker container on our infrastructure. Findings and scan metadata are written to our Supabase Postgres database; evidence artifacts (screenshots, HAR captures, reports) go to Supabase Storage, under a path scoped to your account and that scan. Both are described in more operational detail in our Privacy Policy.
Sub-processors: where your prompts and transcripts go
A scan's tool output, HTTP traffic, recon results, and whatever else the agent gathers, becomes part of what gets sent to a language model to produce findings and a report. That means the model provider sees it too, so we're naming it rather than leaving it generic.
Hosted scans run today on OpenRouter, routed to GLM 5.3 Flash. OpenRouter is the sub-processor your data reaches when you run a hosted scan. The container your scan runs in never holds a real, long-lived credential for it: our own proxy issues it a random, single-purpose token good for one API route and one lifetime request ceiling, and swaps it for the real key on the way out. A compromised scan container can burn its own job's request budget, and nothing more.
Our proxy constrains every request two ways. First, it pins routing to zero-retention endpoints and forces the provider to opt out of data collection, so no provider that serves your request keeps a copy of it or trains on it. Zero retention means the provider does not keep a copy of your data once the request is served. It is not encryption. Second, it restricts routing to a named allowlist of US-headquartered inference providers (Fireworks, Together, CoreWeave, DigitalOcean, DeepInfra, BaseTen, Modal and Parasail), and no endpoint outside that list is eligible to serve the request, whatever its price.
Zero retention is a promise about storage, not about geography, so we constrain geography separately. GLM is an open-weights model, and OpenRouter's zero-retention pool for it includes providers based in China, among them Z.AI (the company behind the model) and SiliconFlow. Z.AI is often the cheapest endpoint in that pool, so left unconstrained, price-first routing would prefer it. Our allowlist is exactly what stops that: Z.AI, SiliconFlow and other non-US providers are excluded, and a hosted scan routes only to the US companies named above. The proxy sets this on every request and its choice overrides anything the scan container asks for. If your policy forbids any China-origin model regardless of where inference runs, we run enterprise scans on a US-built model (xAI's Grok) instead: ask us.
Self-hosted (CLI or desktop app, running outside our infrastructure): the default model is Anthropic's Claude Sonnet, but which model runs is entirely yours to set, down to a model running on your own machine with nothing sent to any third party at all.
Retention
Scan evidence, findings, PoC artifacts, traffic captures, the LLM transcripts of the scan itself, and reports are kept for 90 days from when the scan ran, then deleted. A transcript is what the model saw and said while it worked, so a finding you dispute weeks later can be traced back to it, not just to what got filed; it's treated as evidence, on the same 90-day window and the same deletion path as everything else in that list, not a separate store with its own rules. The audit trail of what the agent did is kept separately, for 365 days, because that's what a security or compliance review still needs after the underlying evidence is gone. Billing records are kept indefinitely, as the ledger of what you were charged for.
Both windows are enforced by retention code we run ourselves. A nightly job does run unattended, but in report-only mode: it lists what is now past its window without deleting it, and the deletion itself is a command we run by hand. Stated plainly rather than implied, because the distinction is the whole point: these are the numbers the policy applies whenever it is run, not a claim that data has been erased on a schedule since launch. You can ask us to erase your account's data early, on demand, ignoring both windows entirely. Full detail (including how backups age out) is in the Privacy Policy.
Access control: who can see a scan
On the hosted platform, findings and scans are protected by Postgres row-level security, not just an application-layer check: the database itself only returns a row whereauth.uid() = user_id. A signed-in user can only ever query their own scans and their own findings. There is no policy letting a user insert, edit, or delete a finding directly either: only our own backend writes them, so a “confirmed” finding can't be fabricated or altered from the account that owns it.
Credentials: what we have, and what we don't
We hold no SOC 2, ISO 27001, or Cyber Essentials certification today, and none is currently in progress. We'd rather say that plainly than let a vague “enterprise-grade security” line imply otherwise. What we have instead is on this page: row-level-scoped database access, per-job credential isolation for the model provider, domain-control authorization before a live target is touched, a human approval gate on exploitation that fails closed, and an append-only audit trail of what an agent did. The six compliance frameworks mentioned elsewhere on this site (SOC 2, ISO 27001, PCI-DSS, NIST, CIS, CE+) describe what a Ryvx report can map findings against for your own compliance work, a feature of the product, not a certification held by us.
If you find a vulnerability in Ryvx itself
Report it privately rather than opening a public issue: email security@ryvx.dev (a GitHub security advisory on our repository also works; either way, not a public issue). Include what you found, how to reproduce it, and its impact. We don't publish a response-time SLA: Ryvx is run by one person with no ticketing system and no on-call rotation; a message gets read by a human, it just doesn't come with a guaranteed turnaround. We aim to ship a fix before any public disclosure.
If Ryvx was run against a target without authorization
If you're the operator of a target that was scanned or exploited by an instance of Ryvx you didn't authorize: that's a misuse of this tool by whoever ran it, not something we can retroactively undo. Contact whoever you believe ran the scan directly. If the run originated from a hosted instance of this project specifically (not a self-hosted copy), report it to the same security contact above: we will investigate, suspend the account responsible pending review, and cooperate with any resulting legal process.
Your scan data on your own machine
Scan findings are sensitive by definition: they describe how to break into something you own. Two things are worth knowing about how the desktop app and CLI treat them locally, stated plainly rather than left for you to discover:
Signing out locks them
The desktop app's local API requires a signed-in session, so another person on the same machine can't read your past scans through the app once you sign out. Before August 2026 it couldn't: anything on the machine could read every scan with no session at all.
Encryption at rest is opt-in
Settings → Encryption shows you the key before it will let you enable anything, because the key lives only on your machine: lose it and every past scan becomes permanently unreadable, by us as much as by anyone else. Off by default for that exact reason: silently encrypting your history with a key you've never seen is a data-loss bug, not a security feature.
It covers findings, not every file
report.md and findings.sarif stay plain text on purpose: people read one and CI tools read the other, and encrypting them would break that silently. Your dashboard settings file stays readable too. We'd rather list the exceptions than let “encrypted at rest” imply more than it covers.
Scope of this policy
This covers Ryvx itself and any officially hosted instance of it. It does not extend authorization to test any third-party system: that authorization has to come from the third-party system's own owner, independent of anything we say here.