Integration guide
Quick Start
By the end of this guide your agent will be registered with a verified identity and making real authorization calls — with a signed audit record produced for every decision.
Before you start
- An AGF account with an active plan — sign up on the pricing page
- A terminal with curl installed (no SDK needed to start)
- About 10 minutes
Three things to know before you code
Actions and scope are strings you define
There is no fixed list. Use any consistent format — resource:verb works well (file:write, payments.transfer, emails.send). The scope you set at registration is a hard ceiling: the agent can never be authorized for an action not in that list.
owner_id comes from your own system
It is any string that identifies who owns this agent — a user ID, an email address, a service account name. You are not creating a user in AGF; you are labelling who in your system is responsible for this agent.
New orgs get a default policy automatically
AGF provisions a default policy for every new org that allows any in-scope action when trust_score is 0.5 or above. You only need custom policies when you want finer control — time windows, amount caps, resource patterns. Contact us to configure those.
Get your API key and org ID
After signing up, AGF emails you an API key and an org ID. Export the API key — every curl command in this guide uses it automatically in the Authorization header. Keep your org ID handy; you will type it directly into the request body in steps 02 and 03.
export AGF_API_KEY="agf_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx" # replace with your real keyRegister your first agent
Before an agent can request authorization it needs an identity — called an Agent Passport. Call /v1/agents/register once per agent. AGF generates a DID (did:agf:agt_…) and returns it in the response. That DID is what you pass on every authorization call. Replace "user_alice" with any string that identifies the agent owner in your own system, and fill in your scope list with every action string this agent may ever attempt.
Note: DID stands for Decentralized Identifier. It is a globally unique string that AGF generates for the agent — you do not invent it. Think of it as the agent's permanent ID card.
Note: The scope list is a hard ceiling set at registration time. If the agent later calls /v1/authorize with an action not in this list it is denied immediately, before any policy is evaluated.
Note: Public key is optional at registration. If your agent will sign delegation tokens or participate in federated trust flows, paste its RSA or EC public key (PEM or JWK format) in the keypair_public field. AGF stores only the public key and uses it to verify signatures — never supply the private key. You can skip this field now and upload the key later via PUT /v1/agents/{agent_id}/key from the agent detail page.
curl -X POST https://api.agentgovernancefoundation.com/v1/agents/register \
-H "Authorization: Bearer $AGF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "report-writer-v1",
"owner_id": "user_alice",
"org_id": "org_acme",
"scope": ["file:read", "file:write"]
}'{
"agent_id": "did:agf:agt_01abc",
"passport_id": "pass_9hMn5sT",
"status": "active",
"trust_score": 1.0,
"created_at": "2026-06-23T10:00:00Z"
}Make your first authorization request
Every time your agent wants to perform an action, call /v1/authorize first and wait for the decision before proceeding. Pass the agent_id from step 02, the action string (it must exactly match one of the scope strings you registered), and the resource being targeted. The resource field is an identifier string you define — any URI that names the target. AGF does not connect to or validate it; it is stored in the audit record and matched by policy rules. Replace all placeholder values before running.
Note: The action value must exactly match one of the strings in the scope list from step 02. If the agent registered with scope ["file:read", "file:write"] and calls with action "file:delete", the decision is deny with reason scope_exceeded — no policy evaluation happens at all.
Note: The context object is optional. If you include it, AGF uses session_id and ip to improve trust scoring. You can omit the entire context field and the call will still work.
curl -X POST https://api.agentgovernancefoundation.com/v1/authorize \
-H "Authorization: Bearer $AGF_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "did:agf:agt_01abc",
"org_id": "org_acme",
"action": "file:write",
"resource": "s3://corp-data/reports/q2.csv",
"context": {
"session_id": "sess_xyz",
"ip": "10.0.1.5"
}
}'Read the decision and act on it
The response arrives in under 10 ms. Check the decision field: allow means proceed, deny means block. The trust_score (0.0–1.0) reflects how trusted this request chain is right now — a freshly registered agent starts at 1.0 and the score shifts as AGF observes behaviour over time. Every call produces an artifact_id: a permanent, signed record of this exact decision stored automatically for audit.
{
"decision": "allow",
"trust_score": 0.91,
"policy_ref": "pol_default",
"artifact_id": "art_7fKm3pQz",
"evaluated_at": "2026-06-23T10:04:33Z"
}// Always gate on the decision field — do not compare trust_score directly
if (response.decision === "allow") {
// proceed with the action
} else {
// block the action — see step 05 for how to handle deny
}Handle a denied decision
When decision is deny, the reason field tells you exactly why. Use it to decide whether to retry with narrower scope, escalate for human review, or abort the task. Log the artifact_id — it is the signed proof of the denial for your audit trail.
Note: policy_not_found means your org's default policy does not cover this action/resource combination. Do not retry — it will deny again until the policy is configured. Contact us and we will check your policy setup.
Note: trust_too_low means the trust_score dropped below the minimum your policy requires. This happens when the agent shows unusual behaviour — high request volume, unusual hours, or anomaly signals. The score recovers naturally with normal behaviour over time.
{
"decision": "deny",
"reason": "scope_exceeded",
"policy_ref": "pol_default",
"trust_score": 0.44,
"artifact_id": "art_8gLn4rRa"
}scope_exceeded — action not in the agent's registered scope
fix: add the action to scope when you call /v1/agents/register
trust_too_low — trust_score below your policy's minimum threshold
fix: no action needed — score recovers with normal behaviour
agent_suspended — this agent has been revoked
fix: contact AGF to reinstate the agent, or register a new agent
policy_not_found — no policy rule covers this action/resource combination
fix: contact AGF to configure the policy for your org
delegation_depth — delegation chain exceeds your org's maximum depth
fix: check your org settings or reduce chain depth
rate_limited — too many requests in a short window
fix: back off and retry — see Retry-After header in the 429 responseUse the Python SDK (optional)
The AGF Python SDK wraps the REST API so you can integrate authorization into any Python agent framework — LangChain, CrewAI, AutoGen, or plain Python — without hand-rolling HTTP calls. Install it from PyPI and pass your API key via the api_key constructor argument.
Note: authorize() never raises for deny or review decisions — it always returns an AuthResult object. Check result.allowed before proceeding. Use AGFDeniedError and AGFReviewRequiredError if you prefer exception-based control flow via the lower-level AGFClient.
Note: The SDK ships LangChain and CrewAI adapters. agf.langchain_tool() adds an authorization gate to your agent's tool list. AGFGuardedTool wraps individual tools so every call is policy-checked automatically.
pip install agf-sdk # core
pip install agf-sdk[langchain] # + LangChain adapter
pip install agf-sdk[crewai] # + CrewAI adapterimport os
from agf import AgentGovernance
agf = AgentGovernance(
api_key=os.environ["AGF_API_KEY"],
org_id="org_acme",
)
result = agf.authorize(
agent_id="did:agf:agt_01abc",
action="file:write",
resource="s3://corp-data/q2.csv",
)
if result.allowed:
# proceed with the action
pass
else:
raise PermissionError(f"Denied: {result.reason}")from agf import AgentGovernance
from langchain.agents import initialize_agent, AgentType
from langchain_openai import ChatOpenAI
agf = AgentGovernance(api_key=os.environ["AGF_API_KEY"], org_id="org_acme")
# agf_tool is a BaseTool the agent calls before sensitive operations
agf_tool = agf.langchain_tool(agent_id="did:agf:agt_01abc")
agent = initialize_agent(
tools=[agf_tool, *your_other_tools],
llm=ChatOpenAI(),
agent=AgentType.OPENAI_FUNCTIONS,
)from agf import AGFClient
from agf.langchain import AGFGuardedTool
from langchain_community.tools import ShellTool
client = AGFClient(api_key=os.environ["AGF_API_KEY"])
guarded_shell = AGFGuardedTool(
tool=ShellTool(),
client=client,
agent_id="did:agf:agt_01abc",
action_type="exec:shell",
resource="local-shell",
)
