Documentation
AgentKey is an authorization and evidence layer for AI agents. It lets you control what your agents are allowed to do, record what they actually did, and prove the record is intact.
What is AgentKey
Every team shipping an AI agent eventually hits the same problem: the agent can call tools, send emails, move money, and modify data, but you cannot see what it did, you cannot stop it when it goes off script, and you cannot prove to an auditor or a customer what happened.
AgentKey sits between your agent and its tools. Every tool call passes through a single authorization check, gets recorded to an append-only evidence chain, and can be verified later without trusting AgentKey itself. You write policies in plain JSON. The agent keeps working the way it always did. The difference is that now you have control and proof.
It is not a framework, not an agent runtime, and not a model. It is a thin control plane you add to any existing agent in one line of code.
What it does
AgentKey gives you four things, working together:
- 01Control. Decide which actions each agent is allowed to take, down to the parameter. Block a charge over $100. Allow refunds only under $500 with a human approval. Restrict email sends to your own domain.
- 02Observe. Every decision and every execution is written to a hash-chained evidence ledger. You get a full session timeline you can replay, export, and audit.
- 03Prove. The evidence chain is tamper-evident by construction. Anyone with the session token can recompute the hashes from the raw events and confirm the record has not been altered, without trusting AgentKey.
- 04Trust the supply chain. A tool trust registry scores and flags every MCP server, API, and plugin your agent connects to, so an unregistered or revoked tool can be blocked before it runs.
Core concepts
A few terms you will see throughout the docs:
- Agent - a registered workload (a bot, a workflow, a model pipeline) that holds one or more API keys.
- Permission - a rule for one
resource+actionpair with a decision:allow,ask, ordeny. - Condition - a parameter check attached to a permission, for example
amount lte 100. - Session - the evidence chain for one run of an agent. Every authorization and execution event lands here in order.
- EvidenceEvent - one record on the chain. Each event carries a hash of the event before it, so the chain is verifiable.
- Tool trust entry - a record of a tool your agent connects to, with a risk score and a status (approved, flagged, revoked).
Quickstart
From zero to a protected agent in four steps.
- Create an agent in the dashboard, or via the
create_agentfunction. You get anagent_id. - Create an API key for that agent. You receive the plaintext key exactly once. Store it as an environment variable on the agent host.
- Configure permissions for the resources and actions the agent should be allowed to touch. Add conditions for parameter limits.
- Install the SDK and call
wrap()on your tool list. The agent is now instrumented.
Everything from here is optional: tool trust scoring, input scanning, human approvals, and evidence export.
Install the SDK
npm install agentkey-aipip install -U agentkeyTwo zero-dependency clients, JavaScript and Python, installable from the public registries.
JavaScript / TypeScript (Node 18+)
npm install agentkey-aiimport { AgentKeyClient } from "agentkey-ai";
const ak = new AgentKeyClient({
apiKey: process.env.AGENTKEY_API_KEY,
// baseUrl defaults to the production API; set it only if you self-host
});Python (3.8+)
pip install agentkeyimport os
from agentkey import AgentKeyClient
ak = AgentKeyClient(
api_key=os.environ["AGENTKEY_API_KEY"],
# base_url defaults to the production API; set it only if you self-host
)Both clients fail closed: if the API cannot return a valid decision within 5 seconds, checks return allowed: false with fail_closed: true - an agent never proceeds on a missing or ambiguous decision.
Wrap your tools
wrap() is the one-line integration. Pass it your tool list (or an MCP client, a LangChain agent, a plain function map) and every call is intercepted. Two modes:
"observe"- record and surface what the agent does, but never block. Safe to enable in production immediately."enforce"- block any call the policy denies, and escalateaskdecisions to a human approval.
// enforce mode: denials raise AgentKeyDenied, ask calls pause for approval
const tools = ak.wrap(
[chargeCard, sendEmail, pushToRepo],
{ mode: "enforce" }
);
// pass the wrapped tools to your agent framework as usualThe wrapped tools have the same signature as the originals. Your agent code does not change. The session starts automatically on the first call and closes when the process exits.
For finer control, use guard() on a single function:
const out = await ak.guard(
{ resource: "stripe.charge", action: "invoke", arguments: { amount: 150 } },
async () => chargeCard({ amount: 150, currency: "usd" })
);
// out.allowed === false → the policy denied it and the function did not runPermissions and conditions
A permission matches a resource + action pair and carries a decision. Conditions are parameter checks evaluated at request time. The request body is the arguments object.
{
"resource": "stripe.charge",
"action": "invoke",
"decision": "allow",
"conditions": [
{ "field": "amount", "operator": "lte", "value": "100", "on_fail": "deny" }
]
}Supported operators:
lteless than or equalltless thangtegreater than or equalgtgreater thaneqequalsneqnot equalsinvalue is in a listnot_invalue not in a listmatches_domaindomain match for emails and URLsstarts_withstring prefixnot_containssubstring absentWhen a condition fails, on_fail decides the outcome: deny blocks the call, ask creates an approval request that a human resolves in the dashboard. Multiple conditions all must pass.
The three decisions are: allow (permit, subject to conditions), ask (always require human approval), and deny (always block). No permission configured means the default is deny.
Evidence and sessions
Every authorization and execution is written as an EvidenceEvent on a per-session hash chain. Events carry a sequence number, a hash of the previous event, and a leaf hash. Sessions can use a linear chain or a Merkle root.
You do not call the evidence API directly. The SDK and the authorize function write to it for you. What you do with it:
- Open the Sessions page in the dashboard to see a timeline of any run.
- Open the Evidence page to filter and inspect individual events.
- Call
verify_sessionto recompute the chain from raw events and confirm integrity. - Export a session as a compliance bundle with
export_compliance.
Evidence is append-only. Nothing is ever deleted or rewritten. If an event is missing (for example a network failure mid-session), a tombstone event is inserted so the chain stays contiguous and the gap is visible rather than hidden.
Every decision also renders as an evidence receipt: the decision, the policy in force, the session and event ids, and, once you verify, the integrity checks that actually ran. Open any event in the Evidence explorer to see its full lifecycle from request to cryptographic verification, and use Export evidence to download the session as a portable bundle.
Tool trust registry
When your agent connects to a tool, register it with register_tool. AgentKey assigns a risk score and a status: pending, approved, flagged, quarantined, or revoked.
During authorization, a flagged or quarantined tool escalates the risk level. A revoked tool is blocked outright, regardless of permission. An unregistered tool carries an unregistered_tool flag so you can see the surface area you have not vetted.
Override a score manually when you have context AgentKey does not, for example a tool you operate yourself.
Input integrity
Agents ingest content from emails, web pages, files, and tool responses. Some of it is hostile. Use scan_input before passing untrusted content to an agent. It returns a scan record with a status (clean, flagged, quarantined) and a list of detected patterns.
Pass the input_scan_id into the authorize call. A flagged scan escalates risk. A quarantined scan blocks the action. Resolve false positives with resolve_input_scan.
MCP bridge
AgentKey speaks the Model Context Protocol. Point your Claude, Cursor, or custom MCP client at the AgentKey bridge endpoint, and every tool call your model makes flows through the same authorization and evidence pipeline as the SDK.
The bridge uses the same API key and the same permissions. There is no separate policy to maintain. See the MCP page in the dashboard for the connection URL and transport details.
REST API reference
All functions live at https://agentkey.us/api/functions/<name>. Authenticate with a Bearer API key.
authorizeCheck a single action against policy. Returns allowed, reason, and an evidence event id.
record_actionRecord an execution that happened, with its result. Does not authorize.
start_sessionOpen an evidence session explicitly.
end_sessionClose a session, compute coverage, and generate findings.
verify_sessionRecompute the chain and return an integrity report.
register_toolAdd or update a tool in the trust registry.
scan_inputScan untrusted content before it reaches the agent.
resolve_approvalApprove or deny a pending ask decision.
curl -X POST https://agentkey.us/api/functions/authorize \
-H "Authorization: Bearer $AGENTKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action":"invoke","resource":"stripe.charge","arguments":{"amount":150}}'The response includes allowed, reason, session_id, event_id, and the current usage against your plan.
Verifying evidence
Verification is the whole point. A session token is just a pointer. To prove a record is intact, you recompute the hashes from the raw events and compare them to the stored root.
curl -X POST https://agentkey.us/api/functions/verify_session \
-H "Authorization: Bearer $AGENTKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"session_id":"<session_id>"}'The response tells you whether the chain verifies, how many events are present, whether there are coverage gaps (actions taken without a matching authorization), and the recomputed root hash. You can run this from outside AgentKey at any time, months later. If the stored root and the recomputed root match, the record is intact.
There is also a public verifier at /verify/evidence. Paste an exported evidence bundle and it runs entirely in your browser: every event hash and the session Merkle root are recomputed locally, and the Ed25519 signature is checked against the public key published at https://agentkey.us/api/functions/evidence_keys. The HMAC attestation check needs the workspace signing key, which never leaves the server. Verification fails closed: unknown and error outcomes are never reported as valid.
What verification proves: the records were produced by AgentKey's signing identity and have not been altered since the session root was signed. What it does not prove: that the signing keys were never compromised, any independent external timestamping (not implemented), or that actions taken outside AgentKey were recorded.
That is the full loop: control what agents do, observe what they did, and prove the record is real.
Ready to try it on your agent?
Create an agent and get a key in under a minute.