Skip to content
Install

Middleware lifecycle

See when plugin hooks run, what they receive, and how the chain stops.

Pentect plugins form an ordered middleware chain around the built-in protection engine. A hook returns normally to continue. It can replace its current payload, block the action, or—in the request hook—return a response without contacting the provider.

You do not call next() in the Rust SDK. Returning Ok(()) is the equivalent of continuing to the next plugin.

Text flow

text
input
  → prepare plugins
  → inspect plugins
  → built-in Pentect detection
  → merge findings and create handles
  → finalize plugins
  → protected text
HookUse it forCan replace?Can block?
prepareNormalize text before detectionYesYes
inspectAdd byte ranges and labelsNoYes
finalizeApply a final text policy after maskingYesYes

inspect findings join the same conflict-resolution process as built-in findings. Plugin order does not decide which overlapping label wins.

Provider flow

text
protected client request
  → request plugins
  → provider
  → response plugins
  → completed tool_call plugins
  → restore known handles locally
  → run tool
  → mask tool result
HookPayloadSpecial action
requestSupported provider request JSONrespond(...) can skip the provider
responseSupported non-stream or completed response JSONReplace or block
tool_callOne completed tool-call JSON objectReplace or block before local execution
fileFilename, media type, and sizeBlock before the normal file action

Streaming provider responses are reassembled only where a completed structure is needed. A plugin does not receive arbitrary transport bytes.

Continue, replace, block, and respond

SDK actionChain behavior
Return Ok(())Continue with the current payload
replace(value) then returnContinue with the replacement
block(message) then returnStop later plugins and the normal action
respond(value) in requestStop the chain and return that provider-shaped response
Return Err(...)Mark this plugin run as failed

Use block for an expected policy decision. Use Err for an internal failure such as invalid service output.

Required and optional plugins

required = true means the protected action must stop when the plugin cannot run. This fits company policy or a detector that must always be present.

With the default required = false, Pentect records partial plugin coverage. For a provider request, the normal unknown-format policy can still block partial coverage. Optional does not mean that Pentect silently claims the plugin ran.

Order and scope

Project plugins run in the order stored in .pentect/config.toml. A one-off plugin passed with --plugins is added for that command or client launch.

sh
pentect codex --plugins ./plugins/company-policy
echo 'sample' | pentect mask --plugins first,second

Use one plugin for one job. Small plugins are easier to approve, test, update, and remove than one plugin with unrelated access.

Sandbox boundary

Wasm plugins have no WASI. They cannot directly read files, environment variables, processes, or sockets. They receive only the hook payload and the specific settings they request.

An HTTP request is made by the Pentect host after it checks the approved origin, method, address, count, and size limits. Changing the manifest, binary, exported hooks, or approved access can require setup approval again.

Continue with Plugin recipes or the Rust SDK.

Pentect is open source.