Skip to content

GraySwanAI/Openclaw-Cygnal-Plugin

Repository files navigation

Gray Swan Cygnal Guardrail

Standalone native OpenClaw plugin that evaluates OpenClaw tool calls and final run transcripts against Gray Swan Cygnal /cygnal/monitor.

Why this plugin exists

This plugin is scoped narrowly on purpose:

  • it hooks before_tool_call for enforcement and agent_end for final audit
  • it captures the latest model-facing conversation with llm_input
  • it correlates each before_tool_call decision with that conversation by runId
  • it tracks same-run tool calls and tool results observed through before_tool_call and after_tool_call so later tool checks in the same run see earlier tool activity before OpenClaw's next conversation snapshot catches up
  • it sends agent_end audits from OpenClaw's final message snapshot plus the cached same-run system prompt when available
  • its before_tool_call stage can run in either block or monitor mode

That makes it suitable for external guardrail / monitoring deployments without adding any bundled-core plugin code.

What Cygnal receives

On each before_tool_call, the plugin sends Cygnal:

  • the latest system prompt captured from llm_input
  • the latest conversation history captured from llm_input
  • the current user prompt captured from llm_input
  • earlier tool calls and tool results observed in the same run, de-duplicated against the latest OpenClaw conversation snapshot
  • the pending tool call that is about to execute
  • metadata about the hook, current tool call, model provider, and OpenClaw agent/session identifiers

On each agent_end, the plugin sends Cygnal:

  • the latest system prompt captured from same-run llm_input, when available
  • the final OpenClaw message snapshot for the run
  • metadata marking the request as monitor / audit-only by setting metadata.cygnal_bypass=true, regardless of the global cygnalBypass setting
  • the latest model provider metadata captured from same-run llm_input, when available
  • OpenClaw agent/session identifiers captured from hook context, when available

The agent_end path never blocks or changes OpenClaw behavior. It ignores Cygnal's decision fields and logs request failures only.

The after_tool_call hook is used only to update the same-run local transcript used by later before_tool_call checks. The plugin does not send a Cygnal request from after_tool_call.

Model metadata is sent as metadata.openclaw_model_provider, metadata.openclaw_model, and metadata.openclaw_model_ref when OpenClaw exposes those values through the llm_input hook.

OpenClaw identity metadata is sent as metadata.openclaw_agent_id, metadata.openclaw_session_id, and metadata.openclaw_session_key when hook context exposes those values.

Config

{
  plugins: {
    allow: ["grayswan-cygnal-guardrail"],
    entries: {
      "grayswan-cygnal-guardrail": {
        enabled: true,
        hooks: {
          allowConversationAccess: true,
        },
        config: {
          apiKey: "cygnal_api_key_here",
          apiBase: "https://api.grayswan.ai",
          policyId: "optional_policy_id",
          reasoningMode: "hybrid",
          violationThreshold: 0.5,
          timeoutMs: 30000,
          failOpen: true,
          cygnalBypass: false,
          debug: false,
          beforeToolCall: {
            enabled: true,
            mode: "block",
            violationThreshold: 0.5,
            blockOnMutation: false,
            blockOnIpi: false,
          },
          agentEnd: {
            enabled: true,
          },
        },
      },
    },
  },
}

Notes

  • apiKey is required in plugin config. Do not commit real keys; inject the value through your local deployment/configuration process.
  • apiBase defaults to https://api.grayswan.ai; the plugin sends requests to ${apiBase}/cygnal/monitor.
  • monitorUrl is optional and overrides apiBase when you need to target a custom full /cygnal/monitor endpoint.
  • policyId is optional and must be provided in plugin config when your Cygnal policy requires it.
  • plugins.allow should include grayswan-cygnal-guardrail in production so OpenClaw only autoloads trusted external plugin ids.
  • hooks.allowConversationAccess=true is required so the plugin can receive llm_input snapshots and agent_end.messages.
  • cygnalBypass: true sets metadata.cygnal_bypass=true.
  • agentEnd.enabled defaults to true. The request is always monitor-only and always sets metadata.cygnal_bypass=true. It also sets metadata.openclaw_system_prompt_included so audits can tell whether the cached system prompt was included.
  • debug: true emits request lifecycle logs with logger.error(...).

Local development install

This package is intentionally outside bundled extensions/ so it behaves like a third-party plugin.

npm install
npm run build
openclaw plugins install --link .

After linking, configure plugins.entries.grayswan-cygnal-guardrail with hooks.allowConversationAccess=true and restart the gateway.

Private distribution

Use exact, immutable versions for private users. Do not share config files or credentials with the package; each install should provide the Cygnal API key through local plugin config.

Packaged installs must include the built runtime at dist/index.js. Run npm run build before creating tags or tarballs, and commit the generated dist/index.js with the release tag.

Recommended options:

  • Private git repo with signed/reviewed release tags. Git installs require OpenClaw 2026.5.2 or newer. For private GitHub repos, prefer SSH so the user's normal SSH key authorizes the clone:
    openclaw plugins install git:git@github.com:GraySwanAI/Openclaw-Cygnal-Plugin.git@v0.1.3
    The shorthand git:github.com/owner/repo@tag uses HTTPS and is best for public repos or environments with GitHub HTTPS credentials already configured.
  • Private npm registry package:
    openclaw plugins install npm:@grayswansecurity/openclaw-grayswan-cygnal-guardrail@0.1.3 --pin
  • Direct tarball for a small trusted group or OpenClaw releases before 2026.5.2:
    npm run build
    npm pack
    shasum -a 256 grayswansecurity-openclaw-grayswan-cygnal-guardrail-0.1.3.tgz
    openclaw plugins install ./grayswansecurity-openclaw-grayswan-cygnal-guardrail-0.1.3.tgz

After install, enable plugins.entries.grayswan-cygnal-guardrail, set hooks.allowConversationAccess=true, configure the plugin, and restart the Gateway:

{
  plugins: {
    allow: ["grayswan-cygnal-guardrail"],
    entries: {
      "grayswan-cygnal-guardrail": {
        enabled: true,
        hooks: {
          allowConversationAccess: true,
        },
        config: {
          apiKey: "cygnal_api_key_here",
          apiBase: "https://api.grayswan.ai",
          failOpen: true,
          beforeToolCall: {
            enabled: true,
            mode: "block",
          },
          agentEnd: {
            enabled: true,
          },
        },
      },
    },
  },
}

ClawHub publish

clawhub package publish . --dry-run
clawhub package publish .

This plugin relies on the existing llm_input, before_tool_call, after_tool_call, and agent_end hooks, not on unreleased before_tool_call context fields.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors