Files
HiveGrid-Wireframes/hivegrid-cloud/docs/features/chatbot-v1.md
T

106 lines
5.1 KiB
Markdown

# Chatbot V1 — User Allow-List, 8 Capabilities, Audit Log
Built on top of the [MVP](./chatbot-mvp.md). V1 ships:
- 8 capabilities (MVP 3 + `data_read` + 4 high-risk).
- Per-user override via the new `TenantChatbotAccess` table.
- Audit-event-per-high-risk-call through `@toolctrl/db/audit-events.server`.
- Per-capability sliding-window rate-limits via `@toolctrl/shared-store`.
## Capability matrix
| Capability | Risk | Tool name | Notes |
| ------------------ | ------ | ---------------------- | ------------------------------------------------------------------ |
| `qa_help` | low | `search_help` | Bundled docs ranker. No DB. |
| `kb_search` | low | `search_knowledge_base`| Tenant-scoped KB. Wraps results in `---KB ARTICLE---` markers. |
| `account_info` | low | `get_account_info` | Whitelist projection. Never returns billing tokens / customer ids. |
| `data_read` | medium | `read_entities` | Strict entity enum, tenant-scoped read. |
| `data_write` | high | `write_entity` | Audit + rate-limit (30/min default). |
| `workflow_trigger` | high | `start_workflow` | Audit + rate-limit (10/min default). |
| `admin_actions` | high | `admin_action` | Audit + rate-limit (5/min) + OWNER/ADMIN role gate. |
| `external_tools` | high | `invoke_external_tool` | MCP-tool registry. Audit + rate-limit (60/min default). |
## Allow-list semantics
`TenantChatbotAccess` is a per-`(tenantId, userId)` override row.
1. Master-flag `chatbot` OFF → no capabilities.
2. Row exists with `enabled = false` → explicit deny (wins over any tenant default).
3. Row exists with `enabled = true` and non-empty `capabilityScopes` → those scopes.
4. Row exists with `enabled = true` and empty scopes → fall through to tenant default.
5. No row, `chatbotAccessMode = 'all_members'` → `Tenant.chatbotDefaultCapabilities`.
6. No row, `chatbotAccessMode = 'allow_list'` → no capabilities.
## Audit pipeline
`auditChatbotToolCall` writes through `createAuditEvent`. Action format:
`chatbot.tool_call.<capability>.<toolName>`. Payload uses an allow-list
projection (`ALLOWED_ARG_KEYS`); anything not on the list is dropped so
prompt-injection cannot exfiltrate secrets into the audit table.
Outcomes:
- `success` — inner tool ran cleanly.
- `failure` — inner tool threw (rethrown to the SDK).
- `blocked` — rate-limit denied or role-check returned `forbidden`.
## Rate-limit defaults (sliding window, 60 s)
| Capability | Max / window |
| ------------------ | ------------ |
| `qa_help` | 1000 |
| `kb_search` | 1000 |
| `account_info` | 1000 |
| `data_read` | 200 |
| `data_write` | 30 |
| `workflow_trigger` | 10 |
| `admin_actions` | 5 |
| `external_tools` | 60 |
Bucket key: `chatbot:<capability>:<tenantId>:<userId|anon>`. Backed by
the shared-store (Redis in prod, MemoryAdapter in tests).
## Operator commands
```sh
# Toggle the master flag
toolctrl chatbot enable | disable | status
# Grant / revoke per-user access
toolctrl chatbot grant --tenant acme --email alice@example.com --capabilities=qa_help,kb_search,data_read
toolctrl chatbot revoke --tenant acme --email bob@example.com # disables override
toolctrl chatbot revoke --tenant acme --email bob@example.com --hard # removes the row
# Update tenant default
toolctrl chatbot set-capabilities --tenant acme --mode allow_list \
--capabilities qa_help,kb_search,account_info
```
## Files
- `apps/web/app/modules/chatbot/lib/capabilities/{data-read,data-write,workflow-trigger,admin-actions,external-tools}.server.ts`
- `apps/web/app/modules/chatbot/lib/capabilities/{audit,rate-limit,high-risk-wrapper}.server.ts`
- `apps/web/app/modules/chatbot/lib/capabilities/resolver.server.ts` — V1 lookup matrix
- `apps/web/app/modules/chatbot/db/chatbot-access.db.server.ts`
- `apps/web/app/routes/app.$tenant/settings/chatbot.tsx` — V1 settings UI
- `packages/cli/src/commands/chatbot/access.ts`
- `prisma/schema/accounts.prisma` (`TenantChatbotAccess`, `Tenant.chatbotAccessMode`, `Tenant.chatbotDefaultCapabilities`)
## Troubleshooting
- **A user sees no chatbot tools even with override.** Check the master
flag (`toolctrl chatbot status`) and the row's `enabled` field.
- **`admin_action` returns `forbidden`.** Role gate. Only OWNER / ADMIN
may run admin actions even with the capability in scope.
- **`rate_limited` returned from a high-risk tool.** Inspect the
`chatbot:<capability>:<tenantId>:<userId>` bucket in Redis or wait the
60 s window.
## Known limitations
- No confirmation UI step yet — the wrapper is ready to return a
`{ ok: false, reason: 'awaiting_confirmation' }` shape but the chat
widget doesn't yet render it.
- `external_tools` provider is a stub. Phase 07 V2 will wire the MCP
client into it.