@context-security/openclaw-email-guard-plugin
v0.1.8
Published
OpenClaw plugin that routes email composition and sending through Context Security Email Guard.
Readme
Context Security Email Guard OpenClaw Plugin
This package installs into a customer OpenClaw Gateway and makes email composition pass through the Context Security Email Guard service.
This repository/package is intentionally limited to the lightweight OpenClaw plugin. The central guard service, backend policy engine, trust graph, tenant data, and deployment secrets remain private.
What It Registers
This follows the OpenClaw plugin model: tools are registered with
api.registerTool(...) and the same names are declared under contracts.tools
in openclaw.plugin.json so the gateway can discover the owning plugin without
loading every runtime (Tools and plugins,
Building plugins). Optional
tools use { optional: true } and still appear in contracts.tools; operators
add them to tools.allow when they want them enabled.
Hooks:
before_prompt_build: injects mandatory email-guard instructions for email-related turns.before_tool_call: blocks direct email send tools such asgmail_send,outlook_send,smtp_send, andsend_email.before_agent_finalize: asks the agent to revise when it tries to output an email draft directly instead of storing/evaluating it first.
For non-bundled plugins, OpenClaw requires conversation hook access when a
plugin uses before_agent_finalize (among other hooks). Enable it under the
plugin entry as shown in Configure (hooks.allowConversationAccess).
Tools:
email_guard_prepare_contextemail_draft_storeemail_guard_evaluateguarded_email_sendemail_guard_feedback
Tenant ID
tenantId identifies the Context Security customer in the guard backend. It is
optional in configSchema so you can install the plugin first and set
plugins.entries.context-security-email-guard.config.tenantId when you onboard the
customer. Until tenantId is set, guard tools return a tenant_not_configured
error; hooks (e.g. blocking raw send tools) still run. After you set tenantId,
restart the gateway. At runtime the plugin injects that value into Trust
Accuracy Signals and feedback; the model cannot choose another tenant.
What tenantId is not: It is not a unique ID generated per Raspberry Pi or per plugin install. It identifies the Context Security tenant (customer org) in the guard backend. Use one tenant id per customer account; multiple gateways or installs for the same customer normally reuse the same tenantId.
Conversation Classifier
Trust Accuracy Signals include a required structured field:
| Field | Role |
| ----- | ---- |
| signals.conversationClassifier | One enum value (validated by the plugin tool schema). Use customer_support for ticket status replies, sales_conversation for sales mail, etc. |
| signals.businessPurpose | Free text: concrete nuance (ticket id, stakeholder, why this mail exists). Same classifier can cover many purposes—keep narrative here. |
Exported constants for backend parity tests or docs:
- TypeScript:
CONVERSATION_CLASSIFIER_VALUESand typeConversationClassifierfrom./dist/schemas.js(seesrc/schemas.ts).
Allowed conversationClassifier values (stable snake_case strings):
customer_support, sales_conversation, legal_matter, finance_payment, hr_recruiting, vendor_procurement, engineering_ip, executive_communication, incident_response, healthcare_pii, generic_internal_update.
Do not stuff the taxonomy into businessPurpose alone—the gateway validates conversationClassifier; duplicates there risk ambiguity.
Install From ClawHub
After publishing this package to ClawHub:
openclaw plugins install clawhub:@context-security/openclaw-email-guard-plugin
openclaw gateway restartYou may install with empty plugin config ({}). Add tenantId when the
customer is known; guardServiceUrl defaults to https://bently-nonenervating-vada.ngrok-free.dev/
or set it explicitly if your guard runs elsewhere.
Install From A GitHub Checkout
If this public plugin package is hosted in a GitHub repository before ClawHub publication:
openclaw plugins install --marketplace https://github.com/<owner>/<repo> @context-security/openclaw-email-guard-plugin
openclaw gateway restartIf your OpenClaw version does not support marketplace installs for the repository shape, publish to ClawHub or install from a local archive created by:
npm pack
openclaw plugins install ./context-security-openclaw-email-guard-plugin-0.1.0.tgz
openclaw gateway restartConfigure
{
plugins: {
entries: {
"context-security-email-guard": {
enabled: true,
hooks: {
allowConversationAccess: true,
},
config: {
guardServiceUrl: "https://bently-nonenervating-vada.ngrok-free.dev/",
tenantId: "customer-tenant-id",
blockedToolNames: ["gmail_send", "outlook_send", "send_email"]
}
}
}
},
tools: {
// Alternatively: allow: ["context-security-email-guard"] to grant every tool this plugin owns.
allow: [
"email_guard_prepare_context",
"email_draft_store",
"email_guard_evaluate",
"guarded_email_send",
"email_guard_feedback"
]
}
}Omit tenantId (and other keys) under config until the customer is onboarded; add tenantId and restart the gateway when ready.
hooks.allowConversationAccess is required so before_agent_finalize can run
for this external plugin (Plugin hooks).
Deny wins over allow globally; optional tools still need an explicit allow
grant when you want them callable (Tool configuration).
guarded_email_send and email_guard_feedback are optional tools. Enable them
explicitly when the customer agent should send through the guard or submit
feedback for adaptation.
Troubleshooting
ClawHub: “archive integrity mismatch” — ClawHub can verify source-linked packages against GitHub. This repo tracks dist/ so the tree matches what npm pack publishes. If you still see a mismatch, install from npm (same version) or use a local .tgz from npm pack:
openclaw plugins install @context-security/openclaw-email-guard-pluginClawHub 429 (rate limit) — Wait and retry, or use npm / a copied tarball as above.
tenant_not_configured from guard tools — Set tenantId under plugins.entries.context-security-email-guard.config, save openclaw.json, then openclaw gateway restart.
Cannot find module '@sinclair/typebox' — Use plugin 0.1.8+ (declares TypeBox as a dependency and bundles it in the .tgz so OpenClaw’s extension install does not need a separate npm install for that package). Rebuild with npm pack, copy the new tarball to the gateway, remove ~/.openclaw/extensions/context-security-email-guard, then openclaw plugins install ./context-security-openclaw-email-guard-plugin-0.1.8.tgz and restart.
CLI fails before install: must have required property 'guardServiceUrl' | 'tenantId' — OpenClaw validates openclaw.json against whatever plugin manifest is already on disk under ~/.openclaw/extensions/context-security-email-guard/ (an older install may still require those keys). Upgrade path: (1) Stop gateway if running. (2) Remove the old extension: rm -rf ~/.openclaw/extensions/context-security-email-guard. (3) Edit ~/.openclaw/openclaw.json and delete the whole "context-security-email-guard" entry under plugins.entries (or set "config": {} once you are on 0.1.8+ only). (4) Run openclaw plugins install …tgz again, then add optional tenantId / URL later and restart.
ClawHub: “archive contents do not match files[] metadata … missing package.json” — The published tarball must include root package/package.json (normal npm pack layout). This package uses .npmignore (not a narrow files list) so the packed tree matches what npm and ClawHub expect. Republish the latest version to ClawHub and npm after pulling this change, then ensure GitHub’s default branch has package.json at the repository root (same path ClawHub’s source link uses).
