diff --git a/README.md b/README.md index e889f46..bbb3792 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,236 @@ -# IntentFrame × Hermes +# AI-Powered Security, Governance and Policy Enforcement for Hermes Agent +### The IntentFrame security plugin and safety gate for [Hermes Agent](https://github.com/NousResearch/hermes-agent) -**Structural security for [Hermes Agent](https://github.com/NousResearch/hermes-agent)** — validate tool calls before they touch your machine. +
-Hermes gives you a capable agent with terminal, files, and tools. IntentFrame adds the governance layer: every dangerous action crosses a policy boundary first. The model proposes; IntentFrame judges; only then does Hermes execute. +**Put an external validation checkpoint in front of the tools [Hermes Agent](https://github.com/NousResearch/hermes-agent) runs on your machine — terminal, code, file writes, cron — powered by [IntentFrame](https://github.com/intentframe/intentframe).** -[Install](#install) · [Run](#run-three-commands) · [Uninstall](#uninstall) · [CLI reference](docs/hermes-cli.md) · [Integration guide](docs/hermes-intentframe-integration-guide.md) · [IntentFrame core](https://github.com/intentframe/intentframe) +IntentFrame is a separate policy runtime, not part of the agent: it judges Hermes's risky actions from *outside* the agent, against rules you set, before they run. Hermes proposes; IntentFrame judges; a governed action runs only on **ALLOW**. (IntentFrame's integration layer is agent-agnostic — Hermes is the first integration.) + +[Install](#install-intentframe-into-hermes) · [See a BLOCK](#see-it-work) · [Choose what's governed](#control-which-hermes-tools-are-governed) · [Write policy](#modify-intentframe-policy) · [Docs](#status-and-resources) --- -## Who is this for? +## Get started with Hermes + +[Hermes Agent](https://github.com/NousResearch/hermes-agent) is Nous Research's self-improving agent — terminal, tools, memory, cron, and a chat dashboard. This IntentFrame plugin routes its tool calls through IntentFrame so each governed call is checked before it runs. + +**Governed out of the box:** `terminal` · `execute_code` · `write_file` · `patch` · `cronjob` +The tools that can actually touch your machine — all checked by default. Every other Hermes tool runs untouched. + +```text +You → Hermes proposes an action → IntentFrame checks your policy + ├─ ALLOW ✓ runs + └─ BLOCK ✗ logged, never runs +``` + +## Why IntentFrame on top of Hermes? + +Hermes already has command approval, allowlists, and container isolation — but those run *inside* the agent stack. A confused or hijacked model is asking the same process that's supposed to stop it. IntentFrame moves the decision out: + +| | Hermes alone | Hermes + IntentFrame | +|---|---|---| +| Where the rules live | Prompts, config, allowlists inside Hermes | Policy you write, **outside** the agent | +| Who validates risky tools | The Hermes runtime | IntentFrame, before the action runs | +| If the model is tricked or wrong | Same process that wanted to act | An external judge blocks it + leaves an audit trail | + +## What the Hermes integration installs + +Without forking Hermes or rewriting its tools, the integration installs: + +- A Hermes plugin that catches selected tool calls before Hermes runs them. +- A small adapter that translates Hermes actions into IntentFrame checks. +- An IntentFrame backend that decides **ALLOW** or **BLOCK**. +- CLI commands to install, start, stop, choose governed tools, and update policy. + +This integration ships governance for the following Hermes tools, all enabled by default: + +| Hermes tool | IntentFrame action | What it protects | +|-------------|-------------------|------------------| +| `terminal` | `RUN_COMMAND` | Shell commands before execution | +| `execute_code` | `RUN_COMMAND` | Generated code before execution | +| `write_file` | `WRITE_HOST_FILE` | Host file writes | +| `patch` | `WRITE_HOST_FILE` / `DELETE_HOST_FILE` | File edits and deletes | +| `cronjob` | `HERMES_CRONJOB` | Scheduled autonomous work | + +Ungoverned Hermes tools continue to work normally. -| If you are… | What this gives you | -|-------------|---------------------| -| Running Hermes on your own machine | Governed `terminal`, `write_file`, `patch`, and `cronjob` — with a required **reason** on each call | -| Shipping agents to users who need guardrails | Policy-driven ALLOW/BLOCK before side effects, not prompt-only hope | -| Evaluating IntentFrame with a real agent | Production-shaped plugin + adapter + CLI — not a toy wrapper | -| Contributing to the integration | Monorepo with plugin, adapter, backend bridge, and E2E tests | +## Install IntentFrame Into Hermes + +No git clone required: + +```bash +curl -fsSL https://github.com/intentframe/agent-integrations/raw/main/scripts/install-hermes-plugin.sh | bash +``` + +Then run Hermes with IntentFrame: + +```bash +export OPENAI_API_KEY=sk-... +intentframe-integrations up hermes +hermes dashboard +``` + +Open: + +```text +http://localhost:9119/chat +``` + +Ask Hermes to run a terminal command. If the tool is governed, IntentFrame validates it before Hermes executes it. + +--- + +## See It Work + +Example probes from the Docker gating session: + +| Prompt | Expected result | +|--------|-----------------| +| `sudo echo test` | **BLOCK**: privilege escalation | +| write a file under `/etc` | **BLOCK**: path outside policy | +| read `~/.hermes/.env` | **BLOCK**: credential access | +| list cron jobs | **ALLOW** or semantic review, depending on policy | + +Full captured session: [tests/docker/logs/2026-06-26-hermes-gating-session.md](tests/docker/logs/2026-06-26-hermes-gating-session.md) --- -## What you get +## Governed Tools vs Policy + +There are two separate controls: -When Hermes calls a **governed** tool, IntentFrame sits in the path: +| Control | What it means | Runtime file | +|---------|---------------|--------------| +| Governed tools | Which Hermes tools are routed through IntentFrame | `~/.intentframe/integrations/hermes/governance/tools.yaml` | +| Policy | Which routed actions are allowed or blocked | `~/.intentframe/integrations/hermes/policy.yaml` | -| Hermes tool | IntentFrame action | -|-------------|-------------------| -| `terminal` | `RUN_COMMAND` | -| `write_file`, `patch` | `WRITE_HOST_FILE` / `DELETE_HOST_FILE` | -| `cronjob` | `HERMES_CRONJOB` | +A tool must be **governed** for IntentFrame to see it. +A governed tool must then pass **policy** before it executes. + +--- +## Control Which Hermes Tools Are Governed + +List governed tools: + +```bash +intentframe-integrations governance list hermes ``` -You → hermes dashboard → LLM → intentframe-gate → adapter → IntentFrame policy → ALLOW → Hermes runs + +Enable governance for a tool: + +```bash +intentframe-integrations governance enable hermes terminal +``` + +Disable governance for a tool: + +```bash +intentframe-integrations governance disable hermes terminal ``` -Ungoverned Hermes tools work as usual. Toggle which tools are governed with the CLI — [docs/hermes-cli.md](docs/hermes-cli.md). +Restart the Hermes gateway and adapter after changing governed tools: + +```bash +intentframe-integrations stop +intentframe-integrations up hermes +``` --- -## Install +## Modify IntentFrame Policy + +Show the current Hermes policy: + +```bash +intentframe-integrations policy show hermes +``` + +Use your own policy file: + +```bash +intentframe-integrations policy set hermes /path/to/policy.yaml +``` + +Reload policy after editing: + +```bash +intentframe-integrations policy reload hermes +``` + +Reset to the bundled default: + +```bash +intentframe-integrations policy reset hermes +``` + +Policy changes apply immediately. You do not need to restart Hermes just to reload policy. + +--- + +## Basic Policy Example + +IntentFrame policy is deny-by-default: actions must appear under `allowed_actions`. + +```yaml +intentframe_schema_version: 1 +agent_id: hermes + +allowed_actions: + RUN_COMMAND: + safe: false + constraints: + blocked_patterns: + - sudo + - "rm -rf /" + deny_capabilities: + - "capability:data_read:credential_material" + - "capability:system_mutate:privilege_config" + + WRITE_HOST_FILE: + safe: false + constraints: + allowed_host_paths: + - "~/*" + + DELETE_HOST_FILE: + safe: false + constraints: + allowed_host_paths: + - "~/*" + + HERMES_CRONJOB: + safe: false + +intent_limits: + - limit_id: no-secret-exfil + domain: data_access + description: Block reading secrets or credential material + raw: Do not read credentials, tokens, cookies, secret files, or upload private data to untrusted destinations. + effect: block +``` + +Useful policy concepts: + +- `allowed_actions`: which IntentFrame actions can be considered at all. +- `safe: true`: action can pass through simpler checks. +- `safe: false`: action is consequential and should be reviewed more carefully. +- `constraints`: deterministic limits like allowed paths or blocked command patterns. +- `intent_limits`: plain-English rules the Guardian uses for semantic policy review. +- `domain_constraints`: structured rules for specific domains like deletion or spending. + +Full IntentFrame policy guide: +[docs/user_policy_yaml_guide.md](https://github.com/intentframe/intentframe/blob/main/docs/user_policy_yaml_guide.md) + +--- + +## Install Options No git clone. One script installs Hermes (if needed), the integration pack, and the `intentframe-gate` plugin: @@ -73,26 +266,6 @@ After headless install, set `OPENAI_API_KEY` (and run `hermes setup` if chat ret --- -## Run (three commands) - -```bash -export OPENAI_API_KEY=sk-... -intentframe-integrations up hermes -hermes dashboard -``` - -Open **http://localhost:9119/chat**. Ask Hermes to run a terminal command — IntentFrame gates it in the background. - -**Smoke-test gating:** - -```bash -tail -f ~/.intentframe/integrations/hermes/adapter.log -``` - -Try something policy should block (e.g. `sudo …`) and look for `BLOCK` in the log. - ---- - ## Uninstall ```bash @@ -135,34 +308,12 @@ Full tables (what is / is not removed): [docs/hermes-cli.md#uninstall](docs/herm --- -## What `up hermes` starts +## Status and Resources -| Component | Role | -|-----------|------| -| IntentFrame backend | Policy registry, bridge, executor | -| Hermes adapter | Maps tool args → IntentFrame `/validate` | -| Hermes gateway | Hermes tool runtime + `intentframe-gate` plugin | +**Current release:** [v0.2.0](https://github.com/intentframe/agent-integrations/releases/tag/v0.2.0) +**Integration maturity:** Hermes plugin + adapter + CLI; Docker E2E; known uninstall caveats on root/FHS — [limitations](docs/hermes-known-limitations.md). -`hermes dashboard` is the web UI — run it after `up hermes` (same or another terminal). - ---- - -## Docker smoke test - -Same install script, inside a container: - -```bash -export OPENAI_API_KEY=sk-... -docker compose -f tests/docker/docker-compose.test.yml up -``` - -→ **http://localhost:9119/chat** (default login `hermes` / `docker-test`). Details: [tests/docker/README.md](tests/docker/README.md). - -**Example session** (chat probes + full IntentFrame audit trail): [tests/docker/logs/2026-06-26-hermes-gating-session.md](tests/docker/logs/2026-06-26-hermes-gating-session.md) · [all session logs](tests/docker/logs/README.md). - ---- - -## Documentation +### Documentation | Doc | Audience | |-----|----------| @@ -190,6 +341,7 @@ uv sync --all-packages |------|---------| | `intentframe-integrations-cli/` | `intentframe-integrations` CLI | | `integrations/hermes/` | Plugin, adapter, governance templates | +| `integrations/_template/` | Scaffold for adding a new agent integration | | `if-integration-backend/` | IntentFrame runtime supervisor | | `if-integration-clients/` | Bridge clients (Python + TypeScript) | | `tests/hermes_gateway/` | Opt-in gateway E2E (isolated sandbox) | @@ -202,3 +354,5 @@ RUN_HERMES_GATEWAY_E2E=1 ./scripts/e2e.sh # optional, slow + networked ``` Package docs: `if-integration-backend/README.md`, `if-integration-clients/README.md`. + +