PermissionPrompt
StableAsks you to allow one thing the assistant wants to do, with a choice to always allow it and an optional note.
Also known as permission request, allow deny, access request
Install with npm install @tattva/ui (setup), or copy the code from the kit in Downloads.
Saving a choice for next time
Send an email
Send the weekly update to your team
To: team@example.comThis command requires approval
<PermissionPrompt
tool="Send an email"
description="Send the weekly update to your team"
target="To: team@example.com"
ruleScope="Emails to team@example.com"
ruleCovers={["Emails to team@example.com"]}
ruleLifetime="Saved for this project"
/>Choose Allow always to see what the saved choice covers before you confirm.
When to use it
Asks before the assistant does one thing that needs a person's yes. It shows the exact command or target, so people approve what will really happen, and can save the choice for a clearly named group of actions.
Made of: Title of the step · Who asked (optional) · Description · Exact thing it will act on · Reason · Choices · Esc key hint beside Deny · What a saved choice covers · Add a note button with N key hint · Note box and hint · Confirm button · Summary of your choice
Use it for
- Before a command, file change or web request that needs approval.
- Letting people allow an action once, for this session, or always for a named group.
- Letting people send a note with their decision to steer the assistant.
Not for
- A plain yes or no with no saved choices: use ApprovalPrompt.
- Changing how much the assistant may do in general: use PermissionModeSwitcher.
- A question with several possible answers: use AgentQuestionCard.
Do and avoid
Delete files
Clear out old downloads
Downloads/old-photosThis command requires approval
Do
- Show the exact thing it will act on, not a loose summary.
- List everything a saved choice would allow.
- Offer only Allow once when you cannot show everything a saved choice would allow.
- Name the helper when a background task is asking.
- Tell people the note box is where they can adjust their choice.
Avoid
- Don't pick Allow always for people. Allow once is selected first.
- Don't jump the cursor into the prompt unless the assistant is stuck waiting.
- Don't use it for a risky action that needs one clear yes or no. Use ApprovalPrompt.
- Don't rely on the keys alone. Deny, Add a note and Confirm also work with a mouse, a tap, or Tab.
- Don't change what Tab does. It keeps moving to the next control.
On a phone
- The Escape to deny and N for a note shortcuts need a keyboard, so on a phone people use the choices and the confirm button.
- Long commands and file paths scroll sideways inside their own boxes instead of wrapping.
- The note field is 44px tall with 16px text on a touch screen.
- The choice rows grow to at least 44px tall on touch screens.
Seen in products
- In Claude Code Manual mode a Bash prompt shows the description ("Run the test suite"), the command, a "This command requires approval" line, then "Do you want to proceed?".
- The Claude Code options are Yes, Yes and don't ask again for `npm test *`, Yes and switch to auto mode, and No.
- The Claude Code footer reads "Esc to cancel, Tab to amend", so the user can add a comment to the approval. On the web, Esc denies and the note field replaces Tab to amend.
- Claude Code Bash and WebFetch approvals persist per repository, and file edits last until session end.
- Claude Code offers only one-time approval on some prompts when the UI cannot show everything a rule would allow.
- Claude Code saves one rule per subcommand (up to 5) for compound commands, so the UI must list them, and read-only commands skip prompts.
- Vercel AI Elements ships a Confirmation component.
- Claude in Chrome shows a dialog "Claude in Chrome wants to" with an "allow all actions on this site" option.
- In Claude Code, background subagents' permission prompts surface in the main session labeled with the subagent's name.
Properties
| Prop | Type | Default | Description |
|---|---|---|---|
| toolrequired | string | none | Kind of action, such as "Bash command". Used as the title and the section name. |
| descriptionrequired | string | none | Plain description of what the action does. |
| targetrequired | string | string[] | none | The literal command or target. An array lists each subcommand of a compound command. |
| reason | string | "This command requires approval" | Why the person is being asked. |
| requestedBy | string | none | Name of the subagent that asked, shown as a badge. |
| sessionScope | string | none | What a session-only approval covers. Adds the middle choice "Allow for this session" (choice "session", state "allowed-session", result "Allowed for this session"). Omit to hide it. |
| ruleScope | string | none | Scope of the saved rule, such as `npm test *`. Omit to offer only Allow once. |
| ruleCovers | string[] | none | Exactly what a saved rule covers, one entry per rule. Falls back to ruleScope. |
| ruleLifetime | string | none | Where and how long a saved rule lasts. |
| onceOnlyReason | string | none | Explains why there is no saved-rule option. Shown when ruleScope is omitted. |
| state | "pending" | "allowed-once" | "allowed-session" | "allowed-rule" | "denied" | none | State, for controlled use. Uncontrolled it starts pending and follows the choice. |
| onStateChange | (state: PermissionState) => void | none | Called after Confirm or Esc with the new state. |
| onDecide | (decision: { choice: "once" | "session" | "always" | "deny"; note: string }) => void | none | Called after Confirm, or after Esc with choice "deny". Carries the choice and the trimmed note. |
| autoFocus | boolean | false | Move focus to the first choice on mount. Use only when the agent cannot continue until the person answers. |
| labels | PermissionPromptLabels | none | Replace choice text, the note label, hint and placeholder, and the scope heading. The Esc and N key hints are fixed. |
| className | string | none | Extra classes on the section. |
"Show code under the preview gives the code for the example on the stage."
In Figma
In Figma, one PermissionPrompt switches all of this from its properties panel, across 5 variants. Each property sets the React prop beside it, so design and code use the same names.
| Figma property | React | Values |
|---|---|---|
| Status | state | Pending, Allowed-once, Allowed-session, Allowed-rule, Denied |
| Tool | tool | Any text |
| Description | description | Any text |
| Target | target | Any text |
Tokens
Change one of these and every part that uses it follows.
--code-bg--code-fg--surface-sunken--border--success--danger--radius-control--radius-field--radius-card
Built in
- The prompt is named "Permission needed" plus the step, and the choices work with the arrow keys.
- Escape anywhere inside the prompt denies, and N opens the note box unless you are typing. Screen readers are told about both keys.
- The reason is read with the choices, and the note box has a label and a hint.
- The Add a note button says whether the note box is open.
- After a choice, the result is shown with an icon and words, not only a color, and keyboard focus moves to it.
- A decision made elsewhere, such as from another screen, is announced to screen readers.
What you need to do
- Set autoFocus only when the assistant cannot continue without an answer. Otherwise leave people where they are.
- Write a reason that says why this step needs a yes.
Built toward WCAG 2.2 AA and checked automatically; no independent audit yet. Read the accessibility guide