A Stripe key that can only read
Stripe restricted keys are set per resource, so a read-only key is something you build rather than something you pick.
The four permissions, and what each one powers
In Stripe, go to Developers, then API keys, and create a restricted key. You are given a long list of resources with a Read, Write or None selector against each. Four go to Read.
Charges (read) powers every revenue figure on the site — the headline total, the trend, refunds, revenue by product and by country, and the orders table itself. Subscriptions (read) powers monthly recurring revenue, the active and cancelling counts, the subscription mix and the subscriptions table. Customers (read) powers the buyer name and email on an order at a provider that does not put them on the order itself, and the mirrored customer records. Products (read) powers the products table — what you sell, with what it has earned beside it wherever the provider attaches a product to an order.
- Charges
- Read — every revenue figure and the orders table
- Subscriptions
- Read — recurring revenue and the subscriptions table
- Customers
- Read — buyer details a charge does not carry
- Products
- Read — the products table
Everything else stays at None
The list Stripe shows you is long, and the temptation is to grant read on things that sound harmless — Balance, Payouts, Invoices, Events. None of them are read here, so granting them adds access that is carried around and never used.
The write column is the one that matters. Nothing in this product ever writes to Stripe, so every Write selector can stay at None, and a key built that way cannot do anything to your account whatever happens to it afterwards. That is a stronger position than any assurance on this page, because it does not depend on us.
What happens if you miss one
Nothing breaks loudly, which is the problem this section exists to prevent. Each of the four resources is requested when you connect and again on every refresh, and the ones that come back 403 are recorded. A resource that cannot be read is skipped rather than failing the whole sync, so a key missing Products still refreshes orders.
The consequence is that the figures that permission powered simply stop changing, which looks exactly like a quiet week. That is why the result is stored against the account and why a change is reported in both directions — losing a resource means figures silently stopped updating, and gaining one means somebody edited the key's permissions, which is the closest honest signal available that write access may have been added too.
Only a 403 counts as a missing permission. A rate limit, a revoked key or a Stripe outage propagates as a real error instead, because recording those as a narrower key would raise a false alarm on the very next refresh.
Replacing or revoking the key
There is no replace-the-key screen today, and this page is not going to imply one. Changing the credential means disconnecting the account here and connecting it again with the new one. Disconnecting deletes the mirrored copy of that account's rows, which is why it is confirmed in place with a sentence naming exactly what goes; the first sync after reconnecting rebuilds it from Stripe. Nothing is lost permanently, but it is a rebuild rather than a swap, so do it when you can wait for a sync.
Revoking the key at Stripe without reconnecting is the gentler case: the account and its last-synced figures stay exactly where they are, and the failure is recorded against it rather than silently swallowed.
While it is stored, the key is encrypted with AES-256-GCM under a per-value random initialisation vector before it reaches the database, and decrypted only inside the sync. Nothing derived from it beyond a short hint is ever sent to the browser.