Agent Governance Foundation

AutoGen integration

Add policy enforcement to AutoGen agents by wrapping function tools with AGF authorization checks. No native adapter needed — the AGF Python SDK integrates at the function level.

Install

pip install agf-sdk

No extra extras needed — the core SDK works with plain Python.

Set your API key

export AGF_API_KEY=agfk_your_key_here

Authorization helper

AutoGen tools are plain Python functions registered in function_map. Wrap them with a policy check using AgentGovernance.authorize():

import os
from agf import AgentGovernance

agf = AgentGovernance(
    api_key=os.environ["AGF_API_KEY"],
    org_id="org_acme",
)

def guarded_tool(action: str, resource: str, fn, *args, **kwargs):
    result = agf.authorize(
        agent_id="did:agf:agt_01abc",
        action=action,
        resource=resource,
    )
    if not result.allowed:
        return f"Action blocked by policy: {result.reason}"
    return fn(*args, **kwargs)

Wrapping a tool

Register the guarded version in function_map. AutoGen calls the wrapper; the wrapper checks the PDP before calling the real function.

import autogen

def read_file(path: str) -> str:
    return open(path).read()

def guarded_read_file(path: str) -> str:
    return guarded_tool("read:file", path, read_file, path)

# Register guarded version as an AutoGen function tool
assistant = autogen.AssistantAgent(
    name="assistant",
    llm_config={
        "functions": [
            {
                "name": "read_file",
                "description": "Read a file from disk",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "path": {"type": "string", "description": "Absolute path to read"}
                    },
                    "required": ["path"],
                },
            }
        ],
        "config_list": autogen.config_list_from_json("OAI_CONFIG_LIST"),
    },
)

user_proxy = autogen.UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",
    function_map={"read_file": guarded_read_file},
)

Group chat with per-agent policies

Register each agent in AGF with a distinct agent_id. Each agent’s tools are guarded independently — different agents can have different policies for the same action.

import autogen

# Each agent uses a different agf agent_id for per-agent policy
def make_guarded_tool(agent_id: str, action: str, resource: str, fn):
    def wrapper(*args, **kwargs):
        result = agf.authorize(agent_id=agent_id, action=action, resource=resource)
        if not result.allowed:
            return f"Blocked: {result.reason}"
        return fn(*args, **kwargs)
    return wrapper

researcher = autogen.AssistantAgent(name="researcher", llm_config=llm_config)
writer     = autogen.AssistantAgent(name="writer",     llm_config=llm_config)
manager    = autogen.GroupChatManager(
    groupchat=autogen.GroupChat(agents=[researcher, writer], messages=[], max_round=10),
    llm_config=llm_config,
)

user_proxy = autogen.UserProxyAgent(
    name="user_proxy",
    human_input_mode="NEVER",
    function_map={
        "search_web":  make_guarded_tool("did:agf:agt_researcher", "read:web",  "internet",  search_web),
        "write_report": make_guarded_tool("did:agf:agt_writer",    "write:file", "reports/",  write_report),
    },
)

user_proxy.initiate_chat(manager, message="Research and write a report on Q1 churn.")

Async agents

For async AutoGen workflows, use AGFClient directly — it’s an async client built on httpx:

import asyncio
from agf import AGFClient

client = AGFClient(api_key=os.environ["AGF_API_KEY"])

async def guarded_tool_async(action: str, resource: str, fn, *args, **kwargs):
    response = await client.decide({
        "chain": ["did:agf:agt_01abc"],
        "action": {"type": action, "resource": resource},
        "audience": "internal",
    })
    if response["data"]["decision"] != "ALLOW":
        raise PermissionError(f"Denied: {response['data'].get('reasoning', '')}")
    return await fn(*args, **kwargs)

Notes

  • AutoGen’s tool system uses plain functions — there’s no BaseTool class to subclass. The function-wrapper pattern is idiomatic and works across all AutoGen versions.
  • Register every agent you deploy in AGF first (POST /v1/agents or via the dashboard). The agent_id must match a registered agent for the policy check to resolve.
  • Each authorization call produces a signed audit artifact. Export from the dashboard or GET /v1/audit.
  • For multi-agent AutoGen systems, pass the full delegation chain via AGFClient.decide() so the PDP can evaluate cross-agent authority.

Related