- ›
/approvals— sensitive actions freeze as pending and resume only when you approve, then replay automatically - ›
/logs— a per-user audit trail of every action an agent took, queryable and streamable - ›
/sessions— short-lived, scoped MCP sessions you can hand to an untrusted runtime - ›
/jobs— unified tracking for every async operation: images, video, research, SEO tasks - ›
Approval-gated by default— cards, formation, domains, connections, and browser signup pause for a human - ›
Built for fleets— the controls that make running many agents auditable instead of terrifying
Today we're launching the governance layer — /approvals, /logs, /sessions, and /jobs. Sensitive actions freeze until a human says yes. Everything an agent does is recorded. Untrusted runtimes get short-lived, scoped access instead of your real key. And every async operation is trackable in one place. These are the controls that turn "running an autonomous fleet" from a leap of faith into something you can actually operate.
The problem: autonomy without controls is a liability
The more an agent can do in the real world — spend money, form companies, sign up for services, hold credentials — the more the absence of guardrails becomes the whole risk. Three questions decide whether you can actually deploy:
- Can I stop the dangerous things? An agent about to issue a card or incorporate a company should be able to pause and ask, not act and apologize.
- Can I see what happened? When something goes wrong — or right — you need a record of what the agent did, not a re-run and a guess.
- Can I limit blast radius? Handing a worker or a third-party tool your long-lived API key means handing it everything, forever.
Most agent stacks treat these as someone else's problem. On Naïve they're primitives, wired into every sensitive action by default. Until now, governance was the part you had to build last and trust least.
/approvals: human-in-the-loop, by default
Sensitive primitives — /cards, /formation, /domain purchase, /integrations connect, and /browser signup — are approval-gated by default. When an agent calls one, it doesn't execute; it returns a pending approval (HTTP 202) and waits.
import { isPendingApproval } from "@usenaive-sdk/node";
const res = await naive.forUser(userId).cards.create({ spending_limit_cents: 5000 });
if (isPendingApproval(res)) {
// Block until a human decides (or time out)
const approval = await naive.forUser(userId).approvals.wait(res.approval_id, {
timeoutMs: 5 * 60 * 1000,
});
// On approve, the API replays the frozen call automatically
}A human (or your own logic) approves or denies:
await naive.forUser(userId).approvals.approve(approvalId);
await naive.forUser(userId).approvals.deny(approvalId, { reason: "limit too high" });On approval, the API replays the frozen call and returns the result — the agent doesn't reconstruct anything. This is what lets you give an agent real spending power without giving it free rein.
/logs: the audit trail
Every action a user's agent takes is recorded. Query it by action and time, or stream it live.
const { events } = await naive.forUser(userId).logs.query({
action: "vault.reveal",
limit: 50,
});When you need to answer "why did this agent reveal that credential" or "what did it do at 3am," the log is the answer — no re-running the agent loop, no reconstructing intent.
/sessions: scoped, expiring access
Never hand a worker, a tool, or a client your long-lived nv_sk_* key. Mint a session instead — a short-lived, TTL-limited token scoped to one user, exposing an MCP endpoint.
const session = await naive.forUser(userId).session({ ttlMs: 60 * 60 * 1000 });
// session.mcp.url + session.mcp.headers — hand these to the runtimeThe runtime acts for a bounded window and nothing more. When the TTL expires, so does the access. It's the difference between lending a key and lending the building.
/jobs: every async operation in one place
Generation and research primitives are async — /image, /video, /clips, /research, and SEO tasks all return jobs. /jobs is the unified place to track them.
const job = await naive.forUser(userId).jobs.get(jobId);
const { } = await naive.forUser(userId).jobs.list();One model for "is it done yet," whatever produced the work.
What you can build with the governance layer
Run a fleet you can actually audit — Every Employee's actions land in /logs, every risky move pauses in /approvals. You can operate dozens of agents and still answer for each one.
Give agents spending power safely — Approval-gate /cards and /formation so an agent can propose to spend or incorporate, but a human signs off — programmatically or in a dashboard.
Hand untrusted runtimes bounded access — Issue a scoped session to a third-party tool or a customer's client so it can use specific primitives for an hour, never your real key.
Build compliance into the product — Pair /logs with /credentials so every credential access and sensitive action is recorded — the audit trail your customers' security teams will ask for.
Coordinate long-running work — Track image, video, clip, research, and SEO jobs through /jobs and drive an orchestrated workflow off their completion.
Get started
Drop this starter prompt into any coding agent to wire up Naïve:
Read https://usenaive.ai/skill.md and use it to set up Naïve in my project.
- Approvals: usenaive.ai/docs/getting-started/approvals
- Logs: usenaive.ai/docs/getting-started/logs
- Sessions: usenaive.ai/docs/getting-started/sessions
- Jobs: usenaive.ai/docs/getting-started/jobs
- Quickstart: usenaive.ai/docs/getting-started/quickstart
- Join the community on Discord