Viewport daemon, relay, and hosted runtime are available in alpha. Surfaces may change.
VIEWPORT
Concepts

Organizations and teams

The tenant model. Workspace is the organization wall. Team is the active work scope.

The Viewport tenant model is single-database, row-level, with workspace as the organization tenant. Users are global. Memberships are explicit. Teams are org-local work scopes. Every customer-data row carries a workspace_id; team-scoped product data also carries a team_id and is filtered through the active team context.

If you've used Slack or Vercel: same shape. One person, many workspaces, each workspace is a hard wall. Inside that wall, a team is the scope you choose before creating workflows, reviewing artifacts, or attaching context.

The shape

User (global)
  ├── membership → Workspace A (role: owner)
  │                  ├── Team: Platform
  │                  │    ├── Workflows, routes, artifacts, context
  │                  │    └── Review packets and inbox decisions
  │                  ├── Team: Reviewers
  │                  ├── Runners (org-scoped compute)
  │                  └── Billing, members, integrations, audit
  ├── membership → Workspace B (role: admin)
  │                  ├── Team: Engineering
  │                  └── Workflows, plans, vaults, inbox …
  └── membership → Workspace C (role: viewer)
                     └── …

Workspace = the tenant

A workspace is the hard wall. It owns:

  • Members (workspace_memberships).
  • Teams (org-local groups).
  • Billing and plan state.
  • Machines and runners.
  • Integrations, webhooks, settings.
  • Audit events.

Workspaces cannot see each other. Resources cannot be shared across workspaces. A team in workspace A cannot receive an ACL entry for a workspace B resource.

Internally referenced by ULID. The slug is display-only.

User = global identity

One user account per email. The same user can belong to many workspaces with different roles in each. There's no users.tenant_id. Sessions cookies are tenant-agnostic; the current org is a per-request context.

Active organization context

For every API request that touches tenant data, the platform resolves the active organization:

  1. Route binding: if the route has {workspace}, that wins.
  2. Request header: X-Viewport-Organization: <ULID>.
  3. Token claim: if the auth token is org-bound, that's used.
  4. Else: fail closed. The request is denied or the page asks the user to pick an org.

The platform verifies the actor has a membership row in the chosen org. No membership = 403 tenant_forbidden.

This means:

  • Web, mobile, CLI, daemon, integrations. They all pass org context in the same way.
  • One user can have web on org A and mobile on org B simultaneously without confusing the server.
  • API tokens can be org-bound (recommended for CI) or user-bound (require explicit header per request).

Team = active work scope

Teams are workspace-scoped collaboration groups. They're not tenants. They're ACL principals and the active scope for most product work.

Rules:

  • A team has exactly one workspace_id. Cannot move.
  • Same slug can repeat across orgs (each "Platform" team is its own thing).
  • A team member must already be an org member. The platform enforces this at write time.
  • Team grants on resources are workspace-scoped: an ACL entry where team.workspace_id != resource.workspace_id is rejected.
  • Teams are never auto-created. An org starts at zero teams.
  • Workflows, workflow routes, workflow runs, artifacts, review packets, inbox items, context packages, context vaults, and Team Resource exports are team-scoped.
  • If a page requires team context and none is selected, the app asks you to choose or create a team before continuing.

Runner = org-level compute

Runners belong to the organization, not to a team. They are simple compute that execute workflow assignments:

  • A runner advertises capabilities such as agents, shell access, integrations, runner pool, and access mode.
  • The router picks a team-scoped workflow run; the org-level runner claims it if policy and capabilities match.
  • The same runner can execute work for multiple teams in the same organization.
  • Provider credentials and repo access stay on the runner.

That split keeps capacity simple: teams own the work, organizations own the compute.

Team Resource = Git-backed record

A Team Resource points a team at a Git repository, branch, and base path. It is the durable place for portable exports:

.viewport/
  team.json
  workflows/definitions.json
  workflows/routes.json
  reviews/packets.json
  artifacts/workflow-run-artifacts.json
  context/packages.json
  context/vaults.json
  context/events.json
  context/candidate-applications.json

Viewport remains the control-plane source of truth. The Git resource gives teams reviewable evidence, historical diffs, and a familiar recovery path.

Roles

LayerRoles
Orgowner, admin, member, viewer
Teamlead, member
Resourceowner, admin, editor, reviewer, viewer

Roles compose: a workspace admin who's also a team member can do everything an admin can plus whatever team membership grants. Multiple grant paths give a user the most permissive resulting role.

The daemon's org binding

A daemon can be paired to one or more orgs. Each org binding has its own:

  • Crypto identity (separate keypair file).
  • Machine ID (different ULIDs in different orgs).
  • Install ID, runtime target ID, relay endpoint.
  • Bound directories.

So the same physical laptop can stream from ~/work to Acme and from ~/personal to Personal without either org ever seeing the other org's metadata or machine identity. Managed workflow runners use the same org boundary, but are intentionally team-agnostic compute. See Concepts: Machines and pairing and Concepts: Trust and privacy.

What multitenancy gets you

  • Personal data stays personal. A consultant working on three clients keeps three clean inboxes, three audit logs, three sets of policies.
  • A compromise of one org doesn't cascade. Audit log compromise in Acme reveals nothing about Personal.
  • Different teams, different rules. Aggressive auto-approval for OSS, strict gates for the production org.
  • Clean offboarding. Removing a user from one org leaves their other memberships untouched.

What multitenancy does not do (today)

  • Schema-per-tenant or DB-per-tenant isolation. Single shared DB with row-level scope. If that's a non-starter for your security posture, talk to us about on-prem.
  • Org-to-org sharing. You can't share a workflow from org A into org B. Export/import is not available yet.
  • Cross-org search. Each org search is its own. We don't have a global "search across all my orgs."

Where to go next

On this page