YinShield Developer docs

Developer docs

Small surface area. Clear integration points.

YinShield ships as a Python package, a local HTTP bridge, and a thin OpenClaw plugin. This page covers the minimum you need to install it, call it, debug it, and publish the surrounding site.

This page is for implementation details. Product framing stays on the homepage.

Package

pip install yinshield

Bridge

yinshield serve --host 127.0.0.1 --port 27811

Plugin

@serein-213/openclaw-yinshield

Installer

python -m yinshield.install_openclaw

Install

Pick the smallest integration that solves the problem.

Python package

pip install yinshield

Run the local bridge

yinshield serve
yinshield serve --host 127.0.0.1 --port 27811
yinshield serve --mode alias --strategy strict --auth-token change-me

OpenClaw plugin

curl -fsSL https://yin-shield.site/setup-openclaw-yinshield.sh | bash

# manual fallback
python -m yinshield.install_openclaw
openclaw plugins install @serein-213/openclaw-yinshield
openclaw plugins enable openclaw-yinshield

Python wrapper

from yinshield import ShieldedOpenAI

client = ShieldedOpenAI(
  api_key="...",
  base_url="https://api.openai.com/v1"
)

HTTP API

Three endpoints are enough for the bridge.

POST /health

Command

curl -X POST http://127.0.0.1:27811/health \
  -H "Authorization: Bearer YOUR_TOKEN"

Response

{
  "ok": true,
  "service": "yinshield",
  "version": "0.0.1",
  "mode": "placeholder",
  "strategy": "balanced",
  "auth_enabled": true,
  "stateless_by_default": true
}

POST /mask

Request

{
  "text": "我叫张三,手机号13812345678",
  "mode": "placeholder",
  "strategy": "balanced",
  "session_id": "chat-1"
}

Response

{
  "text": "我叫<PERSON_1>,手机号<PHONE_1>",
  "mapping": {
    "<PERSON_1>": "张三",
    "<PHONE_1>": "13812345678"
  },
  "session_id": "chat-1"
}

POST /unmask

Request

{
  "text": "我叫<PERSON_1>,手机号<PHONE_1>",
  "mapping": {
    "<PERSON_1>": "张三",
    "<PHONE_1>": "13812345678"
  }
}

Response

{
  "text": "我叫张三,手机号13812345678"
}

POST /messages/mask

Request

{
  "messages": [
    { "role": "user", "content": "我叫张三,手机号13812345678" },
    { "role": "user", "content": [{ "type": "text", "text": "订单号20240324ABC123" }] }
  ],
  "mode": "placeholder",
  "session_id": "chat-1"
}

OpenClaw config

Keep the plugin thin and make the bridge explicit.

Recommended config

{
  "plugins": {
    "entries": {
      "openclaw-yinshield": {
        "enabled": true,
        "config": {
          "baseUrl": "http://127.0.0.1:27811",
          "mode": "placeholder",
          "authToken": "change-me",
          "timeoutMs": 10000
        }
      }
    }
  }
}

Recommended plugin behavior

- Register tools like yinshield_mask and yinshield_unmask
- Support yinshield_shield_messages for batch message masking
- Call local HTTP, do not reimplement masking logic
- Fail clearly if bridge is offline
- Suggest: yinshield serve --auth-token ...

Troubleshooting

The common failures should be obvious.

01

Bridge unreachable

Verify the local service is running on 127.0.0.1:27811. If not, start it with yinshield serve.

02

Wrong mode or strategy

If masking output looks too aggressive or too weak, compare loose, balanced, and strict before changing rules.

03

Plugin mismatch

Keep the npm plugin package and Python engine version notes aligned. The plugin should target the published bridge contract, not private internals.