Permission Policies
Control which agent tool calls auto-approve, which ask for permission, and how Pushary reaches you when they do
A policy decides what happens when your agent is about to run a tool — run it silently, ask you on your phone, ask in the terminal, or just notify you. Policies are matched per tool (Bash, Write, Edit, …) with a * fallback, and they only apply to agents that run through the Pushary hook (Claude Code and Codex today).
Policies are evaluated by the PreToolUse hook installed by npx @pushary/agent-hooks setup. Agents connected over MCP only (Cursor, Windsurf, Hermes) send notifications and questions, but don't gate tool calls — there's no hook to enforce a policy.
The four approval modes
Every policy has a mode that decides where the approval happens.
| Mode | What the agent does | You are asked… |
|---|---|---|
push_first | Sends a push, waits a few seconds, then falls back to the terminal if you don't tap | On your phone and the terminal |
push_only | Sends a push and blocks until you answer or the timeout fires | On your phone only |
terminal_only | No push at all | In the terminal only |
notify_only | Sends a one-way "Agent needs approval" notification, never blocks | Nowhere — the terminal decides immediately |
push_first (the default)
Sends the approval as a push question, then polls for up to pushFirstSeconds. If you tap Yes it runs; No denies it. If you don't answer in time, the hook returns control to the terminal but leaves the push live — so you can still approve from your phone, or from the terminal, whichever you reach first. This is the recommended default: you get the phone prompt without ever being blocked at your desk.
push_only
Sends the push and blocks the agent until you answer or timeoutSeconds elapses. On timeout it applies the policy's timeout action (see below). Use this for genuinely destructive operations where you want the agent to wait for an explicit human decision.
terminal_only
No notification is sent — the agent's own terminal prompt handles approval. Use this for tools you always want to approve at the keyboard.
notify_only
Fires a one-way notification (title "Agent needs approval", body = the tool description) and immediately hands back to the terminal. The agent never waits on Pushary. Use this when you want awareness but not a remote gate.
If Pushary is unreachable, the hook fails open to the terminal — it returns ask with the reason "Pushary unavailable, falling back to terminal approval". An offline agent can't reach your phone anyway, so it defers to the safest available approver: you, at the keyboard.
Policy fields
Prop
Type
The auto-approve shortcut
A policy with timeoutSeconds: 0 and timeoutAction: "approve" is allowed silently — no push, no terminal prompt, regardless of mode. This is how read-only tools stay frictionless, and it's exactly what Teach-on-Tap writes when you say "always allow."
The one thing that overrides the auto-approve shortcut is the kill switch. A halted session is denied before the shortcut is checked, so even silently-approved tools stop.
Default policies
Until you customize them, a new site uses these defaults (catch-all * plus a few well-known tools):
| Tool | Timeout | If no response | Mode | Push first |
|---|---|---|---|---|
Bash | 60s | Auto-deny | push_first | 20s |
Write | 60s | Ask in terminal | push_first | 20s |
Edit | 45s | Ask in terminal | push_first | 20s |
Read | 0s | Auto-approve | terminal_only | — |
* (default) | 60s | Ask in terminal | push_first | 20s |
Read ships with the auto-approve shortcut so file reads never interrupt you. Bash defaults to auto-deny on timeout — if you don't approve a shell command, it doesn't run.
Policies are cached locally for 5 minutes (in your temp dir as pushary-policy-<hash>.json), so editing a policy in the dashboard can take up to 5 minutes to take effect on a running agent, or restart the agent to pick it up immediately.
Editing policies in the dashboard
Open the policy editor
Go to Dashboard → Agent → Policies. Each row is one tool pattern.
Set the mode and timeouts
For each tool choose a Mode, a Timeout (0–300s), and an If no response action (Auto-approve / Auto-deny / Ask in terminal). The Push first field is only editable when the mode is push_first.
Add a rule for a specific tool
Type a tool name (e.g. Bash) and Add rule to override the * default for just that tool. The * row is the catch-all and can't be deleted.
From the command line
The pushary mode command sets a temporary, site-wide mode override that wins over per-tool modes until it expires:
pushary mode push_only --for 30m # force push_only for 30 minutes
pushary mode status # show the current override
pushary mode clear # back to per-tool policiesDurations are <n>m or <n>h. The override is always TTL'd server-side, so a forgotten override self-heals.
Teach-on-Tap: "always allow this tool"
When a push question is about a specific tool, the decision page shows a button: "Always allow <tool> — stop asking." Tapping it approves the current call and mints a durable policy for that tool so you're never asked again.
Under the hood it writes a policy with timeoutSeconds: 0, timeoutAction: "approve", mode: "push_only", pushFirstSeconds: 0 — which trips the auto-approve shortcut on every future call.
Teach-on-Tap is scoped per site and per exact tool name (e.g. Bash). It is not scoped to one agent or one project — once you always-allow Bash, every agent on that site auto-runs Bash. Reverse it any time by editing or deleting the rule in the policy editor.