Stripe restricted keys for AI agents: let an agent handle refunds without a secret key

Stripe now has a way to hand an AI agent a key: a restricted key tagged for agent access, with approval rules on refunds and payouts by default. Here's a setup for a refund agent.

The short answer

Never give an AI agent a Stripe secret key (sk_...). A secret key has unrestricted permissions on all Stripe APIs, and Stripe no longer recommends them for new use cases.1 Give the agent a restricted API key (rk_...) with only the permissions it needs, and when you create it, tag it as authorising agent access to your account. Stripe calls this the recommended way to give autonomous agents access: agent-tagged keys are automatically subject to approval rules, and by default a refund, a subscription cancellation, a payout, an outbound payment or transfer, or a currency conversion they start waits for a designated reviewer.13

Every MCP tool call goes through your rules first. Here a delete that doesn’t say which rows is stopped before it reaches the database. These are the rules deedglass init starts with; the call is made up.

Secret key, restricted key, agent key

Key What it can do For agents?
Secret sk_... Everything, on every Stripe API No: Stripe recommends moving secret key usage to restricted keys1
Restricted rk_... Only the resources you set to Read or Write; everything else is None by default2 Yes, as the base
Restricted, agent-tagged Same permissions as a restricted key, plus automatic approval rules for sensitive actions1 Yes, Stripe’s recommended setup

The agent tag doesn’t change what the key can authenticate to. It changes governance: sensitive actions it starts become approval requests instead of happening immediately.1

Permissions for a refund agent

Stripe’s method for setting permissions is empirical: start in a sandbox with a restricted key, run the integration, read the key’s request logs, and map each successful call to a permission. GET calls need Read; POST and DELETE calls need Write; Write includes Read. If a key lacks a permission, Stripe returns an invalid request error whose message names the permission to add.2

For an agent that looks up a customer’s payment and issues a refund, a starting point to test in a sandbox might be:

Resource Permission Why
Refunds Write To create the refund
Payment Intents Read To find the payment being refunded
Charges Read Older integrations refund by charge
Customers Read To confirm whose payment it is
Everything else None Payouts, payment methods, products, Connect, Billing

Then run the agent’s whole flow in the sandbox and trim anything the request logs show it never used. One restricted key per service or use case is Stripe’s advice, so a compromised agent key can’t touch what the billing service does.2

Approval rules: what waits for a person

Stripe keeps default approval rules for these actions by agent-tagged keys: refund created, subscription cancelled, outbound payment, outbound transfer, payout, and currency conversion.3 When one triggers:

  1. The action is interrupted and an approval request is created.
  2. A designated reviewer approves or denies it in the Dashboard. A user can’t approve their own request.
  3. Approved actions complete automatically; denied ones are discarded with no change.
  4. Requests not approved within 14 days expire.3

You can edit the default rules’ conditions and reviewers. Useful conditions include an amount threshold (approve refunds above a limit only), an actor condition (only agent-tagged keys), and a rate limit (approve when there are more than N requests in a window). A rule can also block an action outright instead of pausing it.3

On a single-person Stripe account, two-party approval can only be saved with the actor set to agent-tagged keys, because the agent key counts as an actor separate from the administrator.3 That’s the setup a solo founder wants anyway.

Handling approval_required in your agent

When an agent-tagged key hits a rule, Stripe returns an approval_required error and submits the approval request itself.3 Your agent code has to treat that as “pending,” not “failed”:

  • Don’t retry. A retry creates a second request for the same refund.
  • Tell the user plainly: “The refund is waiting for approval,” not “Done.”
  • Attach a reason. Stripe lets you update the approval request with a justification, such as the support ticket the refund came from.3
  • Listen for the outcome. Events such as v2.core.approval_request.approved, .rejected, .expired, .succeeded and .failed tell you what happened.3 Only succeeded means money moved.

The last point matters for any agent that reports its own work. “Approved” and “completed” are different events; an approved action can still fail when it runs.

Lock the key down

Permissions limit what the key can do. These limit who can use it:1

  • Access policies. Restrict the key to known IP addresses or CIDR ranges, or with an advanced policy by network (ASN), country and blocked sources such as Tor exit nodes. Stripe blocks other requests and notifies you. Stripe recommends policies on all live keys.
  • A secrets vault, not a file. Stripe says not to put keys in source code or in configuration files checked into version control. For agents, that includes .env files the agent can read; our post on API keys in .env files covers why.
  • Rotation. Rotating revokes the key and issues a replacement; in the Dashboard both keys work for up to 7 days so you can migrate without downtime.
  • Logs. Each key has request logs in Workbench. Check them weekly for calls you didn’t expect.

What this doesn’t cover

  • Actions outside the default rules. A key with Write on Customers can change customer details without approval unless you add a rule; approvals are supported for a specific list of actions.3
  • Whether the refund was right. The reviewer sees the request; deciding it’s correct is their job. Give them the context: the ticket, the order, the reason.
  • Other tools in the session. If the same agent can send email or post to Slack, the approval on refunds doesn’t cover those. Human-in-the-loop approval explains the pattern for tool calls generally.

A checklist

  • No sk_ key anywhere the agent can read.
  • A restricted key, tagged for agent access, one per agent or service.
  • Permissions set from sandbox request logs; everything unused is None.
  • Default approval rules kept, with reviewers who’ll answer within a day.
  • Amount thresholds or rate limits added where useful.
  • The agent treats approval_required as pending and doesn’t retry.
  • An access policy on the live key.
  • Request logs reviewed weekly.

Our guide to Stripe refunds shows the same approval idea applied at the tool-call level, in front of any key. To see what the agents configured on your machine can change, paste the config into the check page or run npx deedglass scan (how the grade works); to try the checks in your browser first, open the playground.

Written with AI assistance and checked against our claims register.

The takeaway

Give agents an agent-tagged Stripe restricted key: refunds and payouts it starts wait for a reviewer by default, and requests not approved in 14 days expire.

Read nextYour AI coding agent can read your .env file. Here's what stops it, and what doesn't. Try it: install in 7 s

Related on this site

More posts

Sources

  1. 1Stripe docs: API keys · docs.stripe.com · checked 26 October 2026
  2. 2Stripe docs: Restricted API keys · docs.stripe.com · checked 26 October 2026
  3. 3Stripe docs: Set up two-party approvals · docs.stripe.com · checked 26 October 2026

Published 26 October 2026, sources last checked 26 October 2026. If something here is out of date, write to hello@deedglass.com.

Try it on your own setup

npx deedglass scan

Grades only your own setup. Nothing is uploaded.

Pricing