By the end of this guide you'll have an agent with a cryptographic identity, a policy that scopes what it can do, and a signed receipt proving what it did. You need a free govern.sh workspace, Node 18 or later, and nothing else — the free tier includes three agents and the full policy engine.
Step 1 — Install the SDK and authenticate
Install the SDK, then create a workspace API key from Settings → API keys in the dashboard. Workspace keys authenticate you — the developer — for management operations like minting passports. They are never given to agents; that's the whole point of what comes next.
npm install @govern/sdk
export GOVERN_API_KEY="wk_live_..." # workspace key, keep server-sideStep 2 — Mint the passport
A passport is a per-agent Ed25519 keypair plus a public profile. One call mints it. The private key is returned exactly once — store it in your secret manager under the agent's own entry, not alongside your workspace key.
import { Govern } from "@govern/sdk";
const ap = new Govern(); // reads GOVERN_API_KEY
const passport = await ap.passports.mint({
name: "refund-agent",
description: "Handles refund requests from the support queue",
owner: "payments-team@yourco.dev",
});
console.log(passport.id); // ap_7f3k9m2x
console.log(passport.publicKey); // ed25519:mAX2...
// passport.privateKey is shown once — store it now.Step 3 — Attach a starter policy
A passport with no policy can do nothing — govern.sh is deny-by-default. Grant the agent a narrow scope with a spending cap and a human-approval threshold. Policies are versioned; every edit creates a new version and old receipts keep pointing at the version that judged them.
await ap.policies.create({
agent: passport.id,
rules: [
{ action: "stripe:refund.create", effect: "allow", maxAmount: 200_00 },
{ action: "stripe:refund.create", effect: "hold",
whenAmountOver: 200_00, approvers: ["role:payments-lead"] },
{ action: "zendesk:ticket.reply", effect: "allow" },
],
budget: { currency: "usd", daily: 2_000_00 },
});Step 4 — Make a call through the gate
The agent authenticates with its own passport key and every tool call passes through the Policy Enforcement Point before it executes. Allowed calls proceed with single-digit-millisecond overhead; anything outside policy is refused with a structured verdict the agent can handle.
import { AgentSession } from "@govern/sdk";
const session = new AgentSession({
passportId: "ap_7f3k9m2x",
privateKey: process.env.REFUND_AGENT_KEY!,
});
const result = await session.act("stripe:refund.create", {
charge: "ch_3Pk...",
amount: 4200, // $42.00 — inside the allow rule
});
console.log(result.verdict); // "allow"
console.log(result.receiptId); // rcp_01hx4...Step 5 — Read the receipt
Every decision produced a signed receipt, chained to the one before it. Fetch it and you'll see the actor, the action digest, the policy version that ruled, and the signature. Try a call for $500 next — you'll get a hold verdict and an approval request instead, and that decision gets a receipt too.
$ govern receipts show rcp_01hx4...
actor ap_7f3k9m2x (refund-agent)
action stripe:refund.create params sha256:9c1e...
verdict allow (policy v1)
issued 2026-02-10T14:03:22.114Z
prev_hash sha256:f2ab41...
signature ed25519:sig:Kj9w... VALID- Rotate or revoke the passport any time from the dashboard — revocation propagates to enforcement nodes in under two seconds.
- Add a second agent and give it a different scope; identities stay separate even when both touch the same tools.
- When you're ready for production patterns, continue with Designing policies that scale.