Skip to main content
Every wire request resolves a Principal through the principal(req) seam you pass to createVendo. The returned subject scopes threads, apps, approvals, grants, activity, and runs. This page covers the identity model and the two behaviors that ride on it: anonymous auto-merge on first sign-in, and organization workspaces (Cloud-gated).

Principal kinds

Principal.kind is "user" or "org". Your principal(req) resolver may only return kind: "user". Organization context is derived from membership inside Vendo and is never resolved directly by the host.
Returning null gives the client an ephemeral session — see Anonymous sessions below.

The reserved vendo: namespace

Subjects that start with vendo: are reserved for Vendo-owned identities. Two are defined today:
  • vendo:webhook:<source> — webhook deliveries execute under this subject when no principal is otherwise attached to the request.
  • vendo:org:<orgId> — the subject for an organization workspace.
A principal(req) resolver that returns a vendo:* subject, or a kind: "org" principal, is rejected at the wire with a blocked error. Mint your own subjects under whatever prefix your product uses (for example user:); leave the vendo: prefix alone. If you have audit readers or dashboards that filter on webhook subjects, update them to match vendo:webhook:<source> instead of the bare webhook:<source> form.

Anonymous sessions

When principal(req) returns null, Vendo mints an ephemeral session principal and carries it in a signed, httpOnly cookie scoped to the wire base path. Ephemeral principals never write to disk — threads, apps, and state live in an in-memory overlay for the life of the process.

Auto-merge on sign-in

The first authenticated request that arrives with a valid anonymous cookie adopts the session’s data into the real user subject and then retires the cookie (Max-Age=0). Users keep the conversation they started, the apps they built, and the state those apps wrote. The merge is idempotent and emits a kind: "principal" audit event. What is adopted:
  • Threads (including the message the user was mid-typing when they signed in)
  • Apps the anonymous session created, and their per-app records and blobs
  • State written by those apps
What is not adopted (consent doesn’t transfer identities):
  • Grants and approvals — the anonymous session’s authority does not carry over. The signed-in user re-approves on the next tool call.
  • Connected accounts — external providers key credentials by subject, so users reconnect after signing in.
  • Audit and run history — kept intact under their original subject.
Existing durable rows always win a collision. If the signed-in user already owns a thread or app with the same id, the anonymous copy is dropped rather than overwriting it. There is no configuration to turn auto-merge off; it is the default behavior of the wire. Nothing on the host side has to change to opt in: as long as principal(req) returns null before the user signs in and a real Principal afterward, Vendo does the rest.

Organizations (Cloud-gated)

Organizations let members share apps, approvals, and grants under one subject. They are gated on VENDO_API_KEY plus the orgs capability on that key; without it, the org APIs return cloud-required (HTTP 402) and /status reports blocks.orgs: false. The chrome renders an honest upgrade state instead of a broken tab.

Roles

Every membership has a role:
  • member — reads and calls org-owned apps.
  • admin — everything a member can do, plus approves grants for the org, manages apps (edit, delete, undo, rebase, enable, disable, transfer), and invites or removes members.
  • owner — everything an admin can do, plus promotes and demotes owners. The store refuses to remove the last owner of an org.

Wire surface

Once the key carries the orgs capability, these routes come online (see the HTTP routes reference for the full table):
  • /orgs — list, create, delete an organization.
  • /orgs/:id/members — invite, list, change role, remove.
  • /orgs/:id/apps — transfer an app your user owns into the org.
Approvals and grants take an ?org=<orgId> query parameter (or body.org on POSTs) to operate under the org’s subject. Only admins and owners can approve on behalf of an org; a member trying to approve receives 403.

Org-owned runs

When a member opens or calls an org-owned app, the run executes under the org principal (vendo:org:<orgId>), but RunContext.actor carries the Principal of the human that initiated the run. Grants and approvals that the run parks are keyed to the org subject, so the next admin who sees them can approve on behalf of everyone. Audit events on org-context runs carry an extra detail.org = { subject, actor } block so you can tell which human triggered which org-scoped action.

Enable orgs

  1. Set VENDO_API_KEY in the host process.
  2. Confirm the key includes the orgs capability:
  3. Open the orgs tab in the chrome, or call /orgs directly, to create the workspace and invite members.
See Vendo Cloud for key management and Environment variables for the full list of entitlements a Cloud key unlocks.