- 01AutoGen's register_function pattern means every API call is a potential credential exposure — delegation tokens scope each call to exactly what it needs.
- 02authsec-autogen plugs into the standard AssistantAgent + UserProxyAgent pattern with no changes to the conversation topology.
- 03MOCK mode runs the full multi-agent conversation loop in CI with no AuthSec server and no secrets required.
AutoGen's multi-agent conversations are powerful — but every registered function your agents call is a potential credential leak. authsec-autogen replaces static API keys with short-lived, RS256-signed delegation tokens so your AssistantAgent never touches a raw credential.
The Problem
AutoGen's conversation loop is built around registered functions — the AssistantAgent proposes a call, the UserProxyAgent executes it. That execution step reaches out to real APIs, and in most codebases it does so with a static credential sitting in an environment variable.
Static API keys make the blast radius enormous:
- They don't expire on their own — a token in a log or a trace is a permanent credential
- They carry no identity — you can't tell which agent conversation used them or why
- They're scoped to everything the key allows, not just what the registered function needs
- Revoking them takes down every other agent or service sharing the same key
The Idea: Function-Native Delegation
AuthSec issues short-lived, RS256-signed JWTs scoped to specific permissions. Instead of storing a credential, your registered fetch_secure_data() function requests a delegation token at call time, uses it for that request, and lets it expire. The raw credential for the downstream API never touches your agent conversation at all.
AssistantAgent ──► propose fetch_secure_data()
│
▼
UserProxyAgent ──► execute fetch_secure_data()
│
▼
AuthSec /delegation-token endpoint
(verified by client ID)
│
▼
Short-lived RS256 JWT
(scoped, SPIFFE-identified, TTL ~30 min)
│
▼
Protected API ──► JSON response
│
▼
Result returned to conversationThe function is registered with autogen.register_function() so the agent can propose and the proxy can execute — but the credential exchange is entirely inside the SDK.
Install
pip install authsec-autogenWire Up the Agents
Set up an AssistantAgent and a UserProxyAgent, then register fetch_secure_data as an executable function:
import autogen
from authsec_helper import fetch_secure_data
config_list = [{"model": "gpt-4", "api_key": "YOUR_OPENAI_KEY"}]
assistant = autogen.AssistantAgent(
name="SecurityAssistant",
llm_config={"config_list": config_list},
system_message=(
"You are a security analyst. Use fetch_secure_data to retrieve "
"protected metrics and summarize what you find."
),
)
user_proxy = autogen.UserProxyAgent(
name="UserProxy",
human_input_mode="NEVER",
max_consecutive_auto_reply=5,
code_execution_config=False,
)
autogen.register_function(
fetch_secure_data,
caller=assistant,
executor=user_proxy,
name="fetch_secure_data",
description="Fetch data from a protected endpoint using AuthSec delegation tokens.",
)
user_proxy.initiate_chat(
assistant,
message="Fetch secure-vault/metrics with scope read:metrics and summarize the results.",
)That's the full integration. The AssistantAgent proposes the call; the UserProxyAgent executes it. The SDK handles the entire token exchange underneath.
What Happens Under the Hood
When UserProxyAgent executes fetch_secure_data(), the SDK runs a clean exchange:
1. AuthSecClient sends GET /authsec/uflow/sdk/delegation-token with the agent's client ID. 2. AuthSec verifies the identity and returns a signed JWT carrying the requested scope and a SPIFFE subject binding. 3. The SDK sends the downstream API request with Authorization: Bearer <token>. 4. The JSON response flows back into the conversation as the function result.
The token log in a live run:
[AuthSec SDK] [Mode] LIVE — using official authsec-langchain-sdk
|- Base URL : https://prod.api.authsec.ai
|- Client ID : fe6d5a81-58ac-4c4b-85fa-f84b6c9cb73d
[AuthSec SDK] [Delegation] Requesting delegation token via official SDK...
[AuthSec SDK] [Success] LIVE delegation token acquired via official SDK.
|- Token : eyJhbGciOiJSUzI1NiIsInR5...
|- Cache : SDK caches token internally (auto-refreshes on expiry).What You Get
Replacing static keys with delegation tokens through authsec-autogen gives you five properties that long-lived credentials simply cannot provide:
- Ephemeral credentials — a delegation token issued for one function call is expired before the next conversation turn starts. A token in a log is already dead.
- Least-privilege per call — read:metrics cannot read records. The scope travels with the token and is enforced at the API, not in the agent code.
- Full audit trail — every token request carries the agent's client ID. The AuthSec server knows which conversation fetched what, when, and under which scope — without extra instrumentation.
- No rotation burden — the client ID is long-lived; the tokens it generates are not. Revoke access through the AuthSec dashboard and the next function call gets a 401 — cleanly, immediately.
- Standard AutoGen compatibility — fetch_secure_data registers like any other function. It works with any AssistantAgent/UserProxyAgent pair, GroupChat, or custom agent topology.
Trying It Without a Full Setup
No AuthSec account needed. Omit the environment variables and the SDK falls back to MOCK mode automatically:
# No AUTHSEC_BASE_URL or AUTHSEC_AGENT_CLIENT_ID set
python main.pyYou get realistic mock vault records, a locally-generated JWT, and the complete agent conversation loop — AssistantAgent proposing, UserProxyAgent executing, result flowing back — enough to build and test your multi-agent logic before touching a real protected API.
Writing about identity, security, and developer tools at AuthSec.



