# Tool → policy pack mapping

The shell/API guardrail entrypoints invoke the guardrail with a **tool name** and **context JSON**. The guardrail maps the tool name to a **policy pack** in `external/aport-policies/` and evaluates the request against that policy and the passport.

This mapping is implemented in `bin/aport-guardrail-api.sh` and `bin/aport-guardrail-bash.sh`. The OpenClaw plugin has its own host-specific mapping in `extensions/openclaw-aport/tool-mapping.js`.

## Mapping table

| Tool name (pattern) | Policy pack ID | Policy location |
|---------------------|----------------|------------------|
| `git.create_pr`, `git.merge`, `git.push`, `git.*` | `code.repository.merge.v1` | `external/aport-policies/code.repository.merge.v1/` |
| `exec.run`, `exec.*`, `system.command.*`, `system.*` | `system.command.execute.v1` | `local-overrides` or API |
| `message.send`, `message.*`, `messaging.*` | `messaging.message.send.v1` | `external/aport-policies/messaging.message.send.v1/` |
| `read`, `file.read`, `data.file.read` | `data.file.read.v1` | API / evaluator |
| `write`, `file.write`, `data.file.write` | `data.file.write.v1` | API / evaluator |
| `mcp.tool.*`, `mcp.*` | `mcp.tool.execute.v1` | API / evaluator |
| `agent.session.*`, `session.create`, `session.*`, `cron`, `sessions_spawn`, `sessions_send`, `sessions_yield`, `subagents`, `session_status` | `agent.session.create.v1` | API / evaluator |
| `sessions_list`, `sessions_history`, `view` | `data.file.read.v1` | API / evaluator |
| `websearch`, `web_search`, `webfetch`, `web_fetch` | `web.fetch.v1` | API / evaluator |
| `browser`, `web.browser` | `web.browser.v1` | API / evaluator |
| `agent.tool.*`, `tool.register`, `tool.*` | `agent.tool.register.v1` | API / evaluator |
| `payment.refund`, `payment.*`, `finance.payment.refund` | `finance.payment.refund.v1` | `external/aport-policies/finance.payment.refund.v1/` |
| `payment.charge`, `finance.payment.charge` | `finance.payment.charge.v1` | `external/aport-policies/finance.payment.charge.v1/` |
| `database.write`, `database.*`, `data.export` | `data.export.create.v1` | `external/aport-policies/data.export.create.v1/` |

**Unknown tool:** In the **bash/API guardrail script**, an unknown tool name results in deny (exit 1). In the **OpenClaw plugin**, unmapped tools are **allowed** by default so custom skills and ClawHub tools work; set `allowUnmappedTools: false` in plugin config for strict (block unmapped).

## How OpenClaw uses it

1. OpenClaw (or your integration code) decides to run a tool, e.g. `system.command.execute` with `{"command":"npm install"}`.
2. Before executing, it calls the guardrail script with that tool name and context:
   ```bash
   ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"npm install"}'
   ```
3. The script maps `system.command.execute` → `system.command.execute.v1`, loads the passport and policy (or calls the API), and evaluates.
4. Exit 0 = allow, exit 1 = deny. Decision details are in `~/.openclaw/decision.json` (or your configured path).

## Adding or changing mappings

To add a new tool → policy mapping, edit the `case` block in:

- `bin/aport-guardrail-api.sh`
- `bin/aport-guardrail-bash.sh`

and add a new pattern and policy pack ID. The policy pack must exist under `external/aport-policies/<pack_id>/` (or in local-overrides / API).

Per-framework host tool names and hook behavior: [FRAMEWORK_TOOL_MAPPING_AUDIT.md](FRAMEWORK_TOOL_MAPPING_AUDIT.md).

## Reference

- OAP spec: `external/aport-spec/`
- Policy packs: `external/aport-policies/`
- AGENTS.md example: [AGENTS.md.example](AGENTS.md.example)
