# Privacy: the tool and this website

> What the ranwhat CLI sends (only what you ask it to), what ranwhat.com collects with your consent, and what an optional account at account.ranwhat.com keeps.

Canonical: https://ranwhat.com/privacy

The first part is about the ranwhat command-line tool, the second about the ranwhat.com website, and the third about the optional account at account.ranwhat.com.

## Nothing leaves the machine unless you ask.

Not a policy but an architecture. Anything touching a secret runs locally. `live`, `update`, `login`, `whoami`, `logout`, `push` and the `--pull-usage` flag go online, and only when you run them.

### Stays local

Credentials, prompts, tool arguments, file contents, customer records. The CLI holds a provider token in memory for one call and never writes it down. The only token it saves for its own use is your own ranwhat token, at `~/.ranwhat/token` (mode 0600): the one `ranwhat login` saves for this machine, or one you save with `update --save-token`. Beside it, `~/.ranwhat/account.json` (mode 0600) notes the plan, organisation and email address the server last gave for each of the last four tokens it asked about, the saved one or one given with `RANWHAT_TOKEN` or `--token`, each filed under the token’s SHA-256 and never the token, so the CLI knows whether to mention Plus. `logout` deletes both. `clean`, when you ask it to mask secrets, first copies each transcript it changes, secrets and all, to `~/.ranwhat/backups` (mode 0600), where the copies stay until you delete them. `ledger record`, when you run it, appends to `~/.ranwhat/ledger.jsonl` (mode 0600) one line for each flagged action: its 16-character id, the agent, the time, and the rule and severity of each hit, with the SHA-256 of the line before it. It holds no command, path or secret, and it is not sent anywhere.

### Goes online, when you ask

`live`, `callers`, `--pull-usage` and `revoke N` in clean's review call the provider that issued each token, and nothing else. `revoke N` sends a leaked token to GitHub, Slack or Google to revoke it, only after you type yes. `callers` reads AWS through your own `aws` CLI, and searches GitHub's audit log by a hash of the token, never the token itself. `update` sends your token to `feed.ranwhat.com` and nothing else. A token made by `ranwhat login` belongs to one machine, and a CI token to one pipeline, so we know the day each last used its token, and nothing finer. `login`, `whoami` and `logout` talk to the same host: `login` to get a code and then this machine’s token, `whoami` with the token it is given with `--token`, or else the one in `RANWHAT_TOKEN`, or else the saved one, and `logout` with the saved one. None of them sends a hostname, operating system, user name or machine identifier. `push` is the one command that sends anything about what your agents did, as derived metadata only, and it is the one place the account holds agent data; [what it sends, and what it does not](https://ranwhat.com/privacy#push), is below. A hosted record beyond that, with payloads hashed in place, does not exist yet.

- **Read-only**: Scans introspect scopes. They never exercise a permission, and never request a write-scoped credential to run.
- **Auditable**: Pure Python standard library. No dependency tree to review before you point it at your own keys.

## And what ranwhat.com collects.

The section above is about the tool. This one is about the site you are reading, which is a separate question with a shorter answer.

- **Who**: Cenner, obrt za računalno programiranje… Reachable at `hello@ranwhat.com`, which is also how you exercise anything below. Full registered details Cenner, obrt za računalno programiranje i ostale usluge, vl. Matija Mikulinec Mikulinci 8, Zagreb, Croatia OIB 23152585818 · MB 99210363
- **Cookies**: None of ours on ranwhat.com. Google Analytics and X’s ad pixel set their own, each only if you allow that one (next two rows). Your answer is kept in your browser’s local storage so the question is asked once. The optional account at account.ranwhat.com is a separate host, and sets cookies of its own there, only when you use it and only the ones it needs to work ([Account](https://ranwhat.com/privacy#account), below).
- **Visit statistics**: If you allow it, Google Analytics loads Google’s gtag.js and records the pages you view, the page or campaign that brought you, how far you scroll, clicks on links to other sites, which Copy button you press (never the clipboard), when you start or send a form (never what you type into it), your device, browser and screen, and an approximate location that Google works out from your IP address. Google says Analytics does not log or store the IP address itself. It sets two cookies on this domain, `_ga` and `_ga_MTR111ZTTE`, which last up to two years so a repeat visit can be counted. Google signals and ad personalisation are switched off, so this is used to count visits, not to advertise to you. The data is kept for two months. Google may process it in the United States under the EU–US Data Privacy Framework. The legal basis is your consent (GDPR art. 6(1)(a), and art. 100 of the Croatian Electronic Communications Act). Withdraw it any time with [Privacy choices](https://ranwhat.com/privacy#stats). Google’s handling is described in [Google’s privacy policy](https://policies.google.com/privacy).
- **Ad measurement**: We advertise on X, and ask before measuring whether it works. If you allow it, X’s pixel loads from `static.ads-twitter.com` and tells X which pages you visited, with your IP address, your browser details and X’s own cookies, so X can connect the visit to an ad it showed you and, if you are signed in to X, to your account. If you then send the contact form, our server tells X that a message was sent, with the ad-click ID if an ad brought you here, your IP address and your browser. Never the message and never your email address. The legal basis is your consent (GDPR art. 6(1)(a), and art. 100 of the Croatian Electronic Communications Act). If you decline, or your browser sends Global Privacy Control, nothing from X loads. Change your answer any time with [Privacy choices](https://ranwhat.com/privacy#ads), also in the footer. What X does with it is in [X’s privacy policy](https://x.com/en/privacy).
- **Forms**: The contact form sends your email address, your topic and your message to a Cloudflare Worker on this domain, which checks the challenge and forwards the message to our mailbox. The Worker keeps no copy. What arrives is kept as described under Email below. The signup for release emails is described in the next row.
- **Release emails**: If you sign up for release emails, on the [updates page](https://ranwhat.com/updates) or the home page, your address goes to the same Worker, which checks the challenge and keeps the address, with the time you signed up, in a database on our Cloudflare account until you confirm. Resend then sends you one email with a link to confirm, the same day unless that day’s confirmation emails, of which we send a set number, are used up, in which case on a later day, in the order people signed up. You are on the list only once you press the button that link leads to. The link works for a week, and an address nobody confirms is deleted a week after its last email goes; one whose email has not gone 30 days after it signed up is deleted then, without it. Once you confirm, the address moves to Resend, which keeps the list and sends the release emails, and we delete our copy. Every release email has a link to unsubscribe, which takes you off the list at once. We do not switch on Resend’s open or click tracking. We use the list to announce releases and nothing else, and never sell or share it. Resend may store it in the United States. The legal basis is your consent (GDPR art. 6(1)(a)); withdraw it with the unsubscribe link or by writing to us. Resend’s handling is described in [Resend’s privacy policy](https://resend.com/legal/privacy-policy). The [RSS feed](https://ranwhat.com/rss.xml) carries the same news and asks nothing of you.
- **Payments**: [Plus](https://ranwhat.com/pricing#plus) is bought for an organisation, by its owner or an admin, from the account at account.ranwhat.com, and paid on Stripe’s checkout page, not ours. Stripe sells you the subscription as merchant of record, through Link: it collects your card, your name, your email address and your billing address, keeps them with the subscription and its invoices, and may offer you a Link account to manage it. We never see your card. Before an organisation’s first checkout, our Worker creates its customer record at Stripe with the email address of the organisation’s owner and the organisation’s ID, and the checkout and the subscription carry that ID, so the subscription is linked to the organisation. An owner or an admin may change that address on Stripe’s billing page. When an owner or an admin leaves, is removed, is made a member or hands on ownership, the Worker changes it back to the current owner’s, unless it is the address of someone who is still an owner or an admin and did not just hand ownership on, and tries again until Stripe takes the change. Our Worker keeps the Stripe IDs of the subscription and customer record, the subscription’s status, whether it is monthly or yearly and when it renews or ends, and the organisation it belongs to, in the same Cloudflare database, so the feed knows whether to answer and the account can show it: not your name, address or card. It reads the email address the checkout gives to send its confirmation through Resend, and does not keep it. A subscription bought on the pricing page before accounts existed, or while the account could not be used, keeps its emailed feed token, of which the database holds a hash, and we attach it to its organisation by hand. We keep those IDs for as long as the subscription exists, and afterwards as the record of a sale. The legal basis is the contract you enter by subscribing (GDPR art. 6(1)(b)), and keeping records of sales is a legal obligation under Croatian accounting and tax law (art. 6(1)(c)). Stripe may process this in the United States. Stripe’s handling is described in [Stripe’s privacy policy](https://stripe.com/privacy), Link’s in [Link’s](https://link.com/privacy), and the [terms](https://ranwhat.com/terms) cover the rest.
- **Server logs**: Cloudflare hosts and serves the site. It logs request metadata, including your IP address, to deliver pages and absorb abuse. That is our legitimate interest in running a website, and the logs are not used to profile anyone.
- **Page views**: Cloudflare Web Analytics counts visits for everyone, whatever you answer above. Your browser loads Cloudflare’s script from static.cloudflareinsights.com, which sends cloudflareinsights.com the page you view, the page that brought you, your browser and device, and how long the page took to load; Cloudflare adds your country from your IP address. It sets no cookies and stores nothing in your browser, and Cloudflare says it does not fingerprint visitors. That is our legitimate interest in knowing which pages are read, and it is not used to profile anyone.
- **Third parties**: Cloudflare Turnstile, on the contact page, on the home and updates pages once you start typing an address into the signup form, and on the account’s pages for signing in, making an account and resetting a password: the challenge that keeps the forms from being used by bots. It loads from challenges.cloudflare.com and reads signals from your browser to tell a person from a script, and our Worker checks its answer with Cloudflare, sending your IP address with it. Resend, only if you sign up for release emails, subscribe to Plus or use the account, or if someone else types your address into one of the account’s forms that email a code, invites you to an organisation or buys Plus for one whose billing email is yours (Account, below). Stripe, only when an organisation subscribes to Plus or opens its billing, and when an owner or an admin of one with a Stripe customer record leaves, is removed, is made a member or hands on ownership, so that its billing email stays the owner’s (Payments, above). Google and GitHub, only if you choose to sign in with one of them, and Have I Been Pwned, only when you choose a password for the account (Account, below). Google Analytics and X, each only if you allow it (above). The directories that list ranwhat, on the home page only (Directory badges, below). Cloudflare Web Analytics, on every page of ranwhat.com (Page views, above). Nothing else loads from anywhere else. Typefaces are served from this domain rather than Google Fonts.
- **Directory badges**: The home page shows a badge for each directory that lists ranwhat. Each badge is an image served by or for that directory, from the host named after it below, so your browser asks that host for it, and the host sees your IP address and browser like any website you load something from. It is told only that the request came from ranwhat.com, not which page. Each badge was checked for cookies when it was added, and none sets one. The directories are Cyber Vendor Guide (www.cybervendorguide.com), Launch (its image served from ranwhat.com), Maidensail (maidensail.com), MarketingDB (marketingdb.live), Noonlaunch (its image served from ranwhat.com), SaaSHub (cdn-b.saashub.com), ScrollLaunch (www.scrolllaunch.com), StartupBase (statics.startupbase.io) and Twelve Tools (twelve.tools).
- **Email**: Mail, whether written directly or sent through the form, is kept in a Gmail mailbox, so Google holds it too and may store it outside the EU. We keep the message and your address for as long as the conversation is useful, and delete it when it is not. Writing to us does not add you to any list.

### Your rights

Under the GDPR you can ask what we hold about you, correct it, have it deleted, or object to it being processed at all. Write to the address above. If we handle that badly you can complain to AZOP, the Croatian data protection authority.

### Changes

When this notice changes the commit history shows exactly what changed and when, which is more than most privacy pages can offer. It lives in the same public repository as the site.

### The install is not tracked

Installing ranwhat, and running check, watch, clean, scan or demo, sends us nothing. There is no licence check, no version ping, no crash reporter. update, login, whoami, logout and push are the only commands that talk to our server, and only when you run them. If you link a machine with ranwhat login, we know that machine exists and the day its token was last used. Beyond that we do not know how many people use it, which is occasionally inconvenient and entirely the point.

## And what the account keeps.

The account at account.ranwhat.com is optional. It manages Plus for an organisation: its members, the machines linked with `ranwhat login`, CI tokens and billing. Nothing ranwhat does on your machine needs it.

- **Its pages**: account.ranwhat.com is a separate host from ranwhat.com. Its pages load none of ranwhat.com’s scripts: not Google Analytics, not X’s pixel and not Cloudflare Web Analytics. The only scripts that run there are Cloudflare Turnstile, on the pages for signing in, making an account and resetting a password, and our own passkey script, on the two pages that add a passkey or sign in with one. Your browser sends it any cookie set for the whole of ranwhat.com, such as Google Analytics’ cookies if you allowed them there, and the account reads none of them, only its own (next row). The account stores no IP address and no user agent. Cloudflare logs requests to it as it does for this site (Server logs, above).
- **Cookies**: Four, set only on account.ranwhat.com, never sent to ranwhat.com, and each only when you use what it is for: `__Host-rw_session`, your signed-in session, set when you sign in and kept at most 30 days (the session also ends after 14 days unused, or when you sign out); `__Host-rw_signin`, which ties a sign-in form and its emailed code to your browser, set when such a form is first shown and kept an hour, or until you are signed in; `__Host-rw_oauth`, set when you choose Google or GitHub, for 10 minutes; and `__Host-rw_invite`, set when you open an invite link, for an hour, so you come back to it after signing in. Each holds random bytes, of which we keep only a hash. They are strictly necessary, so they need no consent (art. 5(3) of the ePrivacy Directive, and art. 100 of the Croatian Electronic Communications Act).
- **Your account**: Your email address, once a code typed from that inbox, or Google for an address it gives out, has shown it is yours; when the account was made and when you last signed in; and, if you set one, your password as a PBKDF2 hash, never the password itself. A password you choose is first checked against passwords known from data breaches, with Have I Been Pwned: our Worker sends it only the first five characters of the password’s SHA-1 hash, never the password. When normalising a password changes its characters, as it does with full-width letters, both forms sign in, so both are checked, each by the first five characters of its own hash. All of this is kept until the account is deleted.
- **Google and GitHub**: Optional ways to sign in. If you use one, your browser goes to Google or GitHub, which asks you to let ranwhat read your email address (and, on GitHub, your profile). Our Worker then exchanges a one-time code with them, reads your account’s ID there and the address they say is verified (on GitHub, your primary verified address), and keeps only those two, with when the link was made and last used. It stores no Google or GitHub token: GitHub’s is used for those two reads and then dropped. While you are away at the provider, we keep hashes of the random values that tie your return to your browser, which provider you chose, the page to return you to and, when you are adding one to your account, which account and session asked. That record works for 10 minutes, and is deleted within a quarter of an hour of being used or running out. If you unlink one, we keep its ID, without an address, so that it cannot link itself to your account again, for as long as the account exists.
- **Passkeys**: If you add one: its credential ID, its public key, its signature counter, whether it is backed up, the name you give it, when you added it, and the day it last signed you in. Nothing about the device, and no attestation is asked for. The account also gets a random passkey handle, which names nothing else.
- **Organisations**: Every account starts with a personal organisation it owns. An organisation keeps its name, its members and their roles, and, from its first checkout, the ID of its Stripe customer record. Everyone in it sees the other members’ email addresses, and the machines linked to it with who linked each. Someone who has left is shown as a former member to anyone who joined after they left. An invite keeps the invited address while it waits, seven days at most, and the address is cleared once the invite is used, taken back or out of date. The invite email tells the person invited who sent it and, quoted as it was typed, the name of the organisation it is for.
- **Machines**: For each machine linked with `ranwhat login`, and each CI token: the name given to it on the account page, who linked or made it and when, and the day it was last used, to the day and no finer. The token itself is kept only as its SHA-256 hash. While a terminal waits to be approved, we keep the country Cloudflare saw its request come from, to show on the approval page, and delete it with the request about an hour after the request’s 10 minutes run out. A terminal’s token unused for 90 days is revoked. A revoked machine leaves the list, but its record, name included, is kept for as long as the organisation is, so its history still makes sense.
- **Security history**: What happened and when: sign-ins and sign-outs, changes to how you sign in, machines and CI tokens linked, made, named or revoked, membership and role changes, and upgrades and billing opened. You see your own on the account page, and an organisation’s owners and admins see its membership changes. It is kept for 13 months, and never holds a code, a token, an email address, an IP address or a user agent. A session keeps a hash of its cookie and when it was made, last used and last confirmed with a code, and is deleted once it ends.
- **Codes and limits**: When you ask for an emailed code, we keep the address you typed, a keyed hash of the code and, if you are making an account with a password, the hash of that password, for the code’s 10 minutes. The record is deleted within a quarter of an hour of the code being used or running out, so an address nobody confirms does not stay. The email has no link: the code is typed. To stop abuse, requests are counted per network, per address, per account and per organisation under a keyed hash, never the IP address or the address itself, and each count is deleted a day after it starts.
- **Email**: Resend sends the account’s email: sign-in, confirmation and password reset codes, a notice when a Google or GitHub account or a passkey is added to yours, invites, and the email that says Plus is on. We keep no copy of what it sends. Resend may process it in the United States, as described in [Resend’s privacy policy](https://resend.com/legal/privacy-policy).
- **Where**: In a Cloudflare D1 database on our Cloudflare account, the same one the release list and the feed use.
- **Legal basis**: The contract you enter by making an account (GDPR art. 6(1)(b)), for the account and what it needs to work: your address, how you sign in, sessions, organisations and machines. Our legitimate interest in keeping accounts secure (art. 6(1)(f)), for the security history, the limits, the country on a terminal’s request and the breached-password check; and the organisation’s legitimate interest in inviting someone, for an invited address while the invite waits. The IDs of a sale are kept as [Payments](https://ranwhat.com/privacy#payments), above, says.
- **Deleting**: On the account page you can leave an organisation, revoke a machine, unlink Google or GitHub, remove a passkey or a password, and sign out everywhere. There is no button that deletes the account itself yet: write to `hello@ranwhat.com` from its address and we delete it by hand, with what belongs to it alone, keeping only the IDs of a sale as its record.

## What `ranwhat push` sends, and what it does not.

`push` is a Plus feature and an explicit command. Nothing runs it for you: not the hook, not `check` or `watch`, and not a schedule we set. It says what it will send and asks before it does. `push --dry-run` prints the exact JSON and sends nothing, and needs no account.

### Sent

For each flagged action, at most 100 of them, the most severe first: the id of each rule it tripped and its severity, a 16-character action id (a hash made on your machine, not the action; where an agent writes no call id, someone who guesses a plain command can check the guess against it), which agent ran it, and the time in UTC. Then counts: flagged, left out by your ignore file (counted, never listed), not listed, transcripts read per agent, how many were unreadable, by severity, by rule and by agent; the window in days and ranwhat’s version. Which machine sent it is the token that signs the request, and the body has no field to say anything else about it.

### Never sent

A command, a path, evidence, a working directory, a session id, a project name, a tool name, file contents, a secret, your hostname or your user name. The client builds the document from those few facts and reads nothing else from a record, and the server refuses a body with any other field, so a bug in the client cannot make it carry more. Ignored actions are counted and not listed.

- **Where it goes**: Only to `feed.ranwhat.com`, over HTTPS, with this machine’s token, from a machine linked with `ranwhat login` or a CI token. An organisation on Free is refused, and nothing is stored. It is stored in the same Cloudflare D1 database as the rest of the account, and no IP address, user agent or hostname is kept with it.
- **Who can read it**: Every member of the organisation the machine is linked to, on the Findings page at account.ranwhat.com, which lists each machine with when it last pushed, its counts by severity and by rule, and its newest findings. Nothing pushed is served back over the feed host.
- **How long**: Each machine’s latest push is kept whole. Before it, only a summary of the counts of each earlier push is kept, for 30 days and at most 30 pushes, and nothing at all is kept past 90 days. Pushing the same findings again changes nothing but the time it was received. This is not the 13-month record: that is a separate feature, and it is not built.
- **How to stop**: Stop running `push`. Run `ranwhat logout`, or revoke the machine on the account page, and everything that machine pushed is deleted with its token, in the same step. If an organisation leaves Plus, its machines are refused and what they pushed is deleted by the same 90-day limit. Deleting an organisation, by hand as [Deleting](https://ranwhat.com/privacy#account-deletion) says.
- **Legal basis**: The contract you enter by using Plus (GDPR art. 6(1)(b)).
