Skip to main content

Google ADK

Vectimus governs tool calls in Google Agent Development Kit agents. The same Cedar policies apply whether your agent runs on Gemini, GPT-4o or Claude via LiteLLM.

Installation

pip install vectimus[adk]

Or with uv:

uv add vectimus[adk]

Use VectimusADKPlugin with Runner(plugins=[...]) to apply governance globally across all agents managed by that runner:

from google.adk.agents import Agent
from google.adk.runners import InMemoryRunner
from google.adk.sessions import InMemorySessionService
from vectimus.integrations.adk import VectimusADKPlugin

# 1. Create the Vectimus plugin
plugin = VectimusADKPlugin(
    observe_mode=False,        # set True to log without blocking
    principal="my-adk-agent",  # identity for the audit trail
)

# 2. Define tools
def bash(command: str) -> str:
    """Run a shell command and return its output."""
    import subprocess
    return subprocess.check_output(command, shell=True, text=True)

def file_read(file_path: str) -> str:
    """Read a file and return its contents."""
    return open(file_path).read()

# 3. Create the agent
agent = Agent(
    name="governed-agent",
    model="gemini-2.0-flash",
    instruction="You are a helpful assistant.",
    tools=[bash, file_read],
)

# 4. Wire the plugin into the Runner
session_service = InMemorySessionService()
runner = InMemoryRunner(
    agent=agent,
    app_name="my-app",
    session_service=session_service,
    plugins=[plugin],          # <-- governance applied here
)

When a tool call is denied, the agent receives a dict like {"error": "Blocked by Vectimus policy vectimus-supchain-001: npm publish is not permitted."} and can try a different approach.

Per-agent callback

For governing a single agent without a plugin, use create_before_tool_callback:

from google.adk.agents import LlmAgent
from vectimus.integrations.adk import create_before_tool_callback

callback = create_before_tool_callback(
    observe_mode=False,
)

agent = LlmAgent(
    name="MyAgent",
    model="gemini-2.0-flash",
    before_tool_callback=callback,
)

The plugin approach is recommended over callbacks for consistent governance across all agents in a runner.

How it works

Vectimus maps ADK tool calls to the same canonical action types used by the CLI integrations:

ADK tool nameVectimus action type
bash, shell, terminalshell_command
file_writefile_write
file_readfile_read
google_search, web_searchweb_request
server__tool (MCP pattern)mcp_tool

Shell commands are further classified into git_operation, infrastructure and package_operation based on the command content. Shell commands that perform file I/O (redirects, tee, inline scripts like python3 -c "open('f','w').write('x')") are reclassified to file_read or file_write with the file path extracted for Cedar policy matching.

Plugin options

ParameterDefaultDescription
policy_dirBuilt-in policiesPath to a directory of Cedar policy files
observe_modeFalseLog decisions but never block (trial mode)
principal"adk-agent"Identity string for the audit trail
cwdNoneWorking directory context for policy evaluation
log_dir~/.vectimus/logsDirectory for audit log JSONL files

Observe mode

Both the plugin and callback support observe mode for trialling without enforcement:

plugin = VectimusADKPlugin(observe_mode=True)

Or via environment variable:

export VECTIMUS_OBSERVE=true

Review the audit log at ~/.vectimus/logs/ to understand which actions your policies would block. When you’re satisfied, set observe_mode=False or unset the environment variable.

Custom policies

Load custom Cedar policies from a directory:

plugin = VectimusADKPlugin(
    policy_dir="./my-policies",
)

See Writing policies for the full guide on creating custom Cedar rules.

Audit trail

Every tool call is logged to the audit trail regardless of the decision. The plugin logs both pre-action evaluations (before tool execution) and post-action results (after tool execution) so you have a complete picture of what your agents did and what was blocked.

Audit logs are JSONL files at ~/.vectimus/logs/audit-YYYY-MM-DD.jsonl.

Every evaluation also produces an Ed25519-signed governance receipt stored in .vectimus/receipts/. Receipts provide tamper-evident proof of each decision for audit compliance. The daemon cleans up receipts older than 7 days by default (configurable via [receipts] retention_days in config). Use vectimus verify to validate receipts and vectimus receipts prune for manual cleanup.