Primitive/governance4 min read

Introducing the governance layer: approvals, logs, sessions, and jobs

Human-in-the-loop approvals that freeze sensitive actions until you say yes, a per-user audit trail of everything an agent did, short-lived scoped MCP sessions, and unified async job tracking — the controls that make an autonomous fleet safe to run.

Primitive/governance
TL;DR
  • /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 runtime

The 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.

Frequently Asked Questions
What is the governance layer?+
It's the set of agent-infrastructure primitives that make autonomous operation safe and observable: /approvals (human-in-the-loop), /logs (audit trail), /sessions (scoped, expiring access), and /jobs (async tracking). Together with the encrypted vault, they're what separate 'an agent doing things' from 'an agent you can trust to do things.'
Which actions require approval?+
Sensitive primitives are approval-gated by default: issuing cards, company formation, domain purchase, connecting third-party apps, and autonomous browser signup. When an agent calls one, it returns a pending approval (HTTP 202) instead of executing, and waits for a human decision.
What happens after I approve?+
The API replays the frozen call and returns the updated approval. From the agent's side, it's as if the call went through once you said yes — no need to reconstruct the request. You can also deny with a reason, and poll or wait for a decision programmatically.
What do logs capture?+
A per-user activity trail of actions taken — what happened, when, and by whom — queryable by action and time, with a streaming endpoint for live monitoring. It's the record you use to answer 'what did this agent do' without re-running it.
What are sessions for?+
A session is a short-lived, TTL-limited token scoped to a single user, exposing an MCP endpoint. You hand it to a runtime (a worker, a third-party tool, a client) so it can act for a bounded window without ever holding your long-lived API key. When the TTL expires, access ends.
How do I get started?+
Check responses with isPendingApproval, then approve or wait via naive.forUser(id).approvals. Query naive.forUser(id).logs, mint a session with naive.forUser(id).session(...), and track async work with naive.forUser(id).jobs. Per-primitive guides live at usenaive.ai/docs/getting-started/approvals, /logs, /sessions, and /jobs.
DZ
Dennis ZaxCTO

CTO of Naïve. Building the open-source agent runtime.

@denniszax