Prerequisites. A VisIQ account (sign in) with a
harness key from Settings → Harness Keys, Python 3.10+ (CrewAI’s own
floor), and a model provider key for CrewAI (the sample calls a hosted model;
any provider works). Full setup and fixes: Before you start ·
Troubleshooting.
visiq.govern(). There
are no per-tool wrappers: every tool on every agent in the crew is governed,
including tools passed to a single Task(tools=[...]), tools you append to an
agent after calling govern(), and the delegation and memory tools CrewAI adds
at run time. You can also govern a single Agent, which covers that agent in
any crew and under agent.kickoff(). The
visiq wheel, compiled from the same
governance core as the TypeScript harness, makes every decision locally,
in-process against a cached rule bundle.
Install
Set environment variables
.env
The
visiq wheel reads its configuration from the process environment and
does not auto-load a project .env. Export the variables (or load them
yourself) before calling govern().
Govern your crew
govern() returns the same object, so it also works as an expression. It is
idempotent: governing a crew or agent twice installs governance once. To govern
one agent rather than a whole crew, pass the agent: govern(support, agent_id="support-bot").
Every tool call the model makes is decided before the tool runs. A deny
means your function is never called: the block message is returned as the tool’s
result, so the model reads why and the crew carries on instead of crashing. A
mask hands your function only the redacted arguments, nested ones included.
Tools named in retrieval_tools also have their result governed before it
reaches the model, with restricted documents dropped and sensitive fields
redacted. A result the retrieval facet cannot split into documents (a dict
envelope, a pydantic model) is withheld rather than passed through.
Both tool styles are governed: @tool functions and BaseTool subclasses. They
reach their code through different callables (a @tool tool’s run never goes
through _run), so VisIQ wraps the one each style actually executes, and a call is
decided exactly once whichever dispatch path CrewAI takes: native function calling
or the text (ReAct) loop.
CrewAI caches tool results and serves a repeated call from that cache without
running the tool. A cached answer would skip the policy decision and the audit
row, so caching is turned off for governed tools: every call is decided afresh.
An
async tool is decided in a worker thread, off your event loop, and then
awaited in your own task.Run this on AWS Bedrock
CrewAI reaches Bedrock through its ownLLM wrapper, which routes to LiteLLM’s
bedrock/ provider, so there is no adapter package and the govern() call is
unchanged:
llm to your agents. Note the bedrock/ prefix on the model id:
that prefix is what selects the provider. Credentials come from the standard AWS
chain (AWS_PROFILE, instance role, AWS_ACCESS_KEY_ID/AWS_SECRET_ACCESS_KEY).
Governance is untouched: the gate fires at the same point, the same rules match,
the same rows land in the audit trail. Verified end to end against real Bedrock
inference.
15 of 15 Bedrock scenario checks passed.
Deploying to Bedrock AgentCore Runtime needs nothing extra either: it hosts
your process, so install the visiq wheel in your image and set VISIQ_API_KEY
in the runtime environment. If instead you use a managed harness, AWS owns the
agent loop and this in-process governance does not apply; see
AWS Bedrock
for the two chokepoints that still work there.
What happens at runtime
New agents start in monitor mode (observe-only) until you flip them to enforce on the Control Agents → Agents page.- Decisions are local. The SDK fetches one cached rule bundle
(
GET /rules/bundle, ETag revalidation) and refreshes it in the background. Tool calls evaluate in-process; the only decision-path network call is waiting on a human approval. - Fail-open by default, loudly — strict deny is opt-in. Real policy outcomes
always enforce: an explicit rule deny, the operator kill-switch, and an
in-core mask/redact that cannot be applied (it downgrades to deny) all block.
A harness-internal failure does NOT block: if the backend is unreachable or
the governance core is unavailable, the harness proceeds UNGOVERNED with a
loud
[VisIQ] FAIL-OPEN (no-bundle)report on stderr, so a VisIQ outage never disrupts your agent (owner decision, 2026-07-15). SetVISIQ_FAIL_MODE=closedto block those harness-internal failures instead. - Deny blocks the call. The tool is never executed, and the model receives the block message as the tool result.
- Approvals pause the call. An
approval_requireddecision holds the tool while a human decides via Slack or Email (Microsoft Teams delivery is built server-side; its connector card is coming soon) — the SDK polls for up to 120 seconds (VISIQ_HITL_TIMEOUT_MS), then fails closed. - Mask proceeds, redacted. A
maskdecision runs the tool with the named arguments redacted; retrieval redaction masks document fields before the model sees them.
What
govern() does not cover. crew.kickoff_for_each(), crew.train() and
crew.test() run on copies of your agents: their existing tools stay governed, but a
tool CrewAI injects into a copy at run time is not, and the copies’ audit events are
delivered in batches or at exit rather than per run. The manager agent CrewAI creates
for Process.hierarchical is not governed (its delegation reaches your governed
agents, whose tools are). A BaseTool subclass that overrides run itself, rather
than _run, is not intercepted. A tool object shared between two separately governed
crews keeps the first crew’s governance. Calling a tool function directly, outside an
agent, is not an agent tool call. Need finer control than the whole crew? The
per-call Governor.gate_tool primitive is documented in the
Python SDK Reference.Verify it’s working
Run the crew once, then open the dashboard:- Control Agents → Agents — your agent appears automatically (monitor mode) with a live last-seen heartbeat.
- Control Agents → Runtime Enforcement — a decision row for every governed tool call, with the matched rule and outcome.
Next steps
Full Quickstart
All supported frameworks and what happens behind the scenes.
Python SDK Reference
The complete
Governor API — gate_tool, gate_documents, fail modes.