Quickstart

DocumentationQuickstart

Simple mode on — some technical details are condensed. Switch to Dev in the nav for full API reference.

Documentation

SDK Quickstart

Create an agent, add one permission, call verify() before execution, and prove both allowed and denied actions in about five minutes.

The five-minute model

BehalfID sits between the AI agent and the tool it wants to run. Your code calls BehalfID first. If the decision is not allowed, the executor does not run.

  1. Create an agent. Use /dashboard/onboarding or behalf agents create. Store the one-time bhf_sk_... API key as BEHALFID_API_KEY.
  2. Create a permission. Start with one clear rule — for a coding agent: deploy on vercel.com with requiresApproval: true for production. For other agents: browse_web on web, or purchase on amazon.com with maxAmount: 25.
  3. Install the SDK. Add the published Node SDK to the app that owns the tool execution.
  4. Call verify before the action. The SDK requires agentId, action, and the API key. Pass vendor or resource when a permission is scoped to a service.
  5. Show an allowed request. Call verify with an action and resource covered by an active permission.
  6. Show a denied or approval-required request. Try a blocked action, a missing permission, or a permission with requiresApproval: true.
  7. Fail closed. Throw or return before the executor. Never run the tool when decision.allowed is false.
terminal
npm install @behalfid/sdk

Copy-paste executor pattern

deploy.ts
import { BehalfID } from "@behalfid/sdk";

const behalf = new BehalfID({
  apiKey: process.env.BEHALFID_API_KEY!,
});

const agentId = process.env.BEHALFID_AGENT_ID!;

async function deployToProduction(vendor: string) {
  const decision = await behalf.verify({
    agentId,
    action: "deploy_production",
    vendor,
  });

  if (!decision.allowed) {
    // Blocked or approval required — reason and requestId are logged
    throw new Error(`Blocked by BehalfID: ${decision.reason}`);
  }

  return runDeploy({ vendor, env: "production" });
}

Allowed request

This succeeds when the agent has an active deploy permission for vercel.com without a blocking rule or approval requirement.

allowed.ts
const decision = await behalf.verify({
  agentId: process.env.BEHALFID_AGENT_ID!,
  action: "deploy",
  vendor: "vercel.com",
});

if (decision.allowed) {
  await runStagingDeploy();
}
allowed response
{
  "requestId": "req_xxx",
  "allowed": true,
  "reason": "Action allowed by active permission.",
  "risk": "low"
}

Approval-required request

When a permission has requiresApproval: true, BehalfID returns allowed: false with a reason that signals human approval is needed. The agent should pause and surface the requestId. After you approve in the dashboard, the agent retries and the action is allowed.

approval-required.ts
const decision = await behalf.verify({
  agentId: process.env.BEHALFID_AGENT_ID!,
  action: "deploy_production",
  vendor: "vercel.com",
});

if (!decision.allowed) {
  // Surface this to the engineer — do not auto-retry
  throw new Error(`BehalfID: ${decision.reason} (ref: ${decision.requestId})`);
}
approval-required response
{
  "requestId": "req_xxx",
  "allowed": false,
  "reason": "Permission requires approval before execution.",
  "risk": "medium"
}

Denied request

This fails closed when a permission is missing, the vendor does not match, or a blockedAction covers the requested action.

denied.ts
const decision = await behalf.verify({
  agentId: process.env.BEHALFID_AGENT_ID!,
  action: "purchase",
  vendor: "shop.example",
  amount: 742,
});

if (!decision.allowed) {
  throw new Error(`Blocked by BehalfID: ${decision.reason}`);
}

await runCheckout(); // not reached when denied
denied response
{
  "requestId": "req_xxx",
  "allowed": false,
  "reason": "Amount exceeds maxAmount constraint.",
  "risk": "high"
}

Create permission with the SDK

permission.ts
await behalf.createPermission({
  agentId: process.env.BEHALFID_AGENT_ID!,
  action: "deploy_production",
  resource: "vercel.com",
  allowedActions: ["promote staging to production"],
  blockedActions: ["rollback without approval", "delete deployment"],
  requiresApproval: true,
});

Manual mode vs enforcement

Passport links and manual preview forms help existing assistants understand the rules, but they do not control a provider directly. Automatic enforcement happens when your app, MCP server, or Action Gateway calls BehalfID before the action and refuses to run denied tools.

For a runnable end-to-end version of this loop, use examples/enforcement-demo. It creates demo permissions, runs allowed and denied actions, and checks the resulting audit log entries.