| 1 | diff --git a/README.md b/README.md |
| 2 | index e49fe7e..642d7fd 100644 |
| 3 | --- a/README.md |
| 4 | +++ b/README.md |
| 5 | @@ -52,6 +52,8 @@ See [Git collaboration](docs/git-collaboration.md) for issues, pull requests, co |
| 6 | |
| 7 | See [Installed app](docs/app.md) for installing the relay as an app, sharing files to it, opening Nostr links and device notifications. |
| 8 | |
| 9 | +See [Agent identities](docs/agents.md) for granting an assistant or bot its own scoped key, what the relay enforces and how to pause or revoke it. |
| 10 | + |
| 11 | **Manage > Health** shows the relay and script versions and whether the browser's WebMCP tools are registered. See [WebMCP tools](docs/webmcp.md) for browser-agent integration and authorization behavior. |
| 12 | |
| 13 | ## Deployment |
| 14 | diff --git a/docs/agents.md b/docs/agents.md |
| 15 | new file mode 100644 |
| 16 | index 0000000..9ad201e |
| 17 | --- /dev/null |
| 18 | +++ b/docs/agents.md |
| 19 | @@ -0,0 +1,86 @@ |
| 20 | +# Agent identities |
| 21 | + |
| 22 | +An agent is a member of your relay that acts under a grant you sign. It has its own key and stays the author of everything it publishes. The grant says which kinds, rooms and repositories the agent may write to and when the permission ends. The relay checks every event the agent sends against the grant, and you can pause or revoke the agent at any time. |
| 23 | + |
| 24 | +Agents suit assistants, bots and automations that should post as themselves rather than with your key. Because the agent signs its own events, nothing it publishes can be mistaken for something you wrote, and you can withdraw its access without changing your own keys. |
| 25 | + |
| 26 | +## Grant an agent |
| 27 | + |
| 28 | +The owner or a moderator grants an agent by publishing a kind 30392 event addressed to the agent's public key. Publishing the grant makes the agent a member with the role `agent`. Publishing a new grant for the same agent replaces the earlier one. |
| 29 | + |
| 30 | +| Tag | Required | Value | |
| 31 | +| --- | --- | --- | |
| 32 | +| `d` | Yes | The agent's public key, 64 lowercase hex characters. | |
| 33 | +| `p` | Yes | The agent's public key again, so clients can find grants by agent. | |
| 34 | +| `name` | No | A short label shown in the agent list. Up to 64 characters. | |
| 35 | +| `expiration` | Yes | Unix time when the grant ends. At most 365 days from now. | |
| 36 | +| `room` | No | A room the agent may post in. Repeat the tag for each room. | |
| 37 | +| `repo` | No | `<owner pubkey>:<identifier>:<read or maintain>`. Repeat for each repository. | |
| 38 | +| `k` | No | An event kind the agent may publish. Repeat for each kind. | |
| 39 | +| `wiki` | No | `propose` or `edit`. Recorded for wiki tooling. | |
| 40 | +| `rate` | No | Events per minute, 1 to 600. The default is 60. | |
| 41 | + |
| 42 | +The content may be empty or a JSON note for your own records. |
| 43 | + |
| 44 | +A grant with no `k` tags lets the agent publish only its profile (kind 0) and relay list (kind 10002). Add a `k` tag for each kind the agent needs. |
| 45 | + |
| 46 | +Example grant for an assistant that posts notes and comments in one room and files issues in one repository: |
| 47 | + |
| 48 | +```json |
| 49 | +{ |
| 50 | + "kind": 30392, |
| 51 | + "tags": [ |
| 52 | + ["d", "<agent pubkey>"], |
| 53 | + ["p", "<agent pubkey>"], |
| 54 | + ["name", "release-notes"], |
| 55 | + ["expiration", "1735689600"], |
| 56 | + ["room", "general"], |
| 57 | + ["repo", "<owner pubkey>:tinyrelay:read"], |
| 58 | + ["k", "1"], |
| 59 | + ["k", "1111"], |
| 60 | + ["k", "1621"], |
| 61 | + ["rate", "30"] |
| 62 | + ], |
| 63 | + "content": "" |
| 64 | +} |
| 65 | +``` |
| 66 | + |
| 67 | +A key that already has a human role keeps that role. A grant never lowers a member's, moderator's or owner's permissions; it only adds the `agent` role to keys that have no other standing on the relay. |
| 68 | + |
| 69 | +## What the relay enforces |
| 70 | + |
| 71 | +Every event from an agent key passes these checks before it is stored, whether it arrives from the agent directly or through synchronization with another relay: |
| 72 | + |
| 73 | +- The grant is not paused, not revoked and not expired. |
| 74 | +- The event kind appears in the grant's `k` tags. Profiles (kind 0) and relay lists (kind 10002) are always allowed. |
| 75 | +- If the event carries an `h` tag, the room appears in the grant's `room` tags. |
| 76 | +- Repository events name a repository the grant covers. Issues, patches, pull requests and comments need `read` or `maintain`. Status changes (kinds 1630 to 1633) need `maintain`. |
| 77 | +- The agent has not exceeded its per-minute rate. |
| 78 | + |
| 79 | +Rejected events return a `restricted: agent grant ...` reason to the client. The relay never edits or stamps an agent's events; it keeps them as signed or refuses them. |
| 80 | + |
| 81 | +The rest of the relay's policy still applies. An agent cannot publish a kind the relay blocks, and a banned key stays banned whether or not it holds a grant. |
| 82 | + |
| 83 | +## Pause and revoke |
| 84 | + |
| 85 | +Use the NIP-86 management methods to control agents. The owner and moderators may call each method. Every call is recorded in the audit log. |
| 86 | + |
| 87 | +| Method | Effect | |
| 88 | +| --- | --- | |
| 89 | +| `listagents` | Lists each agent with its name, public key, owner, expiration, paused and revoked state, scope and the time of its most recent event. | |
| 90 | +| `pauseagent <pubkey>` | Stops the agent until it is resumed. The grant stays in place. | |
| 91 | +| `resumeagent <pubkey>` | Lets a paused agent publish again. | |
| 92 | +| `revokeagent <pubkey>` | Ends the grant and removes the `agent` role. The grant event stays stored for audit. | |
| 93 | +| `pauseallagents` | Pauses every active agent at once. | |
| 94 | +| `resumeallagents` | Resumes every paused agent. | |
| 95 | + |
| 96 | +You can also revoke a grant with your signer: |
| 97 | + |
| 98 | +- Publish a kind 5 deletion that names the grant by its event id or by its address `30392:<your pubkey>:<agent pubkey>`. |
| 99 | +- Publish a new grant for the agent with an `expiration` in the past. |
| 100 | + |
| 101 | +Either way the agent loses its role at once. A fresh grant restores access. |
| 102 | + |
| 103 | +## Discovery |
| 104 | + |
| 105 | +While at least one agent is active, the relay's information document includes an `agents` capability entry, so clients and other agents can tell that this relay accepts granted agents. The entry carries no agent details. |