Install
openclaw skills install @mark-stadtmueller/sentinel-custom-provider-checkVerifies that Sentinel's PII/secret redaction guardrail survives routing through CUSTOM_PROVIDERS to a self-hosted OpenAI-compatible backend (vLLM, TGI, Ollama, or anything speaking /v1/chat/completions) — not just Sentinel's first-party Anthropic/OpenAI/Google routes. Starts the local Sentinel gate
openclaw skills install @mark-stadtmueller/sentinel-custom-provider-checkWhen the user wants to confirm Sentinel's redaction guardrail actually
reaches a self-hosted backend wired up via CUSTOM_PROVIDERS — not just
Sentinel's built-in provider integrations — guide them through the steps
below in order.
Do not verify this by pasting real PII into a chat with Claude and reading Claude's own reply. If that Claude session is itself routed through a Sentinel gateway (common in OpenClaw setups), its own gateway redacts inbound PII-shaped text on the way in — independent of whatever the custom backend actually did with it. That makes an unrelated pass-through look like a successful redaction test.
The only valid check is reading the raw JSON response the backend itself
produced, on a channel nothing else can re-redact. That's what
skill.py's _probe_backend() does: it calls the gateway's
OpenAI-compatible endpoint directly over HTTP and inspects the response body
for the literal {{REDACTED}} marker vs. the leaked probe values.
vllm-colab, Qwen/Qwen2.5-3B-Instruct).sentinel gateway start --help works before
starting this skill — don't assume Sentinel is already present.pip install -r requirements.txt
Create a .env file in the skill root:
CUSTOM_PROVIDER_BASE_URL=https://<your-tunnel-or-deployment>
CUSTOM_PROVIDER_NAME=vllm-colab
CUSTOM_PROVIDER_MODEL=Qwen/Qwen2.5-3B-Instruct
SENTINEL_GATEWAY_PORT=8100
TELEGRAM_BOT_TOKEN=<copy from your OpenClaw config — no separate bot needed>
TELEGRAM_CHAT_ID=<copy from your OpenClaw config — no separate bot needed>
Telegram delivery is optional — if left unset, the skill still runs and prints its result to stdout instead.
python -c "from skill import run; print(run())"
This will:
CUSTOM_PROVIDERS pointed at CUSTOM_PROVIDER_BASE_URL (reuses the
cached sentinel_id — this is not a fresh registration)./{provider}/v1/models until the gateway is reachable./{provider}/v1/chat/completions, asking the model to echo them back.{{REDACTED}} vs. the literal probe values.Register using the metadata in skill.py:
/sentinel_custom_checkCUSTOM_PROVIDER_* /
SENTINEL_GATEWAY_PORT vars above, plus OpenClaw's existing Telegram vars.{{REDACTED}} and neither the probe email
nor phone number appeared anywhere in the backend's own output. The
guardrail intercepted the PII before it reached the custom backend.{{REDACTED}}
marker appeared at all (check CUSTOM_PROVIDER_BASE_URL reachability and
that the gateway actually restarted with the new config — a stale
container from a previous run is the most common cause).This skill formalizes a manual test run on 2026-08-19 against a
Qwen2.5-3B-Instruct vLLM server on a Colab T4, chained through Cloudflare +
a local Sentinel gateway + ngrok. See
../vllm_sentinel_custom_provider.ipynb for the backend half (vLLM +
ngrok) and ../redaction_relay_flow.png / ../redaction-relay.png for a
diagram of the full chain. The original manual test confirmed the guardrail
held; this skill makes that check repeatable without re-deriving the
Cloudflare/Docker/ngrok wiring by hand each time.
sentinel gateway start always launches a container, so a bare
localhost process on the host is never what answers.CUSTOM_PROVIDER_BASE_URL unreachable from the gateway container: on
macOS Docker Desktop, a same-machine backend needs host.docker.internal,
not localhost, as the base URL./health check hangs: some OpenAI-compatible servers (vLLM
included) return HTTP 200 with an empty body on /health — this skill
doesn't call /health directly, but if you extend it to poll one, don't
call .json() on it.CUSTOM_PROVIDER_BASE_URL — this skill
always stops and restarts the container rather than assuming a running one
has current config; confirm your .env change was saved before the run.