Stripe says one restricted key per service: Sume scopes per job

Stripe recommends restricted keys, one per service. Sume keys have fixed scopes. Map each webhook operation to its scope and give the handler no more.

5 min readSume
All posts

Stripe's restricted-key page recommends giving each service its own key with only the permissions it needs, and it names a webhook handler as one such service. Sume has the same idea with named scopes. A handler that only verifies and stores events needs no Sume API key at all, only the signing secret, and each operator action maps to one scope.

What Stripe recommends

Stripe describes restricted keys as keys where you choose Read, Write or None per resource, and says they limit the damage if a key leaks. It says to create a separate restricted key for each service, such as a billing service, a reporting service and a webhook handler. It also notes that Write permission includes Read for the same resource.

Sume operations and the scope each needs

From the Sume webhooks pages, these are the calls around a webhook and the scope each one requires. Scopes are fixed when a key is created and cannot be added later, so a key that lacks one needs replacing.

Webhook operations and scopes (Sume docs; Stripe page read 2026-10-02)
OperationCallScope
Read the signing secretGET /v1/webhooks/signing-secretaccount:read
Rotate the signing secretPOST /v1/webhooks/signing-secret/rotateaccount:write
Send a test deliveryPOST /v1/webhooks/test-deliveriesaccount:write
Redeliver a job webhookPOST /v1/jobs/{job_id}/webhook/redeliverjobs:write
Redeliver a Format run webhookPOST /v1/format-runs/{run_id}/webhook/redeliverformats:write

A split that follows the advice

A request without the right scope fails with 403 insufficient_scope, never 404, according to the run webhooks page. That error is useful when you test a new key: if a redeliver call is refused, the scope is the first thing to check.

  • The receiving handler: no API key. It holds SUME_COM_WEBHOOK_SIGNING_SECRET and verifies each request.
  • A recovery job that redelivers failed jobs: a key with jobs:write only.
  • A deploy script that rotates the secret: a key with account:write and account:read, used by the pipeline only.
  • Format redelivery: formats:write on its own key, so a leak of the job key cannot touch Formats.

What I did not verify

The docs I read name these scopes for the webhook calls. They do not say whether a write scope implies the matching read scope, as Stripe's does. Do not rely on it, and grant each scope you need.

Operational habits

Name keys for their job, such as webhook-redeliver or secret-rotation, so the dashboard list tells you what a leak would expose. Create a new key and delete the old one when someone leaves or a pipeline changes, since scopes cannot be edited on an existing Sume key.

Store each key in the secret manager of the one service that uses it. A key that appears in two systems is two leak paths. Stripe's page makes the same point when it says to use one key per service, and its advice to audit request logs applies on Sume too: look at which calls a key actually makes and remove any scope it never uses when you next replace it.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume