eleven / messenger Public

docs: add the Stripe secrets to the inventory (#762)

Billing shipped (#628/#649) and paid access levels (#703) added four Stripe
secrets that docs/secrets.md never picked up, breaking its own same-PR rule.
Add a Billing section (live secret key, cloud webhook secret, per-instance
Connect pair) and widen the connect-broker bullet to the multi-provider
registry env names (Stripe/HubSpot OAuth client secrets, not just
DNSimple/GitHub).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 6c582f52c8b1e967a94de5fc1afc04a34dfbb79c parent 8557183
1 file changed, +36 −5
  • docs/secrets.md +36 −5
diff --git a/docs/secrets.md b/docs/secrets.md
index ea759c6..a9cd97c 100644
--- a/docs/secrets.md
+++ b/docs/secrets.md
@@ -91,11 +91,14 @@ live in `CLAUDE.local.md` and 1Password, not here.
held in sidecar session state, able to decrypt exactly the threads the bot
was added to. *Rotate*: there is no key rotation — remove the bot member
(admin API) and re-provision a fresh identity via `add-bot`.
-- **Connect broker: admin token + provider OAuth client secrets (DNSimple,
- GitHub) + per-instance broker tokens** — the broker persists no OAuth user
- material, so the client secrets gate only the ability to *initiate* flows.
- *Rotate*: provider secrets at the provider dashboard + broker env swap;
- instance tokens via the broker admin API.
+- **Connect broker: admin token + provider OAuth client secrets + per-instance
+ broker tokens** — one client id/secret pair per OAuth-capable service in the
+ integrations registry (DNSimple under its legacy env names; every other
+ service — GitHub, Stripe, HubSpot, … — via `LCHAT_OAUTH_<ID>_CLIENT_ID` /
+ `_CLIENT_SECRET`). The broker persists no OAuth user material, so the client
+ secrets gate only the ability to *initiate* flows. *Rotate*: provider
+ secrets at the provider dashboard + broker env swap; instance tokens via the
+ broker admin API.
## Provisioning & DNS
@@ -109,6 +112,34 @@ live in `CLAUDE.local.md` and 1Password, not here.
*Rotate*: admin/control tokens by env swap + restart; caller tokens via
the cloud admin API.
+## Billing (Stripe)
+
+- **Stripe secret key** (`LCHAT_STRIPE_SECRET_KEY`) — the **live** key the
+ cloud provisioner uses for space-upgrade Checkout, the Billing Portal, and
+ subscription webhook reconciliation. *Blast radius*: full API access to the
+ Stripe account — customer emails and subscription state, refunds,
+ cancellations. No message content (Stripe never sees the product), but the
+ worst non-signing secret to lose. *Rotate*: roll the key in the Stripe
+ dashboard (pick a grace window so the swap is zero-downtime), swap the cloud
+ env, restart.
+- **Stripe webhook signing secret** (`LCHAT_STRIPE_WEBHOOK_SECRET`) —
+ authenticates Stripe's event posts to the cloud webhook endpoint. *Blast
+ radius*: forge checkout/subscription events → mint or revoke space
+ entitlements without payment; no access to the Stripe account itself.
+ *Rotate*: roll the endpoint's signing secret in the Stripe dashboard, swap
+ the cloud env, restart.
+- **Stripe Connect platform key + webhook secret**
+ (`LCHAT_STRIPE_CONNECT_KEY`, `LCHAT_STRIPE_CONNECT_WEBHOOK_SECRET`) —
+ per-*instance* env powering paid access levels (member subscriptions via
+ Stripe Connect). Deliberately tri-state: both unset → feature off; a partial
+ config warns and stays off. *Blast radius*: the platform key can also act on
+ connected accounts (sellers' Stripe accounts) within the platform's
+ permissions; the webhook secret forges membership entitlements on that
+ instance. *Rotate*: same shapes as the cloud pair above.
+- Kept alongside but **not secrets**: `LCHAT_STRIPE_PRICES` (the price book —
+ price ids are public by the time Checkout renders) and
+ `LCHAT_STRIPE_PORTAL_CONFIG` (a portal configuration id).
+
## AWS (from the #550 build-out)
- **`dev-agent` access key** — AdministratorAccess on the dev account, for