How HiveKey governs an agent.
Here's what putting an agent under policy looks like end to end: a role that grants exactly the capabilities it needs, a guard checked in the path, an agent routed through the gateway, and every action — allowed and denied — on one immutable audit log. Your team and ours set this up together.
Before you start
- A HiveKey workspace, provisioned with you during onboarding, and your admin key (hk_live_…).
- Node 18+ or a shell with curl.
- An agent you'd like to govern (any runtime that can set a base URL + bearer token).
Install the CLI
Install the HiveKey CLI and authenticate it with your admin key.
# install (macOS / Linux)
npm install -g @hivekey/cli
# authenticate the CLI to your workspace
hivekey login --key hk_live_8fK2…aR9
✓ Authenticated as acme-corp · workspace prod Create a role with scope
A role is deny-by-default. This one grants a support agent exactly two capabilities — read inbox, send mail — and nothing else. Write it as YAML and apply it.
apiVersion: policy.hivekey.ai/v1
kind: Role
metadata:
name: support-agent
description: First-line support — read mail, reply only.
scope:
# deny-by-default — only these actions are visible
allow:
- mail.read
- mail.send
guards: [] # add one in the next step hivekey role apply -f support-agent.yaml
✓ Role support-agent created · rev 1 · 2 grants Add a guard rule
Scope says what; a guard says under what conditions. Here we restrict outbound mail to approved domains. The guard is checked in the path — before the action runs.
{
"guards": [
{
"id": "approved-domains",
"action": "mail.send",
"when": { "field": "to.domain", "in": ["acme.com", "acme-support.com"] },
"effect": "allow",
"otherwise": "deny"
},
{
"id": "daily-volume-cap",
"action": "mail.send",
"when": { "field": "rate.per_day", "lte": 500 },
"effect": "allow",
"otherwise": "review"
}
]
} effect · allow, deny, or review (held for human sign-off). The first guard whose when fails falls through to its otherwise.
Point an agent at the gateway
Mint a scoped token for the agent, then set your agent's base URL to the HiveKey gateway. Every action now flows through scope + guards. No code change beyond the endpoint and the token.
# 1. mint a token bound to the role
hivekey agent create helpdesk-bot --role support-agent
# 2. the agent calls actions through the gateway
curl https://gateway.hivekey.ai/v1/actions/mail.send \
-H "Authorization: Bearer hk_agt_3pQ…" \
-H "Content-Type: application/json" \
-d '{"to":"jordan@acme.com","subject":"Hi","body":"…"}' Allowed — the recipient domain is on the list:
{
"id": "act_2Nf9kQ",
"action": "mail.send",
"verdict": "allow",
"matched_guard": "approved-domains",
"agent": "helpdesk-bot",
"result": { "message_id": "msg_a1b2c3", "queued": true }
} Denied — a recipient outside the allowlist:
{
"id": "act_2Nf9kR",
"action": "mail.send",
"verdict": "deny",
"matched_guard": "approved-domains",
"reason": "recipient domain 'gmail.com' not in allowlist",
"logged": true
} Read the audit log
Both attempts — the allow and the deny — were written as they happened. Tail the log from the CLI, or query the API.
TIME AGENT ACTION VERDICT DETAIL
14:02:11 helpdesk-bot mail.send allow to=jordan@acme.com
14:02:39 helpdesk-bot mail.send deny domain gmail.com not allowed
14:03:02 helpdesk-bot mail.read allow folder=inbox limit=20 That's it — your first governed agent.
One role, one guard, one audit trail. Every future agent inherits the same shape. Stream the log to your SIEM next, or gate an MCP server.
SDKs
Prefer a typed client? The gateway speaks plain HTTP, but first-party SDKs wrap tokens, retries, and verdict handling.
import { HiveKey } from "@hivekey/sdk";
const hk = new HiveKey(process.env.HK_AGENT_TOKEN);
await hk.actions.run("mail.send", { to, subject, body }); from hivekey import HiveKey
hk = HiveKey(token=os.environ["HK_AGENT_TOKEN"])
hk.actions.run("mail.send", to=to, subject=subject, body=body) Stuck? Talk to our team — we help you set up roles, audit, and SSO.