All plugins

ntfy-approval

Answer Hermes' approval prompts from your phone: once selected with security.approval.transport: ntfy, each dangerous-command prompt arrives as an ntfy push notification with Approve once, Approve for session and Deny buttons, and no answer still means deny. Disclosure — once selected, anyone who can read the ntfy topic can approve dangerous commands (the one-time answer codes are in the notification), so on the public ntfy.sh default the topic name is the only secret and NTFY_APPROVAL_TOKEN is optional; each pending approval publishes Hermes' reason, the redacted command (unless send_command is false), the non-default profile name and one-time answer codes to the configured ntfy server, then reads <topic>-reply and deletes the notification; any failure or timeout is a deny; reads NTFY_APPROVAL_TOPIC/NTFY_APPROVAL_TOKEN from the profile .env, never puts the token in a notification, follows no redirects, writes no files and starts no processes.

AhmetArif02Automationv1.0.1Updated 1 month ago

About

Answer Hermes' approval prompts from your phone: once selected with security.approval.transport: ntfy, each dangerous-command prompt arrives as an ntfy push notification with Approve once, Approve for session and Deny buttons, and no answer still means deny. Disclosure — once selected, anyone who can read the ntfy topic can approve dangerous commands (the one-time answer codes are in the notification), so on the public ntfy.sh default the topic name is the only secret and NTFY_APPROVAL_TOKEN is optional; each pending approval publishes Hermes' reason, the redacted command (unless send_command is false), the non-default profile name and one-time answer codes to the configured ntfy server, then reads <topic>-reply and deletes the notification; any failure or timeout is a deny; reads NTFY_APPROVAL_TOPIC/NTFY_APPROVAL_TOKEN from the profile .env, never puts the token in a notification, follows no redirects, writes no files and starts no processes.

ntfy-approval

Answer Hermes' approval prompts from your phone.

When Hermes wants to run a command it flags as dangerous, it normally stops and waits for you at
the terminal or in the chat. With this plugin the question goes to your phone as an
ntfy push notification instead:

⚠️ Hermes needs your approval
git force push (rewrites remote history)

git push --force origin main

Answer within 5 min. No answer means deny.
[ Approve once ] [ Approve for session ] [ Deny ]

Tap a button and Hermes continues (or stops) right away. Nothing listens on your machine: the
button makes your phone post a one-time answer back to ntfy, and Hermes reads it from there.

It uses Hermes' approval transport interface, so Hermes still decides what needs approval,
redacts secrets before anything leaves the machine, checks every answer against the request, and
treats silence as a no.

Setup

  1. Install the plugin:

    hermes plugins install AhmetArif0/hermes-ntfy-approval#ntfy-approval --enable
    
  2. Get a private topic name and the next steps:

    hermes ntfy-approval setup
    
  3. Install the ntfy app (Android, iOS) and subscribe to the printed topic.

  4. Save the topic for Hermes (it goes to your profile's .env):

    hermes config set NTFY_APPROVAL_TOPIC hermes-…
    
  5. Check that a tap reaches Hermes. This sends a sample request; nothing runs:

    hermes ntfy-approval test
    
  6. Send Hermes' approval prompts to your phone:

    hermes config set security.approval.transport ntfy
    

To go back to terminal and chat prompts: hermes config set security.approval.transport builtin.

What you get

  • Approve once: this command runs, nothing is remembered.
  • Approve for session: Hermes stops asking about this kind of command in this session.
    Only shown when Hermes offers it for the request.
  • Deny: Hermes blocks the command and tells the agent not to try another way.
  • No answer before approvals.timeout (default 300 s): denied. The notification is then
    removed from your devices, and a late tap does nothing.
  • You stop the turn (/stop, Ctrl-C) while it waits: denied, and the notification is
    removed right away.

"Always allow" is never offered from the phone: an ntfy notification has room for three buttons,
and permanently allowlisting a command from a lock screen is a step better taken at the
keyboard.

Where it applies: interactive sessions, which are the CLI, TUI, Desktop, and messaging-gateway
chats. Once selected, the phone replaces the terminal prompt and the chat buttons. Cron jobs,
hermes chat -q and webhook/API sessions never ask a human, so the phone is not used there;
they follow approvals.cron_mode, approvals.single_query_mode and approvals.unattended_mode.

If ntfy can't be reached, the request is denied. To fall back to the normal prompt instead, set
security.approval.transport_fallback: builtin.

Settings

| Setting | Where | Default | |
|---|---|---|---|
| Topic | NTFY_APPROVAL_TOPIC in .env | none | Required. Treat it like a password (see below). |
| Access token | NTFY_APPROVAL_TOKEN in .env | none | For servers with access control. |
| server | plugins.entries.ntfy-approval.settings | https://ntfy.sh | The server your phone subscribes on. |
| priority | same | high | min, low, default, high or urgent. |
| send_command | same | true | false sends only Hermes' reason for asking, not the command. |

The Desktop app shows these on the plugin's settings page. Without a token the topic must be at
least 16 characters; setup makes a 39-character random one.

Self-hosting with access control

On your own ntfy server you can keep requests private and still let the phone's button post its
answer. The button sends no credentials, so the reply topic (your topic plus -reply) must
accept anonymous writes. Nobody can read it, and it only accepts one-time answer codes:

ntfy user add hermes
ntfy access hermes hermes-approvals rw
ntfy access hermes hermes-approvals-reply rw
ntfy access everyone hermes-approvals-reply write-only
ntfy token add hermes          # → NTFY_APPROVAL_TOKEN

Log in on the phone app with a user that can read hermes-approvals, then:

hermes config set plugins.entries.ntfy-approval.settings.server https://ntfy.example.com
hermes config set NTFY_APPROVAL_TOKEN tk_…
hermes config set NTFY_APPROVAL_TOPIC hermes-approvals

Security and footprint

  • register() only registers: the ntfy approval transport, the hermes ntfy-approval
    command, and one observer hook, post_approval_response, which only withdraws a notification
    Hermes has stopped waiting for. The transport stays inactive until you select it
    (security.approval.transport: ntfy).
  • Network: only to the configured ntfy server, and only while an approval is pending. The
    plugin publishes one notification, reads the reply topic until an answer, the timeout, or
    Hermes stops waiting, and then deletes the notification. Redirects are not followed, and the
    access token is never put inside a notification.
  • What leaves your machine: the notification title, Hermes' reason for asking, the command as
    Hermes redacted it (skip it with send_command: false), and three one-time answer codes. On
    ntfy.sh this passes through a public service. Use your own server if that matters to you.
  • Who can answer: anyone who can read the topic, because the answer codes are in the
    notification. On ntfy.sh the topic name is the secret, so keep it private. With access
    control, only users with read access can answer. Each code works once, only for its own
    request and button; anything else on the reply topic is ignored. Hermes separately rejects an
    answer that does not match the request or is not a choice it offered.
  • No subprocesses, downloads, file writes, config changes or background threads. It reads
    the topic and token from your profile's .env, through Hermes' profile secret scope.
  • Profiles: each profile has its own settings and topic. On a gateway that serves several
    profiles from one process, Hermes currently calls approval transports without the profile's
    context (hermes-agent #114580). The plugin detects this and denies the request rather than use
    another profile's topic.

Design notes and verified facts: DESIGN.md.

Changelog

1.0.1

Stopping a turn (/stop, Ctrl-C) while an approval was on your phone left its buttons there
until approvals.timeout ran out (5 minutes by default), and for good if Hermes exited in the
meantime. Hermes had already denied the request, so a tap did nothing. The notification is now
removed as soon as Hermes stops waiting.

1.0.0

First release: approvals from ntfy with Approve once, Approve for session and Deny buttons;
hermes ntfy-approval setup and test.

License

MIT

README from the reviewed commit 95d3a4b; it updates when the author re-pins.

More by AhmetArif0

5 plugins by AhmetArif0 in the catalog.

Developer Mode

Explore built-in Hermes toolsets and actions.

HermesAgent

Developer?

Create a Hermes extension for Desktop or agent workflows.

Developer Section