Skip to main content
Interactive approval is now the default for dangerous built-in tools — no configuration needed. When an agent calls a sensitive or external tool, PraisonAI pauses and asks you before it runs. Your choices can be saved as project rules for next time. See Approval for the full list of gated tools and bypass options.
from praisonaiagents import Agent

agent = Agent(
    name="Coder",
    instructions="Edit files as requested",
    approval=True,
)
agent.start("Refactor utils.py")
The user requests a change; PraisonAI pauses on dangerous tools until they allow or deny in the terminal.

Quick Start

1

Simple Usage

from praisonaiagents import Agent

agent = Agent(
    name="Coder",
    instructions="Edit files as requested",
    approval=True,
)
agent.start("Refactor utils.py")
2

With Configuration

praisonai --approval console run "Show me git status"
A prompt appears:
⚠ Tool Approval Required
Tool: bash(command='git status -s')
Risk: medium
Agent: Coder

Options:
  [a] Allow once
  [A] Always allow this command (bash:git status *)
  [T] Always allow ALL uses of bash (bash:*)
  [d] Deny
  [D] Always deny (persist rule)

Your choice:
[A] persists the narrowest reasonable pattern (command-prefix for shell tools, first-arg literal for others). Only the explicit [T] choice grants blanket bash:*.

When approval is required

Approval runs when any of these apply:
  • The agent has approval=True (or a CLI --approval backend)
  • The tool is in the default dangerous-tools list (e.g. bash, write, delete)
  • The tool has trust_level == "external" in the tool registry

Change Preview

Before you press [A] on a file-mutating tool, PraisonAI prints a preview so you approve the actual change — not just the tool name. For edit / apply_patch (unified diff supplied by the caller):
Preview (diff):
--- a/utils.py
+++ b/utils.py
@@ -1,3 +1,3 @@
-def add(a, b): return a+b
+def add(a: int, b: int) -> int: return a + b
For write (up to 2000 chars, truncated after):
Preview (content to utils.py):
def add(a: int, b: int) -> int:
    return a + b
No preview is shown for read-only or non-file tools.

Denial Steering

Pressing [d] or [D] opens a follow-up prompt for an optional reason, which is passed back to the agent as feedback so it can correct course instead of aborting.
Your choice: d
Reason for denial (optional, steers the agent): use `git diff --stat` instead — this diff is too noisy
Empty input skips feedback. Non-interactive shells (CI, PRAISONAI_NON_INTERACTIVE=1) skip the prompt entirely — the run stays fail-closed and denials carry no feedback.

Approval modes

CLI flagPermissionModeValueBehaviour
--approval consoleDEFAULTdefaultPrompt for each sensitive call
--approval planPLANplanBlock write, edit, delete, bash, shell
--approval accept-editsACCEPT_EDITSaccept_editsAuto-approve edit/write tools
--approval bypassBYPASSbypass_permissionsSkip all checks
The CLI uses --approval bypass but the enum value is bypass_permissions.

Persistence

Press [A], [T], or [D] to write a PermissionRule to .praisonai/permissions/rules.json (priority 100, scoped to the project directory). The two allow choices persist different scopes:
ChoiceScopePersisted pattern example
[A] Always allow this commandNarrow command-prefixbash:git status *, edit:utils.py, write:.env
[T] Always allow ALL uses of <tool>Blanketbash:*, edit:*, write:*
[A] uses the shared derive_pattern helper so the CLI, YAML --allow/--deny, and Python PermissionManager all scope identically. Compound commands (&&, |, ;, $(...)) fall back to a literal single-use pattern so a persisted rule can only match the exact invocation you approved.
Tune the derived pattern with Reusable Approval Scopes — call PermissionManager.suggest_scope_pattern(target) for a custom UI, or hand-author bash:git * via praisonai permissions allow.
Manage rules with:
praisonai permissions list
praisonai permissions allow "bash:git *"
FileShared?
rules.jsonYes — commit for team rules
approvals.jsonNo — local session data
Each entry carries pattern, approved, scope, created_at, expires_at, agent_name, and a derived flag. derived: true marks approvals whose pattern was auto-generated by reusable command-prefix scopes — user-edited or hand-authored patterns save with derived: false. Old files without the field load cleanly (derived defaults to False).
When building a custom UI or CLI wrapper, call PermissionManager.suggest_scope_pattern(target) to get a derived prefix glob (e.g. bash:git status * for bash:git status -s) before saving a session or always approval. Show the suggestion to the user, let them tweak it, then pass the final value as pattern= to approve(). See Reusable Approval Scopes.

Non-interactive and CI

praisonai --yes --approval console run "Check deployment"
PRAISONAI_NON_INTERACTIVE=1 praisonai --approval console run "Check deployment"
Without a TTY, prompts default to deny so CI pipelines fail closed.

Best Practices

Use --approval plan until you trust the agent’s behaviour in a codebase.
Tools marked external always prompt — verify third-party integrations before allowing.
Team-wide allow/deny patterns belong in version control.
[A] scopes to the specific command-prefix (shell tools) or first-arg literal (other tools), while [T] is the only path to <tool>:* — use [A] for daily work and reserve [T] for tools you already trust project-wide.
The preview is your last chance to catch an unintended edit. It renders for edit, write, and apply_patch so you approve the actual change, not just the tool name.
A reason turns a rejection into a correction — the agent can re-plan rather than abort the whole run.

Bot/chat-channel approvals

This page covers the CLI/terminal approval flow. When running PraisonAI on Telegram, Slack, or Discord, approvals render as interactive buttons and are actor-bound — only the requester and configured admins can resolve them.

Interactive Callback Authorization

Lock approval buttons to specific users in shared chats — covers Telegram, Slack, and Discord bots.

derive_pattern — shared narrow-pattern derivation used by CLI, YAML, and Python rules

Permissions CLI

praisonai permissions reference

Permission Modes

All modes for agents and CLI

Permissions Module

Python SDK API