Security
How Honest MRR handles the keys and billing data you trust us with.
Last updated: October 6, 2026. This page describes our current security practices and is provided for information. It is not a contractual warranty; the terms that govern your use of Honest MRR are the Terms of Service.
Used only to read
We ask for the most limited credential each billing provider offers — a restricted, read-only key wherever one exists — and use whatever you connect only to read customers, subscriptions, prices, invoices, and charges to compute your metrics. We never initiate payments or refunds, and never change your customers, subscriptions, or settings. The one thing we may create, and only when the key you connect permits it, is a webhook endpoint in your Stripe account that points at Honest MRR, so changes reach your reports as they happen; it stays in your Stripe account after you disconnect, so delete it there if you no longer want it. Ad platforms are connected with the narrowest access each one offers (Google Ads has no read-only option), and every ad, app-store and traffic connection is used only to read reports.
Credentials encrypted at rest
Every credential you connect — billing API keys, webhook signing secrets, app-store reporting keys, ad-platform and Stripe App OAuth tokens, traffic-source keys, saved report links, and your Slack or Discord webhook — is encrypted with AES-256-GCM before it is stored. The system is designed so plaintext credentials are not written to logs and are not sent to your browser or to third parties; the app never shows more than the last four characters of a key. The encryption key can be rotated, re-encrypting every stored credential under the new key.
Tenant isolation
The data imported from your providers, and everything computed from it, lives behind Postgres row-level security: the application's database role can only see rows belonging to the organization making the request, enforced by the database itself — not just application code. The few tables outside it, such as connection records (their credentials encrypted), team membership and API keys, are filtered by organization in the application.
Sign-in and account linking
You sign in with Google, Apple, Facebook or Microsoft — whichever the sign-in page offers; we don't create password accounts. A sign-in joins an existing Honest MRR account with the same email only when the sign-in service vouches that the address is verified and that account is verified too; otherwise it is refused. If a sign-in service doesn't vouch for your address, we ask you to confirm it by email before anything else is sent to you, and the confirmation link works only while you are signed in to that same account — so a link can't confirm an address for someone else.
Roles and permissions
Every teammate has a role. Viewers can only read — enforced on the server for every change, not just hidden in the interface. Only the owner can invite or remove members, change the plan, delete a provider's imported data, hand over ownership or delete the organization; owners and admins manage API keys, share links and the public page.
API keys and share links
Metrics API keys are random, shown once and stored only as a hash. They are read-only unless you grant the import scope, rate-limited per key and per network address, and stop working the moment they are revoked; removing a teammate revokes the keys they created. Investor share links are signed, carry their own expiry of 7, 30 or 90 days, show aggregate metrics — never customer-level data — and are kept out of search engines and our analytics.
Incoming webhooks
A webhook from a billing provider is accepted only with a valid signature or token for that connection; a delivery that fails the check is rejected and nothing from it is recorded. Each event is recorded once, however many times the provider sends it.
Links you ask us to fetch
Apart from Slack and Discord webhook addresses, which must be on those services' own domains, the only addresses you can point us at are the report (CSV) links you save. We fetch those only over HTTPS on the standard port, and refuse private, internal and reserved network addresses — checked on every connection, including each redirect, so a link can't be pointed at our own network. Each read is capped in size and time.
Rate limits and browser protections
Sign-in, the OAuth flows that connect ad and Stripe accounts, webhooks and the API are rate-limited, and request sizes are capped. Every response is sent with HTTPS-only (HSTS), no-sniff and anti-framing headers, and API responses are never cached.
Error reports
When something fails, an error report goes to our error monitoring with link tokens, email addresses, cookies, request bodies and authorization headers removed, and no user identity attached.
Auditable, not opaque
We keep the latest copy of every billing record your provider sends, fingerprint every version in an append-only hash chain, and compute subscription metrics from a ledger of movements that syncing never edits. Each movement shows its ledger entry and, where we have them, the provider event and the subscription record behind it — and nothing we compute ever changes the data in your billing account: we only read it.
Tamper-evident source data
Every version of every billing record we receive is committed to a per-organization hash chain at the moment of ingest — each entry cryptographically links to the one before it, blockchain-style, so editing, deleting, or reordering an entry breaks the chain, and a verification run detects it, along with any stored record that no longer matches its last fingerprint. The journal is append-only at the database level: the application's database role cannot edit or delete its entries, and removing a provider's data adds entries that mark the removal as deliberate; only deleting the organization removes its chain. Investor share reports and monthly statements show the chain head — unless the organization has a test-mode connection, in which case they say so instead — so two copies can be compared: the same head means they were computed from the same billing records. The chain covers those records themselves: a figure computed from them can still change when a provider reports a subscription late or you change your reporting currency, and ad spend, traffic, uploaded reports and the figures you enter are not part of it.
What we can — and cannot — attest to
Integrity guarantees begin the moment data reaches Honest MRR. Deployment configuration — encryption keys, database credentials, the host environment — is supplied by whoever operates the deployment, and we use exactly what is provided: we cannot see, verify, or vouch for the security of an operator's environment files or key management. Everything downstream of ingest is covered by the guarantees above.
Your data stays yours
Any member can export the organization's data as JSON, and the owner can delete the organization — removing its data from our database at once and from our backups within 14 days — from within the app, with no support ticket. Disconnecting a provider deletes its credentials and keeps the history it brought in; the owner can delete that provider's imported data as well. The privacy policy lists everything we keep and for how long.
Reporting a vulnerability
Found something? Email us and we'll respond promptly. Please give us reasonable time to remediate before public disclosure. The same contact is published in security.txt.
