Skip to main content
WatchlightWatchlight

Watchlight Developer Edition

Govern an AI agent in five minutes. One install, zero infrastructure, same API as production.

pip install watchlight        # Python 3.9+, prebuilt wheels
npm install @watchlight/sdk # Node 18+, the compiled engine comes with it

Watchlight puts a policy decision point in front of every action your agents take. It authorizes each tool call and records a value-free audit trail.

The Developer Edition runs the real authorization engine in-process — no server, no database, no signup. When it says Deny, it denies for the same reasons production does.

from watchlight import govern, Denied

# Permit ONLY "research". Fail-closed: everything else is denied.
govern.allow('permit(principal, action == Action::"research", resource);')

@govern.tool(intent="research")
def web_search(query: str) -> str:
return f"results for: {query}"

@govern.tool(intent="transfer") # governed, but no policy permits it
def transfer_funds(to: str, amount: int) -> str:
return f"sent ${amount} to {to}" # never runs — denied first

web_search("watchlight docs") # ALLOW → the body runs
transfer_funds("mallory", 1000) # DENY → raises Denied, before the body

That DENY is the product. The transfer_funds body never ran, and the decision is already on disk in .watchlight/audit.jsonl.

→ Quickstart — the full program, its output, and the live console.

What you can govern​

Python — pip install …Node — npm install …
A tool you wrotewatchlight → @govern.tool(intent=…)@watchlight/sdk → govern.tool(fn, { intent })
A framework agentwatchlight[langgraph] · [pydantic-ai] · [claude-agent] · [deepagents]governedHooks() for the Claude Agent SDK, governTool() for LangChain / LangGraph.js
An MCP serverwatchlight-mcp — a policy enforcement point in front of any MCP serverpoint any MCP client at that same PEP
Your own appgovern.authorize(…)await govern.authorize({…})

pip install "watchlight[all]" is one install for the whole Python lane, and every Python example in these docs runs after it. On the Node lane @watchlight/sdk is the only install you need — see TypeScript / Node.

Both lanes write .watchlight/audit.jsonl, and watchlight dev tails it:

watchlight dev            # → http://localhost:7000

Who is acting, and on whose behalf​

A governed call answers two separate questions, and that is what separates a policy from an if.

QuestionWhere it goes
On whose behalf does this run?principal — the subject, e.g. User::"db:4412"
Which runtime is acting?context.actor, set by the SDK from the agent name
Through whose delegation?context.actor_chain
Under what narrowed authority?govern.scope(tools=[...])

The SDK sets context.actor itself and refuses a caller-supplied value that disagrees, so a policy can trust it. → The identity model

A note on identity​

The Developer Edition authorizes the principal you assert — the agent you construct the governor with, or the Watchlight-Agent-Id on a governed MCP request. It does not cryptographically prove the caller. On your own machine, running both sides, that is the right trade.

Bind any non-loopback listener behind something that authenticates the caller — a reverse proxy doing mTLS or OIDC, or the Enterprise plane. Identity hardens as you grow without changing your policies.

The license​

Everything you write against is open and Apache-2.0: the govern decorator, scope attenuation, the CLI and watchlight dev, the framework plugins, every example.

The decision engine ships compiled (watchlight-engine, and the watchlight-mcp runtime) under the Developer Edition license — free, including in production and commercially. A commercial license is needed only to re-offer the engine itself as a hosted authorization service. To govern agents across a fleet from one control plane, talk to us about Enterprise.

Where to go next​